Debugging HTTP requests to PHP via the CLI

Mattias 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
  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.

Hi! My name is Mattias Geniar. I'm a Support Manager at Nucleus Hosting in Belgium, a general web geek, public speaker and podcaster. Currently working on DNS Spy. Follow me on Twitter as @mattiasgeniar.

I respect your privacy and you won't get spam. Ever.
Just a weekly newsletter about Linux and open source.

SysCast podcast

In the SysCast podcast I talk about Linux & open source projects, interview sysadmins or developers and discuss web-related technologies. A show by and for geeks!

cron.weekly newsletter

A weekly newsletter - delivered every Sunday - for Linux sysadmins and open source users. It helps keeps you informed about open source projects, Linux guides & tutorials and the latest news.

Share this post

Did you like this post? Will you help me share it on social media? Thanks!


Stéphan Wednesday, July 2, 2014 at 18:47

Still a golden post!
Just thought I’d weigh in here.

When using php instead of php-cgi, the application is sometimes able to detect this.


with php:

# SERVER_NAME='' HTTP_HOST='' REQUEST_URI='/2014/06/30/generic-title-page' php index.php

Page Caching using apc (Console mode)
Database Caching using apc

with php-cgi:

# REDIRECT_STATUS=200 REQUEST_METHOD=GET SERVER_NAME='' SCRIPT_FILENAME='/var/www/vhosts/site.tld/httpdocs/index.php' SCRIPT_NAME='/index.php' PATH_INFO='/' HTTP_HOST='' SERVER_PROTOCOL='HTTP/1.1' REQUEST_URI='/2014/06/30/generic-title-page' $(which php-cgi)


Page Caching using apc
Database Caching 27/90 queries in 0.078 seconds using apc

When using php-cgi, more info is given, and it more closely represents the actual call going from apache (or nginx) to php-cgi .


Stéphan Wednesday, July 2, 2014 at 19:10

If you’d like to run strace against sites (like WordPress):

strace -r -E REDIRECT_STATUS=200 -E REQUEST_METHOD=GET -E SERVER_NAME='' -E SCRIPT_FILENAME='/var/www/vhosts/site.tld/httpdocs/index.php' -E SCRIPT_NAME='/index.php' -E PATH_INFO='/index.php' -E HTTP_HOST='' -E SERVER_PROTOCOL='HTTP/1.1' -E REQUEST_URI='/2014/06/30/generic-title-page' $(which php-cgi)

This will output nice timestamps relative to each request.
You can increase output by using -s 10240
And enable logging by using -o /path/filename


Leave a Reply

Your email address will not be published. Required fields are marked *