Problems with ob_file_callback and fwrite

2019-09-04 17:54发布

问题:

<?php

$forks = 2;

switch ($forks) {
    case 1:
        $ob_file = fopen('case1.txt','w');
        function ob_file_callback($buffer)
{
        global $ob_file;
        fwrite($ob_file,$buffer);
}
        ob_start('ob_file_callback');
        echo $ip = $_SERVER['REMOTE_ADDR'];
        ob_end_flush();

        header("LOCATION: case1.php");

    case 2:
    $ob_file = fopen('case2.txt','w');
function ob_file_callback($buffer)
{
  global $ob_file;
  fwrite($ob_file,$buffer);
}
ob_start('ob_file_callback');
echo $ip = $_SERVER['REMOTE_ADDR'];
ob_end_flush();
    ;
     header("LOCATION: case2.php");
        }


?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>

If I choose $forks = 1, it write to case2.txt which is nuts but it does. Not only does it fail to redirect LOCATION, but it won't even show the default page. It claims there's an issue on the header location because headers have already been sent, which is surreal. Then, even though I'm not asking it to redeclare ob_file_callback because it's in case 2 and I've opted for case 1, it claims cannot redeclare ob_file_callback on the ob_file_callback that's sitting inside case 2.

If I choose $forks = 2, it doesn't write into any file whatsoever and just claims it can't modify header information so it's another header relocation fail, which is also stupid. It does however give me the default page, but that just confuses me further.

My problem with fwrite, ob_start or ob_end_flush or whatever's doing the writing to file, is that it'll only write it once. Either that or it's erasing the file everytime it opens it, so the resulting issue is that when forks 1 does indeed write to case2.txt, it's always only ever 1 string sitting there.


First round of corrections:

    <?php

     function ob_file_callback($buffer)
{
     global $ob_file;
     fwrite($ob_file,$buffer);
}
$forks = 1;
switch ($forks) {
    case 1:
     $ob_file = fopen('case1.txt','w');

     ob_start('ob_file_callback');
     echo $ip = $_SERVER['REMOTE_ADDR'];
     ob_end_flush();
     header("LOCATION: case1.php");
     exit;
break;

   case 2:
    $ob_file = fopen('case2.txt','w');
    ob_start('ob_file_callback');
    echo $ip = $_SERVER['REMOTE_ADDR'];
    ob_end_flush();
    header("LOCATION: case2.php");
        }
    exit
?>

回答1:

You have no break statement in your first case branch dealing with the "1". You do send a redirection header, but that is just a header sent to the client. it does not terminate execution!

Using the feedback from the discussion in the comments, I try to make things a little clearer:

<?php

// writes a given string $buffer into a file handle spcified by the global $file
function ob_file_callback($buffer) 
{ 
    global $ob_file;
    fwrite($ob_file,$buffer); 
    return $buffer;
}

// main(): 

// #####
$forks = 1; // testing only !!
//$forks = 2; // testing only !!
// #####

global $ob_file = FALSE;
switch ($forks) {
    case 1:
        $ob_file = fopen('case1.txt','w');    
        ob_start('ob_file_callback');
        echo sprintf('ip = %s',$_SERVER['REMOTE_ADDR']);
        ob_end_flush();
        fclose($ob_file);
        header("Location: case1.php");
        break;
    case 2:
        $ob_file = fopen('case2.txt','w');
        ob_start('ob_file_callback');
        echo sprintf('ip = %s',$_SERVER['REMOTE_ADDR']);
        ob_end_flush();
        fclose($ob_file);
        header("Location: case2.php");
} // switch

?>

I have not tested that code (so there might be some syntax glitch...). I just want to note down a suggestion of how to get this working...