Debugging HTTP requests to PHP via the CLIMattias Geniar, Tuesday, April 22, 2014 - last modified: Wednesday, April 22, 2015
You're a sysadmin. You love the CLI. You use PHP. Surely, you should be able to troubleshoot PHP applications that are normally run via an HTTP server through the CLI as well, right? Well good news; you can -- with a few caveats.
This is in follow-up of a blogpost I made in 2012 titled "Running php-cgi scripts via the CLI as a webserver would (by faking them)". If you can run your PHP applications via the CLI, you can use tools such as strace to debug the PHP app's behaviour.
TL;DR: you can fake pretty much any HTTP request by setting the correct environment variables before you call the PHP binary.
First, the caveats.
- Your PHP settings may be altered or overwritten in the webserver (Apache/PHP-FPM daemon), the PHP binary you run via CLI may not have a correct representation as the PHP(-FPM) binary used via that HTTP server -- so check your PHP settings;
- You won't be using the APC or OPcache as you're running PHP via the CLI, neither the opcode nor the key/value cache of APC/OPcache is used;
- Your $_SERVER environment variables will be different than via an HTTP webserver, keep that in mind if your application depends on it;
Now. On with it.
Basic web application
If you have a simple PHP application you will most likely be able to run it simply via the CLI.
$ cd /path/to/your/docroot $ php index.php
The output can (but is not necessarily the case) be the same as if it were called via the web.
Using environment variables to determine dev/staging/prod
Just like you can specify environment variables in Nginx or Apache, to allow your code to use different users/passwords/settings, it can be used via the CLI as well. If your application depends on an environment variable called
APPLICATION_ENV to distinguish environments, you can add it to your request.
$ cd /path/to/your/docroot $ APPLICATION_ENV=development \ php index.php
A framework which uses routes
If you're using a framework that has a routing controller, to map URI's directly to the index.php file, you can add environment variables to make the PHP app think you're requesting a specific URI.
$ cd /path/to/your/docroot $ REQUEST_URI=/your-test-page \ php index.php
Multi-domain PHP application
If you're running your PHP application as a multi-site app, meaning your content and code behaviour can differ depending on the hostname being used in the request, you can also pass those along as environment variables.
$ cd /path/to/your/docroot $ SERVER_NAME=www.yoursite.tld \ HTTP_HOST=www.yoursite.tld \ REQUEST_URI=/your-test-page \ php index.php
Sending POST requests at CLI
The HTTP method is just a environment variable -- so it's changeable.
$ cd /path/to/your/docroot $ REQUEST_METHOD=POST \ CONTENT_TYPE=application/www-form-urlencoded \ REQUEST_URI=/your-test-page php index.php
Running these PHP commands via the CLI allows you to troubleshoot applications more easily, as you can now reproduce specific HTTP requests on demand. The main benefit comes from the ability to attach a debugger (such as gdb or strace, sysdig) to that process.
You can see all low-level system calls as well as all network traffic (such as MySQL queries, memcached requests, MongoDB traffic, ...) as your application is sending and receiving it.