fwrite(STDERR,"...") yields an error:
"PHP Warning: fwrite(): supplied argument is not a valid stream
resource ..."
I can work around this by using file_put_contents("php://stderr","..."),
but the page that documents php://stderr, says:
"php://stdin, php://stdout and php://stderr allow access to the
corresponding input or output stream of the PHP process. The stream
references a duplicate file descriptor, so if you open php://stdin and
later close it, you close only your copy of the descriptor--the actual
stream referenced by STDIN is unaffected. Note that PHP exhibited buggy
behavior in this regard until PHP 5.2.1. It is recommended that you
simply use the constants STDIN, STDOUT and STDERR instead of manually
opening streams using these wrappers. "
So, what functions should I use with STDERR, since fwrite() does not like
STDERR?
--
Robert Heller -- 978-544-6933
Deepwoods Software -- Download the Model Railroad System
http://www.deepsoft.com/ -- Binaries for Linux and MS-Windows
hel...@deepsoft.com -- http://www.deepsoft.com/ModelRailroadSystem/
> I am using PHP5 (5.1.6)
>
> fwrite(STDERR,"...") yields an error:
>
> "PHP Warning: fwrite(): supplied argument is not a valid stream
> resource ..."
>
> I can work around this by using
> file_put_contents("php://stderr","..."), but the page that
> documents php://stderr, says:
>
> "php://stdin, php://stdout and php://stderr allow access to the
> corresponding input or output stream of the PHP process. The
> stream references a duplicate file descriptor, so if you open
> php://stdin and later close it, you close only your copy of the
> descriptor--the actual stream referenced by STDIN is unaffected.
> Note that PHP exhibited buggy behavior in this regard until PHP
> 5.2.1. It is recommended that you simply use the constants STDIN,
> STDOUT and STDERR instead of manually opening streams using
> these wrappers. "
>
> So, what functions should I use with STDERR, since fwrite() does
> not like STDERR?
Those constants are only defined when using PHP from the command
line. Are you attempting to use them in a server environment?
In a server environment, you might find using the `error_log()'
function more helpful than relying on using the STDERR stream. If
`error_log()' isn't what you want, you might try rolling your own
error handling functions/classes.
<http://php.net/manual/en/function.error-log.php>
--
int i;main(){for(;i["]<i;++i){--i;}"];read('-'-'-',i+++"hell\
o, world!\n",'/'/'/'));}read(j,i,p){write(j/p+p,i---j,i/i);}
~ Anonymous (1984 IOCCC winner)
>
> On 04 Jul 2009, Robert Heller <hel...@deepsoft.com> wrote:
>
> > I am using PHP5 (5.1.6)
> >
> > fwrite(STDERR,"...") yields an error:
> >
> > "PHP Warning: fwrite(): supplied argument is not a valid stream
> > resource ..."
> >
> > I can work around this by using
> > file_put_contents("php://stderr","..."), but the page that
> > documents php://stderr, says:
> >
> > "php://stdin, php://stdout and php://stderr allow access to the
> > corresponding input or output stream of the PHP process. The
> > stream references a duplicate file descriptor, so if you open
> > php://stdin and later close it, you close only your copy of the
> > descriptor--the actual stream referenced by STDIN is unaffected.
> > Note that PHP exhibited buggy behavior in this regard until PHP
> > 5.2.1. It is recommended that you simply use the constants STDIN,
> > STDOUT and STDERR instead of manually opening streams using
> > these wrappers. "
> >
> > So, what functions should I use with STDERR, since fwrite() does
> > not like STDERR?
>
> Those constants are only defined when using PHP from the command
> line. Are you attempting to use them in a server environment?
Yes. So how do people debug server-side PHP code if it is not possible
to write to stderr (my classic way of debugging code is to print
debugging messages to stderr, esp. in environments where an interactive
debugger is not possible)?!?
>
> In a server environment, you might find using the `error_log()'
> function more helpful than relying on using the STDERR stream. If
> `error_log()' isn't what you want, you might try rolling your own
> error handling functions/classes.
>
> <http://php.net/manual/en/function.error-log.php>
OK, I'll check this out.
You don't have a console, so you don't have the console streams.
You can display error messages or write them to an error log.
Plus, there are interactive debuggers for PHP. Also, you should always
have a local test machine and never develop on a production system.
>> In a server environment, you might find using the `error_log()'
>> function more helpful than relying on using the STDERR stream. If
>> `error_log()' isn't what you want, you might try rolling your own
>> error handling functions/classes.
>>
>> <http://php.net/manual/en/function.error-log.php>
>
> OK, I'll check this out.
>
>
--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
jstu...@attglobal.net
==================
How very 'MS-Windows' PHP is. :-) In the UNIX world 'stderr' is always
available, even if there is no 'console'. In the UNIX world, the term
'console streams' does not really mean much -- stderr is just FD #2 and
even deamon process would have it bound to something (a log file for
example). Apache binds it to its error_log and in fact passes it on to
its modules and/or sub-processes (in the case of CGI scripts). Mod_php
should have stderr available, if it cared to bind it to an open stream
(php://stderr does in fact work). Not binding STDERR does not make any
sense to me, but then I am a long time UNIX/Linux user and most of the
MS-Windows way of doing things makes no sense (to me).
When I coded CGI scripts (in Tcl), I could always write to stderr and the
output would land in Apache's error log (typically
/var/log/httpd/error_log), which I could monitor with a shell terminal.
>
> You can display error messages or write them to an error log.
>
> Plus, there are interactive debuggers for PHP. Also, you should always
> have a local test machine and never develop on a production system.
I have a local test machine, which is running a (local) server
environment. It is my CentOS desktop machine, which also runs Apache,
MySql, etc. -- it is more or less a mirror of my production server,
except it is not 'visible' to the public InterNet.
Do the interactive debuggers for PHP function in a server environment?
>
> >> In a server environment, you might find using the `error_log()'
> >> function more helpful than relying on using the STDERR stream. If
> >> `error_log()' isn't what you want, you might try rolling your own
> >> error handling functions/classes.
> >>
> >> <http://php.net/manual/en/function.error-log.php>
> >
> > OK, I'll check this out.
> >
> >
>
>
--
This has nothing to do with Windows vs. Unix. I don't know where you
think stderr is available with Unix under Apache - AFAIK, it's not
available in PHP, Perl or Java (as modules). I'm not sure about other
languages.
> When I coded CGI scripts (in Tcl), I could always write to stderr and the
> output would land in Apache's error log (typically
> /var/log/httpd/error_log), which I could monitor with a shell terminal.
>
Running as a CGI is not the same as running as an Apache module.
>> You can display error messages or write them to an error log.
>>
>> Plus, there are interactive debuggers for PHP. Also, you should always
>> have a local test machine and never develop on a production system.
>
> I have a local test machine, which is running a (local) server
> environment. It is my CentOS desktop machine, which also runs Apache,
> MySql, etc. -- it is more or less a mirror of my production server,
> except it is not 'visible' to the public InterNet.
>
> Do the interactive debuggers for PHP function in a server environment?
>
Yes, they do. But I've never needed one for PHP scripts.
>>>> In a server environment, you might find using the `error_log()'
>>>> function more helpful than relying on using the STDERR stream. If
>>>> `error_log()' isn't what you want, you might try rolling your own
>>>> error handling functions/classes.
>>>>
>>>> <http://php.net/manual/en/function.error-log.php>
>>> OK, I'll check this out.
>>>
>>>
>>
>
--
It IS available to PHP, since php://stderr works just fine (it is just
combersome to use it that way -- opening/closing a file to write just
one line to it). It is available to CGI scripts (written Perl, C/C++,
or Tcl). Apache re-opens fd#2 (stderr) when it fades into deamon state
on startup to its log file and all processes it creates inhierit this
channel.
>
> > When I coded CGI scripts (in Tcl), I could always write to stderr and the
> > output would land in Apache's error log (typically
> > /var/log/httpd/error_log), which I could monitor with a shell terminal.
> >
>
> Running as a CGI is not the same as running as an Apache module.
I know. OTOH, CGI scripts are invoked from the CGI module which pretty
much just calls fork() and exec() (either the CGI script is directly run
or it is passed to suexec for security checks and UID/GID munging). File
channels are passed along during the fork() call.
>
> >> You can display error messages or write them to an error log.
> >>
> >> Plus, there are interactive debuggers for PHP. Also, you should always
> >> have a local test machine and never develop on a production system.
> >
> > I have a local test machine, which is running a (local) server
> > environment. It is my CentOS desktop machine, which also runs Apache,
> > MySql, etc. -- it is more or less a mirror of my production server,
> > except it is not 'visible' to the public InterNet.
> >
> > Do the interactive debuggers for PHP function in a server environment?
> >
>
> Yes, they do. But I've never needed one for PHP scripts.
>
> >>>> In a server environment, you might find using the `error_log()'
> >>>> function more helpful than relying on using the STDERR stream. If
> >>>> `error_log()' isn't what you want, you might try rolling your own
> >>>> error handling functions/classes.
> >>>>
> >>>> <http://php.net/manual/en/function.error-log.php>
> >>> OK, I'll check this out.
> >>>
> >>>
> >>
> >
>
>
--
Exactly. You have to OPEN and CLOSE a file to write to it. It is just
another stream - it is NOT the same as STDERR.
The Apache stderr is a completely different stream.
>>> When I coded CGI scripts (in Tcl), I could always write to stderr and the
>>> output would land in Apache's error log (typically
>>> /var/log/httpd/error_log), which I could monitor with a shell terminal.
>>>
>> Running as a CGI is not the same as running as an Apache module.
>
> I know. OTOH, CGI scripts are invoked from the CGI module which pretty
> much just calls fork() and exec() (either the CGI script is directly run
> or it is passed to suexec for security checks and UID/GID munging). File
> channels are passed along during the fork() call.
>
That is a fair summary of the way some CGIs work.
> At Sun, 05 Jul 2009 09:11:29 -0400 Jerry Stuckle
> <jstu...@attglobal.net> wrote:
>> Robert Heller wrote:
>> > At Sun, 05 Jul 2009 06:54:07 GMT Curtis Dyer
>> > <dye...@gmail.com> wrote:
>> >> On 04 Jul 2009, Robert Heller <hel...@deepsoft.com> wrote:
<snip>
>> >>> So, what functions should I use with STDERR, since fwrite()
>> >>> does not like STDERR?
>> >> Those constants are only defined when using PHP from the
>> >> command line. Are you attempting to use them in a server
>> >> environment?
>> >
>> > Yes. So how do people debug server-side PHP code if it is not
>> > possible to write to stderr (my classic way of debugging code
>> > is to print debugging messages to stderr, esp. in environments
>> > where an interactive debugger is not possible)?!?
>>
>> You don't have a console, so you don't have the console streams.
>
> How very 'MS-Windows' PHP is. :-)
Not really.
> In the UNIX world 'stderr' is always available, even if there
> is no 'console'.
This is the case on Windows, as far as I know.
> In the UNIX world, the term 'console streams' does not really
> mean much -- stderr is just FD #2 and even deamon process would
> have it bound to something (a log file for example). Apache
> binds it to its error_log and in fact passes it on to its
> modules and/or sub-processes (in the case of CGI scripts).
If you want to write an error message to your server's error log,
use the `error_log()' function, as suggested before. It's easier
to use than "fwrite(STDERR, 'Message...');" and can be adapted to
write to a log file of your choosing or even send an email.
> Mod_php should have stderr available, if it cared to
> bind it to an open stream (php://stderr does in fact work).
> Not binding STDERR does not make any sense to me,
I also don't know why they didn't provide the constants for PHP
running in a server environment, but it's not a problem.
Generally, I don't find it useful for my PHP applications to send
errors to my server's error log, because it generally doesn't
make sense for them to be there.
> but then I am a long time UNIX/Linux user and most of the
> MS-Windows way of doing things makes no sense (to me).
As far as I can tell, Windows has nothing to do with anything
here.
> When I coded CGI scripts (in Tcl), I could always write to
> stderr and the output would land in Apache's error log
> (typically /var/log/httpd/error_log), which I could monitor
> with a shell terminal.
<http://php.net/manual/en/function.error-log.php>
<snip>
>
> Robert Heller wrote:
> > At Sun, 05 Jul 2009 14:09:57 -0400 Jerry Stuckle <jstu...@attglobal.net> wrote:
> >
> >> Robert Heller wrote:
> >>> At Sun, 05 Jul 2009 09:11:29 -0400 Jerry Stuckle <jstu...@attglobal.net> wrote:
> >> This has nothing to do with Windows vs. Unix. I don't know where you
> >> think stderr is available with Unix under Apache - AFAIK, it's not
> >> available in PHP, Perl or Java (as modules). I'm not sure about other
> >> languages.
> >
> > It IS available to PHP, since php://stderr works just fine (it is just
> > combersome to use it that way -- opening/closing a file to write just
> > one line to it). It is available to CGI scripts (written Perl, C/C++,
> > or Tcl). Apache re-opens fd#2 (stderr) when it fades into deamon state
> > on startup to its log file and all processes it creates inhierit this
> > channel.
> >
>
> Exactly. You have to OPEN and CLOSE a file to write to it. It is just
> another stream - it is NOT the same as STDERR.
>
> The Apache stderr is a completely different stream.
Are you really sure? According to the documentation for php://stderr,
it is (as I understand it) pretty much a wrapper for the C stdio
function 'fdopen(dup(2),"w")': "The stream references a duplicate file
descriptor, ..." (see: http://php.net/manual/en/wrappers.php.php). This
pretty much suggests to me that Apache's stderr is just bound to it's
error log, and the actual behaviour seems to confirm it. The
documentation also suggests not using the wrappers due to buggy
behaviour.
>
> >>> When I coded CGI scripts (in Tcl), I could always write to stderr and the
> >>> output would land in Apache's error log (typically
> >>> /var/log/httpd/error_log), which I could monitor with a shell terminal.
> >>>
> >> Running as a CGI is not the same as running as an Apache module.
> >
> > I know. OTOH, CGI scripts are invoked from the CGI module which pretty
> > much just calls fork() and exec() (either the CGI script is directly run
> > or it is passed to suexec for security checks and UID/GID munging). File
> > channels are passed along during the fork() call.
> >
>
> That is a fair summary of the way some CGIs work.
>
>
>
>
--
"Pretty much" is not the same as. And even in UNIX, stderr has to have
somewhere to go. The default is the console (window) if the application
has a console attached. However, in the case of Apache and similar,
these are started in the background without any console. So where do
you expect stderr to go?
The Apache stderr error log is NOT the same as a console stderr! And
once a file descriptor has been closed, it is available for someone else
to allocate - in any OS. It can even be used to point to an error log
by the application.
In apache, either as a CGI or module, filehandle 2 should be available
and associated with the ErrorLog file.
C.
I would like to do what i think Robert wants to do:
Use statements like
fprintf(STDERR,"blah blah %d\n",5);
in a server program and have it show up where everything
else written to file descriptor 2 shows up.
As others in the thread have noted it is possible to
write to file descriptor 2 in php, but indirectly.
One way of doing this is
system("/bin/echo blah blah 1>&2",$ret_val);
and at least on my system it will certainly wind up
in the apache error log, exactly, character-for-character,
as i sent it, with no extra characters like error_log() emits.
But this sacrifices the ease and versatility of
the fprintf formatting.
Also, i have tried "php://stderr", and it doesn't seem
to work for me in the server context, although it works in the CLI.
The code i have tried is along the lines of
$fp=fopen("php://stderr","w");
if ($fp===false) do_something();
fprintf($fp,"blah blah\n");
This works in the CLI, but doesn't seem to in the server context
(more exactly, $fp is not === false, but the characters just
disappear).
(My php version is 5.2.3 so that should be late enough.)
So i would really appreciate it if somebody could tell me
what i would need to do to get a "resource" from a statement like
$fp=fopen("php://stderr","w");
Perhaps extra arguments, or other calls somewhere? I just would like
to get the equivalent of STDERR, in a server context, somehow.
Second, i can't find a discussion of STDERR or fprintf() in the php
online
documentation that unambiguously states exactly what is happening
in the server environment. That is, it would be good to have,from
an authoritative source, a 3-sentence declaration along the lines of:
STDERR is defined in the CLI environment.
STDERR is not defined in a server environment.
There is no way to access a resource wrapping file descriptor 2
in the server environment.
if this is indeed true. Of course, i hope it's not true.
Thanks in advance anybody for any advice on how to grab hold
of something like STDERR in a server environment.
dan
On Jul 6, 5:02 am, "C. (http://symcbean.blogspot.com/)"
>
> Thanks Colin for your post. It would be nice indeed
> if filehandle 2 were available and associated with
> the ErrorLog file.
>
> I would like to do what i think Robert wants to do:
>
> Use statements like
> fprintf(STDERR,"blah blah %d\n",5);
> in a server program and have it show up where everything
> else written to file descriptor 2 shows up.
>
> As others in the thread have noted it is possible to
> write to file descriptor 2 in php, but indirectly.
> One way of doing this is
> system("/bin/echo blah blah 1>&2",$ret_val);
> and at least on my system it will certainly wind up
> in the apache error log, exactly, character-for-character,
> as i sent it, with no extra characters like error_log() emits.
>
> But this sacrifices the ease and versatility of
> the fprintf formatting.
>
> Also, i have tried "php://stderr", and it doesn't seem
> to work for me in the server context, although it works in the CLI.
> The code i have tried is along the lines of
> $fp=3Dfopen("php://stderr","w");
> if ($fp=3D=3D=3Dfalse) do_something();
> fprintf($fp,"blah blah\n");
> This works in the CLI, but doesn't seem to in the server context
> (more exactly, $fp is not =3D=3D=3D false, but the characters just
> disappear).
> (My php version is 5.2.3 so that should be late enough.)
>
> So i would really appreciate it if somebody could tell me
> what i would need to do to get a "resource" from a statement like
> $fp=3Dfopen("php://stderr","w");
> Perhaps extra arguments, or other calls somewhere? I just would like
> to get the equivalent of STDERR, in a server context, somehow.
>
> Second, i can't find a discussion of STDERR or fprintf() in the php
> online
> documentation that unambiguously states exactly what is happening
> in the server environment. That is, it would be good to have,from
> an authoritative source, a 3-sentence declaration along the lines of:
> STDERR is defined in the CLI environment.
> STDERR is not defined in a server environment.
> There is no way to access a resource wrapping file descriptor 2
> in the server environment.
> if this is indeed true. Of course, i hope it's not true.
>
> Thanks in advance anybody for any advice on how to grab hold
> of something like STDERR in a server environment.
put_file_contents("php://stderr","blah, blah\n");
works, but is awkward.
error_log(...) also works, but is lso awkward.
In a *UNIX* environment, fds 0, 1, and 2 are generally available. It
takes some specific fenagling to actually have these fds be closed.
Initially the init program (the 'grandparenet of all processes) opens
them and binds them to the system console. Later, daemon process
rebind them one way or another. Apache binds fd 2 to its error log
(yes, this really happens, since fd 2 is in turn *inherieted* by CGI
scripts (forked from an httpd process). There really isn't any *sane*
reason for STDERR not to be available in a server context. This is
either an oversighte or something (screwy) in the PHP design. Or if it
really is intended, it should at least be properly documented! -- The
online documentation does NOT definitively state that STDERR is not
available in a server context. It seems to assume that it is not
availale. *My* thought is that this is just plain broken. If I was
more of a full time PHP coder, I'd probably file a bug report, although
I suspect that I'd likely get flamed for doing so.
>
> dan
>
>
> On Jul 6, 5:02=A0am, "C. (http://symcbean.blogspot.com/)"
> <colin.mckin...@gmail.com> wrote:
> > On Jul 5, 7:09=A0pm, Jerry Stuckle <jstuck...@attglobal.net> wrote:
> >
> > > Robert Heller wrote:
> > > > At Sun, 05 Jul 2009 09:11:29 -0400 Jerry Stuckle <jstuck...@attglobal=
> .net> wrote:
> >
> > > >> Robert Heller wrote:
> > > >>> At Sun, 05 Jul 2009 06:54:07 GMT Curtis Dyer <dye...@gmail.com> wro=
> te:
> >
> > > >>>> On 04 Jul 2009, Robert Heller <hel...@deepsoft.com> wrote:
> >
> > > >>>>> I am using PHP5 (5.1.6)
> >
> > > >>>>> fwrite(STDERR,"...") yields an error:
>
--
I was wrong, php://stderr does indeed work with fprintf().
It's php://stdout that fails (it should spill out on the web page).
What i wrote in the quoted text was from memory, and that
was just irresponsible, so i'm sorry for writing it.
In fact, this code:
$fp=fopen("php://
stderr","w");
if ($fp===false) {
echo "<pre>could not open stderr for writing</pre>
\n";
} else {
fprintf($fp,"this came through an fprintf() to php://stderr (w)
\n");
fflush
($fp);
fclose
($fp);
}
works.
And this works whether we open php://stderr with "w" or "a".
If, in place of php://stderr, we use php://stdout or /dev/stdout
(this is a linux system, ubuntu 8.10), it fails silently. It
should spill onto the web page but simply doesn't.
If we use /dev/stderr we fail but with a permission error,
so at least there's an error message to work with.
I'm fine with that---although in a command line environment
/dev/stderr does work---because it does give me a path in to
STDERR.
The funky asymmetry between php://stdout and php://stderr is
a little disquieting, as are the vanishing characters.
Anybody who has some insight in to the theory of php,
please advise on why php://stderr and php://stdout are
different, and likewise /dev/stdout and /dev/stderr,
and the difference between the command line context and
server context. Thanks in advance.
dan
On Jul 18, 6:53 pm, Robert Heller <hel...@deepsoft.com> wrote:
> At Sat, 18 Jul 2009 16:33:21 -0700 (PDT) dan <dan.h...@gmail.com> wrote:
........
> > Also, i have tried "php://stderr", and it doesn't seem
> > to work for me in the server context, although it works in the CLI.
> > The code i have tried is along the lines of
> > $fp=3Dfopen("php://stderr","w");
> > if ($fp=3D=3D=3Dfalse) do_something();
> > fprintf($fp,"blah blah\n");
> > This works in the CLI, but doesn't seem to in the server context
> > (more exactly, $fp is not =3D=3D=3D false, but the characters just
> > disappear).
****** ACK! sorry for this misinformation!!!, php://stderr does work,
****** it's php://stdout that fails.
> > (My php version is 5.2.3 so that should be late enough.)
........
> --
> Robert Heller -- 978-544-6933
> Deepwoods Software -- Download the Model Railroad Systemhttp://www.deepsoft.com/ -- Binaries for Linux and MS-Windows
> hel...@deepsoft.com --http://www.deepsoft.com/ModelRailroadSystem/
What mode are you running PHP in? CGI, as an Apache module, or CLI?
I don't see any rule that PHP run as an Apache module needs to
route stdout to the web page, as long as the default target of
things like echo and printf ends up on the web page.
>If, in place of php://stderr, we use php://stdout or /dev/stdout
>(this is a linux system, ubuntu 8.10), it fails silently. It
>should spill onto the web page but simply doesn't.
For PHP running as an Apache module, where is that documented?
I'm thinking that in a threaded environment, the output for *all*
web pages being processed simultaneously can't be stdout.