It seems that by default, PHP-CLI now runs solely in quiet mode, instead of requiring the user to pass -q or --no-header.
For example, if phptest.php is the following:
<?php header("Location: http://www.something.com"); ?>
We can request it using cURL and an Apache server, with the following result:
$ curl -I "http://localhost/phptest.php"
HTTP/1.1 302 Found
Date: Tue, 20 Mar 2018 16:47:48 GMT
Server: Apache/2.4.7 (Ubuntu)
X-Powered-By: PHP/5.5.9-1ubuntu4.24
Location: http://www.something.com
Content-Type: text/html
But if we request through the PHP-CLI, we get nothing:
$ php /var/www/phptest.php
My question, then, is how can I get the PHP-CLI to return headers as well? If it's not possible, what alternatives exist (short of cURLing or wgeting it)?
Use php-cgi instead of php:
$ php-cgi /var/www/phptest.php
Status: 302 Moved Temporarily
X-Powered-By: PHP/5.6.32
Location: http://www.something.com
Content-type: text/html; charset=UTF-8
Related
I have two hosting environments, one is running PHP 7.4 with Apache, and the other one is running PHP 8.1 with Nginx both on Azure.
I run this PHP script on both:
<?php ini_set("display_errors", 1); header('Status: 301 Moved Permanently', true, 301); ?>
When I run this code on host 1, I get what I expect; the headers are output as 301:
D:\home\site\wwwroot>curl -is test.php
HTTP/1.1 301 Moved Permanently
Content-Length: 0
Content-Type: text/html; charset=utf-8
Date: Fri, 25 Nov 2022 08:46:09 GMT
Server: Microsoft-IIS/10.0
X-Powered-By: PHP/7.4.30
X-Powered-By: ASP.NET
Running the same script om the Nginx environement under PHP 8.1 I get:
root:/home# curl -is localhost:8080
HTTP/1.1 200 OK
Server: nginx/1.22.1
Date: Fri, 25 Nov 2022 08:45:33 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
X-Powered-By: PHP/8.1.9
<br />
<b>Warning</b>: Cannot modify header information - headers already sent by (output started at /home/site/wwwroot/index.php:1) in <b>/home/site/wwwroot/index.php</b> on line <b>1</b><br />
As you can see the header 301 could not be sent because the 200 header was already sent.
There is absolutely nothing before the first <?php-tag.
I have tried lots of things with the Nginx config, but no result. Is this something that is inside PHP.INI?
What is causing the header 200 to be sent before any line of my PHP script?
Solution: output_buffering is apparently disabled by default, you can turn it on in the INI of PHP, like so:
Create a folder inside /home/site called ini
Add a file there with the extention .ini, like site.ini
Add this line and save:
output_buffering = on
Go to your azure portal to the webapp and inside Configuration add an application setting with name = PHP_INI_SCAN_DIR and value = /usr/local/etc/php/conf:/home/site/ini
Then save the application setting witch will restart your app.
I have a laravel/php script that runs the exec command:
$result = exec($command, $output);
return json_encode($output);
I know exec is dangerous (this is for testing). When I load the page in a browser, the command takes a while and eventually the browser downloads and empty file:
If I comment out the exec command, the page outputs and empty array just fine.
When I use fiddler to see the response I get the following:
HTTP/1.1 200 OK
Date: Thu, 31 Dec 2015 20:08:53 GMT
Server: Apache/2.2.22 (Win32) mod_ssl/2.2.22 OpenSSL/0.9.8x
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: application/x-httpd-php
Content-Length: 0
This happens in Chrome and IE.
PHP-server without router (working)
$ php -S 127.0.0.1:8000
PHP 5.6.15 Development Server started at Sat Nov 21 13:12:04 2015
Listening on http://127.0.0.1:8000
Header of style.css:
$ curl -I http://127.0.0.1:8000/style.css
HTTP/1.1 200 OK
Host: 127.0.0.1:8000
Connection: close
Content-Type: text/css; charset=UTF-8
Content-Length: 23
Content of style.css (via Chrome Inspector, Preview):
body{background:#fff;}
PHP-server with router (not working)
$ php -S 127.0.0.1:8001 router.php
PHP 5.6.15 Development Server started at Sat Nov 21 13:15:02 2015
Listening on http://127.0.0.1:8001
Header of style.css:
$ curl -I http://127.0.0.1:8001/style.css
HTTP/1.1 200 OK
Host: 127.0.0.1:8001
Connection: close
Content-Type: text/css; charset=UTF-8
Content-Length: 23
Content of style.css (via Chrome Inspector, Preview) - problem:
�HTTP/1.1 200 OK
Host: 127.0.0.1:8000
Connection: close
Content-Type: text/css; charset=UTF-8
Content-Length: 23
body{background:#fff;}
Content of router.php
<?php return false; ?>
Why is the HTTP-header written to the top of style.css?
Update: Solution
Set the following value in php.ini:
zlib.output_compression = off
Maybe it's the jetlag, but I'm failing to make PHP/HHVM give me the Content-Type header when I need it.
I've deployed the full stack (MySQL, HHVM, Nginx) on a Vagrant machine and I've managed to reproduce the issue on a test script:
<?php
$file='/usr/share/doc/iptables/html/NAT-HOWTO.html'; # random test file
header('Content-Length: ' . filesize($file));
echo(readfile($file));
?>
If you examine the headers with curl:
hostname:~ jsimpson$ curl -I http://vagrant/test.php
HTTP/1.1 200 OK
Server: nginx/1.4.6 (Ubuntu)
Date: Tue, 16 Sep 2014 22:09:25 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 2592
Connection: keep-alive
X-Powered-By: HHVM/3.2.0
Content-Encoding: none;
We have a content length header. However if we hit the same URL from Chrome, and get the headers from the Dev tools:
HTTP/1.1 200 OK
Server: nginx/1.4.6 (Ubuntu)
Date: Tue, 16 Sep 2014 22:14:41 GMT
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
X-Powered-By: HHVM/3.2.0
Content-Encoding: gzip
No Content-Length header. I've also packet sniffed this to verify that the header isn't sent. I can switch to PHP FPM and it sends the header.
I reproduced the issue by hitting the server with:
curl -H 'Accept-Encoding: gzip,deflate' --compressed -v http://foo/bar
HHVM enables compression by default. Disabling that gave me the header back.
Everything was awesome after adding this to /etc/hhvm/server.ini
hhvm.server.gzip_compression_level = 0
I stumbled upon this issue/feature. Not running HHVM though. Pure nginx + PHP-FPM.
The thing is, if your PHP app calculates and sets Content-Lenght header field, and your nginx is configured to gzip content, it will just ditch this information and replace it by Chunked transfer encoding and GZIP headers.
So do not set GZIP to a very small buffers, default is 20 bytes which does quite the opposite (end result is larger then before GZIP compression).
I set it like this:
gzip_min_length 1024;
I am using a .htaccess file to compress my .php , .css and .js files. What I want to do is to echo out in my footer is GZIP enabled or not.
For example if its not enabled by the server to echo out GZIP is not enabled or of it is to echo out GZIP is enabled.
I've looked around the net and couldn't find a php script doing that. I thought I could make it work with ini_get() but obviously unsuccessfully.
Can someone give me a tip?
Thanks :)
I have problems to understand your question. If you want to find out if the gzip encoding of your server and php configuration works, you need to check that with an additional program sending requests to the URLs in question and check if gzip is used. One such tool is curl on the commandline:
$ curl --compress --raw -i URL
Example:
$ curl --compress -I https://stackoverflow.com/questions/8029168/show-is-my-gzip-enabled-on-my-webpage
HTTP/1.1 200 OK
Cache-Control: public, max-age=18
Content-Length: 8683
Content-Type: text/html; charset=utf-8
*****************************
* Content-Encoding: deflate *
*****************************
Expires: Sun, 06 Nov 2011 18:21:05 GMT
Last-Modified: Sun, 06 Nov 2011 18:20:05 GMT
Vary: *
Date: Sun, 06 Nov 2011 18:20:46 GMT
See the line I highlighted:
Content-Encoding: deflate
it signals that something gzip is active. See RFC2616 - HTTP/1.1 14.11 Content-Encoding for the full meaning of this line.
More information is available in a related question/answer: PHP Output buffering, Content Encoding Error caused by ob_gzhandler?.
If that's not your issue maybe Gzip a website with inline PHP code is helpful.