0

===================

Note: This is not a duplicate, since I already tried the solution on the linked question and it did not work for my problem

===================

How can I "erase" any previously [browser's] echoed items? -Clear the screen completely (set the screen blank)?

For instance...:

<?php
function test($var) {
    if ($var === 0) { echo "Hello "; }
    if ($var === 1) { echo "World"; }
    if ($var < 0 || $var > 1) { [clear screen]; echo "Number is too big";}
}

test(0);
test(1);
test(666);

========MORE DETAILS========

The problem I am experiencing is this. The page renders part of the HTML but when it reaches keywords, it stops and echoes what I need (Intended behavior if the page has no keywords).

However, since it does not clear the screen and DOM...as a result, the browser's screen is blank without any error message. This is because I need to erase any previously echoed output.

I did try ob_end_clean() before posting this question. but it does not work:

PHP:

class keywords{

    private static function run(){
    ...pdo code...
    ...some more code...
    if( $sht->rowCount() === 0 ){
        ...[clear screen goes here]...
        exit("Page " . $pageID . " has no keywords");
    else...
    ...more code
    }

    ...more code    
}

On the HTML side I am using ...content="<?php keywords::run(); ?>" />. When the page has no keywords this is the output (Without clearing the browser):

HTML

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">

    <meta name="description"    content="Some page" />  
    <meta name="keywords"       content="Page: 0123456789 Page has no keywords

As a result, the screen is blank without any error message

Community
  • 1
  • 1
Omar
  • 11,783
  • 21
  • 84
  • 114
  • 2
    Terminal or Browser? – Rizier123 Feb 15 '15 at 04:28
  • @Rizier123 Browser's, but if you know both... – Omar Feb 15 '15 at 04:31
  • Delete old echo string, then you will be only what you want, it's no C/C++ that you need clrscr() – Gaurav Dave Feb 15 '15 at 04:34
  • 1
    possible duplicate of [How to clear previously echoed items in PHP](http://stackoverflow.com/questions/1057986/how-to-clear-previously-echoed-items-in-php) – WoogieNoogie Feb 15 '15 at 04:40
  • @WoogieNoogie Please read again. It is not a duplicate – Omar Feb 15 '15 at 05:10
  • @WoogieNoogie Can you please remove your "possible duplicate"? As you can see the answer you are pointing to didn't solve my issue. – Omar Feb 15 '15 at 05:20
  • 1
    All I see in your edit is that ob_end_clean() didn't work, but you didn't explain anything past that. The problem, as you describe it, is that you are echoing items, and want to clear them if the code meets a certain criteria. If you use ob_start() as described in the linked question, it should do exactly what you want. Other answers in that question also bring up the larger issue, which is, you shouldn't be echoing something that shouldn't be there. It would be better to save the content, and wait to echo it until the conditions are met. – WoogieNoogie Feb 15 '15 at 06:04
  • @WoogieNoogie `If you use ob_start() as described`...why you think I posted this? Have you tried to see if you can solve it? Because I certainly have and it DOES NOT WORK and it is not the same problem nor the same question. – Omar Feb 15 '15 at 06:09
  • @WoogieNoogie Do you have a solution to my question? – Omar Feb 15 '15 at 06:26
  • @WoogieNoogie Otherwise, what about removing your dup? – Omar Feb 15 '15 at 06:27
  • @Omar It seems that you do not understand the technique behind php and a browser. Also if you do not get any example to work, you should post the error here. And there is no info if any of the other posted solutions work for you. Try to be more concrete because Woogie gave a good advice to work around your need for ob_start(); and here are many samples how to. – Daniel Feb 26 '15 at 15:56

10 Answers10

6

PHP Docs

ob_start says:

Output buffers are stackable, that is, you may call ob_start() while another ob_start() is active. Just make sure that you call ob_end_flush() the appropriate number of times. If multiple output callback functions are active, output is being filtered sequentially through each of them in nesting order.

ob_clean says:

The output buffer must be started by ob_start() with PHP_OUTPUT_HANDLER_CLEANABLE flag. Otherwise ob_clean() will not work.

PHP Docs PHP_OUTPUT_HANDLER_CLEANABLE

Controls whether an output buffer created by ob_start() can be cleaned.

Available since PHP 5.4.

Are you sure you can start/flush/end output buffer?
Have you checked your server configuration?
Are you sure there are no output buffer stacking happening?

Community
  • 1
  • 1
josegomezr
  • 888
  • 4
  • 15
3

You can get some help from output control key funcs: ob_start, ob_clean, ob_end_flush try code below

<?php
ob_start();
function test($var) {
    if ($var === 0) { echo "Hello "; }
    if ($var === 1) { echo "World"; }
    if ($var < 0 || $var > 1) { 
        ob_clean(); 
        echo "Number is too big";
    }
}

test(0);
test(1);
test(666);
ob_end_flush();
Sky Ye
  • 31
  • 2
2

Is there a reason why you couldn't do the following? You shouldn't be outputting until you know what you want to print/echo

<?php
$output = "";
function test($var) {
if ($var === 0) { $output = "Hello "; }
if ($var === 1) { $output = "World"; }
if ($var < 0 || $var > 1) { [clear screen]; $output="Number is       too big";}
}
Function outputCheck(){
  Echo $output;
}

test(0);
test(1);
test(666);

outputCheck();
Markus013
  • 72
  • 7
2

You cannot erease the output. Normally the server sends every output at once. So a print or echo cannot be reversed. But you may buffer your output by starting all your code with ob_start();

At the end of your code you can send your buffer to the client with ob_end_flush();

To output your error details you may use a custom function like:

function error($str) {
    ob_end_clean();
    exit($str);
}

This will do your trick.

BUT

It will be far better to collect all informations to your meta before even sending html. This will result into faster sending to the client. You just output metas if all info is clear:

$test1 = test(1);
$test2 = test(2);
if //all my content is okay {
    ...paste html here...
}
Daniel
  • 795
  • 1
  • 10
  • 25
1

As I undestand your need, in fact, you don't want to clear the screen, but to see the error message in your browser, without looking at the source code. And it's impossible because you have already opened tags.

Try this, instead of your exit code:

   exit('<html><head></head><body>Page ' . $pageID . " has no keywords</body></html>");

You have to close, your meta tag, and header and start the body tag.

Npzy
  • 18
  • 5
Adam
  • 17,838
  • 32
  • 54
1

You are using "exit" in a very bad way: http://php.net/exit

Exit will finalize the execution of your script and I suppose that this is not the behavior that you are expecting from it. So your code are not working as you could expect when the document don't have keywords:

class keywords{

    private static function run(){
    ...pdo code...
    ...some more code...
    if( $sht->rowCount() === 0 ){
        ...[clear screen goes here]...
        exit("Page " . $pageID . " has no keywords");
    else...
    ...more code
    }

    ...more code    
}

You must use "return" or another way to exit from "run" but without ending PHP script execution!

For example (leaving this text inside your keywords tag):

class keywords{

    private static function run(){
    ...pdo code...
    ...some more code...
    if( $sht->rowCount() === 0 ){
        ...[clear screen goes here]...
        echo "Page " . $pageID . " has no keywords";
        return;
    else...
    ...more code
    }

    ...more code    
}

Example (without leaving any text):

class keywords{

    private static function run(){
    ...pdo code...
    ...some more code...
    if( $sht->rowCount() === 0 ){
        ...[clear screen goes here]...
        return "Page " . $pageID . " has no keywords";
    else...
    ...more code
    }

    ...more code    
}

That text could be used to warn caller about that issue, but in your code it will silently leave keywords tag empty and still let the rest of PHP script run.

Best regards.

OscarGarcia
  • 1,995
  • 16
  • 17
0
<?php
ob_start(); //starts the buffer
function test($var) {
    if ($var === 0) { echo "Hello "; }
    if ($var === 1) { echo "World"; }
    if ($var < 0 || $var > 1)
    {
         ob_get_clean(); //fetches buffer (not used here) and cleans it. It do not stop the buffer from working like  ob_end_clean();
         echo "Number is too big";
    }
}

test(0);
test(1);
test(666);

This is often used in cms'es that loads custom plugins. People tends to add leading enter at the end of the file or space/enter before the first <?php tag, therefore engine usually opens ob handler and then after everything was loaded (and before templates are used for output - it cleans the buffer from all errors, enters and so on.

Seti
  • 2,169
  • 16
  • 26
0

ok... you should use this :

exit(' " /> </head><body> Page '.$pageID.' has no keywords </body></html>');
Federico
  • 1,231
  • 9
  • 13
  • 1
    I already wrote the same solution 5 days ago (see my comments below or above)... Try to read others answers before posting... But you're right, it is the solution to such... problem... – Adam Feb 26 '15 at 10:05
  • Ah sorry Adam, I did not see that. I Just gave you a +1 – Federico Feb 26 '15 at 11:17
  • At least i'm glad to see that someone as read the question ;-) – Adam Feb 26 '15 at 11:20
0

Ok, I'll try to face that problem in multiple ways. As we can understand, your first "test" script:

<?php
function test($var) {
    if ($var === 0) {
        echo "Hello ";
    }
    if ($var === 1) {
        echo "World";
    }
    if ($var < 0 || $var > 1) {
        echo "Number is too big";
    }
}

test(0);
test(1);
test(666);

should result in only:

Number is too big

As you can see in other answers - ob_start is suitable for this, but as it is used in function, it must be properly nested. Below example works correctly.

function test($var)
{
    if ($var === 0) {
        echo "Hello ";
    }
    if ($var === 1) {
        echo "World";
    }
    if ($var < 0 || $var > 1) {
        ob_clean();//clear all output till now
        echo "Number is too big";
    }
}
ob_start();//start buffering output
test(0);
test(1);
test(666);

So we got the basics. Let's get back to YOUR code.

I assume that HTML is something like this:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="description"    content="Some page" />  
    <meta name="keywords"       content="<?php keywords::run(); ?>" />
</head>
<body>
maybe some content?...
</body>
</html>

It's not clear if you want to send blank page with only error, or place this error in your body. I assume latter.

Possible solution: Place additional error somewhere in your content

So, we want to catch that error from keywords::run() and place it somewhere in the body. Let's use new class for that!

class YourErrorCatcher
{

    private static $errors = array();//array for collecting all your errors

    public static function addError($errorString)//method to add new error
    {
        self::$errors[] = $errorString;
    }

    public static function echoErrors()//function echoing all your errors in selected place
    {
        $errorMessage = implode("<br>", self::$errors);
        echo $errorMessage;
        return true;
    }

}

Now your HTML can look same as before, with one addition:

<body>
maybe some content?...
and here we have our errors:
<?php YourErrorCatcher::echoErrors(); ?>
</body>

How should look your keywords class now?

class keywords{

    private static function run(){
    //i assume that this function is echoing some keywords, so let's start buffering output
    ob_start();
    ...pdo code...
    ...some more code...
    if( $sht->rowCount() === 0 ){
    ob_clean();//there's error - clear buffer!
    //"throw" error
    YourErrorCatcher::addError("Page " . $pageID . " has no keywords");
    YourErrorCatcher::addError('Yes, you can "throw" more than one error in this solution and all of them will be shown.');
    //instead of exit we're returning false
    return false;
    else...
    ...more code
    }

    ...more code    
}

This one open for a long time, maybe this will help you. Let me know if this helped you!

Paweł Tomkiel
  • 1,974
  • 2
  • 21
  • 39
-1

I tried the sample code you provided in your description and below code worked for me.

<?php
    ob_start();
    function test($var) {
        if ($var === 0) { echo "Hello "; }
        if ($var === 1) { echo "World"; }
        if ($var < 0 || $var > 1) { 
            ob_end_clean(); 
            echo "Number is too big";
        }
    }

    test(0);
    test(1);
    test(666);

More details on ob_end

Let me know if it worked for you.

Paweł Tomkiel
  • 1,974
  • 2
  • 21
  • 39