STDOUT vs. php://STDOUT

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Dick Watson

    STDOUT vs. php://STDOUT

    I'm trying to debug some code I haven't been in for years. It's in the 1and1
    linux hosting environment.

    Under
    php -v
    PHP 4.4.8 (cgi) (built: Mar 6 2008 18:09:06)

    This code
    <?php
    fwrite(STDOUT, "trythis\r\ n");
    ?>

    executed thusly:
    php -f trythis.php
    does nothing.

    Under
    php5 -v
    PHP 5.2.5 (cgi) (built: Apr 25 2008 14:13:32)

    This code
    <?php
    fwrite(STDOUT, "trythis\r\ n");
    ?>

    executed thusly:
    php5 -f trythis.php
    Produces:
    <br />
    <b>Warning</b>: fwrite(): supplied argument is not a valid stream resource
    in <b......./trythis.php</bon line <b>2</b><br />

    Apparently I must now do something looking like this:

    <?php
    $STDOUT = fopen('php://stdout', 'w');
    fwrite($STDOUT, "trythis\r\ n");
    ?>

    Did I miss something along the way??!? Is this because it's (cgi)? How do I
    coerce it to run (cli)???

    Thanks for any thoughts!


  • Rik Wasmus

    #2
    Re: STDOUT vs. php://STDOUT

    On Sat, 17 May 2008 02:00:37 +0200, Dick Watson
    <littlegreengec ko@mind-enufalready-spring.comwrote :
    This code
    <?php
    fwrite(STDOUT, "trythis\r\ n");
    ?>
    Under
    PHP 4.4.8 (cgi) (built: Mar 6 2008 18:09:06)
    does nothing.
    Causes an error, which is not shown due to ini settings
    (error_reportin g/display_errors) .
    Under
    PHP 5.2.5 (cgi) (built: Apr 25 2008 14:13:32)
    Produces:
    <br />
    <b>Warning</b>: fwrite(): supplied argument is not a valid stream
    resource
    in <b......./trythis.php</bon line <b>2</b><br />
    Apparently I must now do something looking like this:
    <?php
    $STDOUT = fopen('php://stdout', 'w');
    php://output
    Did I miss something along the way??!? Is this because it's (cgi)?
    Yes.
    How do I coerce it to run (cli)???
    And the manual states
    <http://www.php.net/manual/en/features.comman dline.php>:
    "CLI specific constants"

    Allthough they lie (it works as a module), if you NEED it, get cli instead
    of cgi.

    BTW: a weird side effect I suspect are a result of these CLI constants,
    which you shouldn't trust, is that you can define streams as resources and
    make them global:
    <?php
    define('CONSTAN T',fopen('test. txt','w');
    function foo($string){
    fwrite(CONSTANT ,$string);
    }
    foo("this works in CLI & Modules");
    ?>

    It's abusing a behaviour that's not supposed to be so (constants should
    only hold scalars), and I certainly will not guarantee you this will work
    n arbitrary versions of PHP, however, different versions I've worked with
    had that 'feature'. If you need this feature to get some code running fast
    (defining forementioned methoed and bulk replacing instanced of STDOUT
    with $GLOBALS['STDOUT'] will work too), maybe it's worth to take a look if
    CGI does too?
    --
    Rik Wasmus
    ....spamrun finished

    Comment

    • Thomas Mlynarczyk

      #3
      Re: STDOUT vs. php://STDOUT

      Rik Wasmus schrieb:
      define('CONSTAN T',fopen('test. txt','w');
      It's abusing a behaviour that's not supposed to be so (constants should
      only hold scalars), and I certainly will not guarantee you this will
      work n arbitrary versions of PHP, however, different versions I've
      worked with had that 'feature'.
      You mean it *is* actually possible to define constants with non-scalar
      values, contrary to what the manual says? Could they even be objects or
      arrays? In which versions of PHP does this work?

      Greetings,
      Thomas

      --
      Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
      (Coluche)

      Comment

      • Rik Wasmus

        #4
        Re: STDOUT vs. php://STDOUT

        On Sat, 17 May 2008 14:56:23 +0200, Thomas Mlynarczyk
        <thomas@mlynarc zyk-webdesign.dewro te:
        Rik Wasmus schrieb:
        >
        >define('CONSTA NT',fopen('test .txt','w');
        >It's abusing a behaviour that's not supposed to be so (constants should
        >only hold scalars), and I certainly will not guarantee you this will
        >work n arbitrary versions of PHP, however, different versions I've
        >worked with had that 'feature'.
        >
        You mean it *is* actually possible to define constants with non-scalar
        values, contrary to what the manual says? Could they even be objects or
        arrays?
        Nope, AFAIK, this only works for stream resouces. You could define a
        custom stream wrapper to objects or arrays, and check wether this works,
        but it seems an awful lot of trouble for something that could be removed
        from PHP at any time, and cheating scope is often a sign bad design.
        In which versions of PHP does this work?
        I haven't met a PHP4 / 5 version yet in which this didn't work. I did not
        test all of them though.
        --
        Rik Wasmus
        ....spamrun finished

        Comment

        • Rik Wasmus

          #5
          Re: STDOUT vs. php://STDOUT

          On Sun, 18 May 2008 04:15:43 +0200, ljb <ljb1813@pobox. comwrote:
          luiheidsgoeroe@ hotmail.com wrote:
          >On Sat, 17 May 2008 14:56:23 +0200, Thomas Mlynarczyk
          ><thomas@mlynar czyk-webdesign.dewro te:
          >>
          >>Rik Wasmus schrieb:
          >>>
          >>>define('CONS TANT',fopen('te st.txt','w');
          >>>It's abusing a behaviour that's not supposed to be so (constants
          >>>should
          >>>only hold scalars), and I certainly will not guarantee you this will
          >>>work n arbitrary versions of PHP, however, different versions I've
          >>>worked with had that 'feature'.
          >>>
          >>You mean it *is* actually possible to define constants with non-scalar
          >>values, contrary to what the manual says? Could they even be objectsor
          >>arrays?
          >>
          >Nope, AFAIK, this only works for stream resouces. You could define a
          >custom stream wrapper to objects or arrays, and check wether this works,
          >but it seems an awful lot of trouble for something that could be removed
          > from PHP at any time, and cheating scope is often a sign bad design.
          >>
          >>In which versions of PHP does this work?
          >>
          >I haven't met a PHP4 / 5 version yet in which this didn't work. I did
          >not
          >test all of them though.
          >
          The manual says "Do not define resource constants", but the PHP define()
          function is written to accept resources (of any type). And the PHP CLI
          module defines constants such as STDOUT with resources as values.
          >
          I think the explanation is that while resource constants work, PHP is
          unaware of the defined constant when it manages whatever the resource
          represents. So if the resource is freed using a function or when its
          variable goes out of scope, the constant is now indeterminate. It might
          point to nothing, or it might point to another resource that re-used the
          integer value. For example:
          $f = fopen('test1.da t', 'w');
          define('myfile' , $f);
          fwrite(myfile, "Line written to file\n");
          fclose($f);
          $f = fopen('test2.da t', 'w');
          fwrite(myfile, "Where will this go?\n");
          (Try it without the second fopen. Can you explain what happens? I can't.)
          A quick check here reveals that allthough fclose($f) is called, the stream
          is NOT closed, and you can still use both $f and myfile to write. The same
          goes the other way around with fclose(myfile), and then trying to write
          with $f & myfile both work. Both the $f AND myfile have to be closed
          before the stream is definitly closed / fwrite generates a warning. So
          your premise about it being closed by either is wrong. Observe the
          difference in output/test1.dat:
          <?php
          $f = fopen('test1.da t', 'w');
          define('myfile' , $f);
          fwrite(myfile, "Line written to file\n");
          var_dump(myfile ,$f,$f===myfile );
          fclose(myfile);
          var_dump(myfile ,$f,$f===myfile );
          fwrite(myfile, "This will also go to file\n");
          fclose(myfile);
          fwrite(myfile, "Issues a warning, invalid stream\n");
          ?>
          And:
          <?php
          $f = fopen('test1.da t', 'w');
          $g = $f;
          fwrite($g, "Line written to file\n");
          var_dump($g,$f, $f===$g);
          fclose($g);
          var_dump($g,$f, $f===$g);
          fwrite($g, "This will fail\n");
          fclose($g);
          fwrite($g, "And this one of course too\n");
          ?>

          And this is all nice & theoretical, never ever define something elsethena
          constant as a scalar. Quick run-once-and-this-saves-time code, maybe, but
          not ever in a system meant to be run after that day.
          --
          Rik Wasmus
          ....spamrun finished

          Comment

          • Thomas Mlynarczyk

            #6
            Re: STDOUT vs. php://STDOUT

            Rik Wasmus schrieb:

            [defining constants with non-scalars other than resources?]
            Nope, AFAIK, this only works for stream resouces. You could define a
            custom stream wrapper to objects or arrays, and check wether this works,
            but it seems an awful lot of trouble for something that could be removed
            from PHP at any time, and cheating scope is often a sign bad design.
            I agree. However, it would be useful to be able to define arrays as
            constants. I suppose, resources only work because the variable holds
            just a handle, which internally is an integer and thus perfectly valid
            for a constant.

            Greetings,
            Thomas

            --
            Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
            (Coluche)

            Comment

            Working...