Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

php i/o streams not seeming to work #103

Closed
jistok opened this issue Sep 22, 2015 · 6 comments
Closed

php i/o streams not seeming to work #103

jistok opened this issue Sep 22, 2015 · 6 comments

Comments

@jistok
Copy link

jistok commented Sep 22, 2015

I had expected more info going to the logs, however the only thing i've gotten to work so far is error_log. Is this expected behavior? Sample php file here does not show stdout/stderr in the logs but does write the output stream and error_log line:

<?php

$output = fopen('php://output', 'w');
ob_start();

echo "regular echo\n";
$stdout = fopen('php://stdout', 'w');
$stderr = fopen('php://stdout', 'w');

for($loop=0; $loop<1000; $loop++)
{
    fwrite($stdout, $loop . " writing to stdout directly\n");
    fwrite($output, $loop . " writing to php://output directly\n");
    fwrite($stderr, $loop . " writing to stderr directly\n");
}

fclose($stdout);
fclose($stderr);
$ob_contents = ob_get_clean();
print "ob_contents: $ob_contents\n";

error_log("will you work");

?>
@cf-gitbot
Copy link

We have created an issue in Pivotal Tracker to manage this. You can view the current status of your issue at: https://www.pivotaltracker.com/story/show/103957712.

@dmikusa
Copy link

dmikusa commented Sep 23, 2015

Are you accessing this as a web page? or are you running this as a cli script? I think the behavior would be different depending on what you're doing.

If it's a web page, this is what I'd expect...

1.) print, echo and php://stdout all go to the same place, the output buffer. Normally this is the response that get's returned to the HTTP client.

2.) Because you've called ob_start, the output buffer is not the response rather it's an in-memory buffer, which means nothing is written until you call print in the second to last line of the script. You're calling print on the second to last line, so that writing the contents of buffer to the response.

3.) Calling ob_start after calling fopen (on the first line) doesn't matter. After ob_start everything get's buffered, until you stop buffering.

This function will turn output buffering on. While output buffering is active no output is sent from the script (other than headers), instead the output is stored in an internal buffer.

http://php.net/manual/en/function.ob-start.php

Also, you're calling $stderr = fopen('php://stdout', 'w');, did you mean $stderr = fopen('php://stderr', 'w');?

Lastly, what do you see when you run this locally? What version of PHP is your local server using? Is it using fast-cgi or mod_php?

Thanks!

@jistok
Copy link
Author

jistok commented Sep 23, 2015

hi again daniel. appreciate the msg. this is a web page and ive
simplified everything and taked out the ob_* stuff. Attached you can see
the full manifest as well as the original (index-orig.php) and the new one
(index.php). The log of index.php is (note i get the error_log stuff) -
right after that is my local run of using the builtin php server:

2015-09-22T20:20:44.15-0700 [DEA/40]     OUT Starting app instance (index
0) with guid f29969fe-c83a-4e4b-b715-a922ce1e2aa0
2015-09-22T20:20:52.48-0700 [App/0]      OUT 03:20:52 php-fpm |
[23-Sep-2015 03:20:52] NOTICE: fpm is running, pid 38
2015-09-22T20:20:52.48-0700 [App/0]      OUT 03:20:52 php-fpm |
[23-Sep-2015 03:20:52] NOTICE: ready to handle connections
2015-09-22T20:20:52.51-0700 [App/0]      OUT 03:20:52 httpd   | [Wed Sep 23
03:20:52.503628 2015] [mpm_event:notice] [pid 36:tid 139712649979712]
AH00489: Apache/2.4.16 (Unix) configured -- resuming normal operations
2015-09-22T20:20:52.51-0700 [App/0]      OUT 03:20:52 httpd   | [Wed Sep 23
03:20:52.503743 2015] [mpm_event:info] [pid 36:tid 139712649979712]
AH00490: Server built: Jul 22 2015 20:20:52
2015-09-22T20:20:52.51-0700 [App/0]      OUT 03:20:52 httpd   | [Wed Sep 23
03:20:52.503757 2015] [core:notice] [pid 36:tid 139712649979712] AH00094:
Command line: '/app/httpd/bin/httpd -f /home/vcap/app/httpd/conf/httpd.conf
-D FOREGROUND'
2015-09-22T20:21:09.76-0700 [App/0]      OUT 03:21:09 httpd   | [Wed Sep 23
03:21:09.767457 2015] [proxy_fcgi:error] [pid 49:tid 139712589805312]
[client 64.134.232.87:60676] AH01071: Got error 'PHP message: will you
work\n'
2015-09-22T20:21:09.76-0700 [App/0]      OUT 03:21:09 httpd   |
64.134.232.87 - - [23/Sep/2015:03:21:09 +0000] "GET / HTTP/1.1" 200 363
vcap_request_id=5a9bfa35-8b6b-4a1b-43d6-d60f6d52710a peer_addr=10.10.16.16
2015-09-22T20:21:09.77-0700 [RTR/1]      OUT jistok.cfapps.io -
[23/09/2015:03:21:09 +0000] "GET / HTTP/1.1" 200 0 363 "-" "Mozilla/5.0
(Macintosh; Intel Mac OS X 10_11_1) AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/45.0.2454.99 Safari/537.36" 10.10.2.35:44620
x_forwarded_for:"64.134.232.87" x_forwarded_proto:"http"
vcap_request_id:5a9bfa35-8b6b-4a1b-43d6-d60f6d52710a
response_time:0.003506534 app_id:f29969fe-c83a-4e4b-b715-a922ce1e2aa0

NOTE - locally just using the php builtin (also on 5.6) i get what is
expected:

JMFI:~/working/cf/jistok> php -S localhost:8000 -t .
PHP 5.6.12 Development Server started at Tue Sep 22 20:23:46 2015
Listening on http://localhost:8000
Document root is /Users/jistok/working/cf/jistok
Press Ctrl-C to quit.
0 writing to stdout directly
0 writing to stderr directly
1 writing to stdout directly
1 writing to stderr directly
2 writing to stdout directly
2 writing to stderr directly
3 writing to stdout directly
3 writing to stderr directly
4 writing to stdout directly
4 writing to stderr directly
5 writing to stdout directly
5 writing to stderr directly
6 writing to stdout directly
6 writing to stderr directly
7 writing to stdout directly
7 writing to stderr directly
8 writing to stdout directly
8 writing to stderr directly
9 writing to stdout directly
9 writing to stderr directly
[Tue Sep 22 20:23:52 2015] will you work
[Tue Sep 22 20:23:52 2015] ::1:56227 [200]: /

@dmikusa
Copy link

dmikusa commented Sep 23, 2015

Sorry, I don't see your attachments. Here's the script that I used:

<?php
    $output = fopen('php://output', 'w');
    $stdout = fopen('php://stdout', 'w');
    $stderr = fopen('php://stderr', 'w');

    for($loop=0; $loop<10; $loop++)
    {
        fwrite($output, $loop . " writing to php://output directly\n");
        fwrite($stdout, $loop . " writing to stdout directly\n");
        fwrite($stderr, $loop . " writing to stderr directly\n");
    }

    fwrite($stdout, "Post loop - writing to stdout directly\n");
    fwrite($stderr, "Post loop - writing to stderr directly\n");

    error_log("will you work");

    fclose($output);
    fclose($stdout);
    fclose($stderr);
?>

When I run this, I all I see 10 calls of "writing to php://output directly" and the error_log output. I suspect that the difference we're seeing is because we use php-fpm and FastCGI to run apps on PWS and you're using the built-in HTTP server.

If you want similar behavior from PWS, you're going to need to change this option in php-fpm.conf.

https://github.com/cloudfoundry/php-buildpack/blob/master/defaults/config/php/5.6.x/php-fpm.conf#L471-L476

You can do that by adding a .bp-config/php/php-fpm.conf file to your project. This will override the default one that we use on PWS, so you can change this and other options. Please note that it completely overrides the default, so you should start by downloading the default for your version of PHP and then modifying it to fit your needs. 5.4 5.5 5.6

The other option would be to just use PHP's built-in HTTP server. You can do that by setting "WEB_SERVER": "none" in .bp-config/options.json. This will instruct the build pack not to download a web server. Then you need to specify a custom start command. You can do this with the -b argument to cf push or by adding a command block into your manifest.yml file.

Ex:

---
applications:
- name: php-info
  memory: 128M
  instances: 1
  host: php-info
  path: .
  command: php -S 0.0.0.0:$PORT -t .

Note that we use $PORT which contains the right port for the app to listen. The -t argument should point to your files. . will tell it to serve them from the root of your project. If you've got a public, html or htdocs folder then you'd want -t htdocs/ or whatever your folder name should be.

For what it's worth, I have only seen PHP's HTTP server listed as "dev" quality. We go with the FastCGI setup in the build pack because this is widely recognized as the best option for production PHP installations. You're welcome to use the built in HTTP server if it works for you though.

@jistok
Copy link
Author

jistok commented Sep 23, 2015

fantastic! i looked everywhere for this. the catch_workers_output = yes
is exactly what i was looking for (and actually think it should be on by
default myself). Thanks so much again!

-j

On Wed, Sep 23, 2015 at 6:22 AM, Daniel Mikusa notifications@github.com
wrote:

Sorry, I don't see your attachments. Here's the script that I used:

When I run this, I all I see 10 calls of "writing to php://output
directly" and the error_log output. I suspect that the difference we're
seeing is because we use php-fpm and FastCGI to run apps on PWS and
you're using the built-in HTTP server.

If you want similar behavior from PWS, you're going to need to change this
option in php-fpm.conf.

https://github.com/cloudfoundry/php-buildpack/blob/master/defaults/config/php/5.6.x/php-fpm.conf#L471-L476

You can do that by adding a .bp-config/php/php-fpm.conf file to your
project. This will override the default one that we use on PWS, so you can
change this and other options. Please note that it completely overrides the
default, so you should start by downloading the default for your version of
PHP and then modifying it to fit your needs. 5.4
https://raw.githubusercontent.com/cloudfoundry/php-buildpack/master/defaults/config/php/5.4.x/php-fpm.conf
5.5
https://raw.githubusercontent.com/cloudfoundry/php-buildpack/master/defaults/config/php/5.5.x/php-fpm.conf
5.6
https://raw.githubusercontent.com/cloudfoundry/php-buildpack/master/defaults/config/php/5.6.x/php-fpm.conf

The other option would be to just use PHP's built-in HTTP server. You can
do that by setting "WEB_SERVER": "none" in .bp-config/options.json. This
will instruct the build pack not to download a web server. Then you need to
specify a custom start command. You can do this with the -b argument to cf
push or by adding a command block into your manifest.yml file.

Ex:


applications:

  • name: php-info
    memory: 128M
    instances: 1
    host: php-info
    path: .
    command: php -S 0.0.0.0:$PORT -t .

Note that we use $PORT which contains the right port for the app to
listen. The -t argument should point to your files. . will tell it to
serve them from the root of your project. If you've got a public, html or
htdocs folder then you'd want -t htdocs/ or whatever your folder name
should be.


Reply to this email directly or view it on GitHub
#103 (comment)
.

@flavorjones
Copy link
Contributor

@dmikusa-pivotal Thanks for working through this! Closing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants