Nginx by examples: PHP setup

When setting up PHP with Nginx we are effectively still using Nginx as a reverse proxy in front of a FastCGI server as the fastcgi_pass directive is functionally equivalent to the proxy_pass one.

There are plenty of blog posts and examples online that show how to setup PHP behind nginx but most of them don’t really explain why the suggested setup simply works :)

Let’s start with a simple configuration:

server {

  root /var/www/;
  index index.php;


  access_log /var/www/;
  error_log /var/www/ error;

  location / {

    # we serve a file if it's there, 
    # otherwise we rewrite internally as a request to /index.php
    try_files $uri /index.php?$args;

  # regex matching: anything ending with .php
  location ~ \.php$ {

    # allows for requests to /test.php/article/0001 
    # to be handled by /test.php. At the same time 
    # it sets the $fastcgi_path_info env variable 
    # (that can be sent to php via the fastcgi interface)
    fastcgi_split_path_info ^(.+\.php)(/.+)$;

    # defaults calls to /uri/ to /uri/index.php (optional)
    fastcgi_index index.php;

    # sets the standard fastcgi parameters (from another file)
    include fastcgi_params;

    # if the rewritten $uri doesn't really exist 
    # let's return 404 to the user
    try_files $uri =404;

    # let's pass the request to the fastcgi downstream


 Request resolution process

The main point here is to understand how the

location / {
    try_files $uri /index.php?$args;

and the

location ~ \.php$ {

interact with each other

In the catch-all location / {} block the tryfiles directive matches any incoming request not ending with .php
If the request has:

 Apache Mod Rewrite


Now read this

Evolving CRUD (part 2)

Serving content at scale without complexity Command Querying Responsibility Segregation Martin Fowler and Udi Dahan have in the past described this approach at length. This is obviously not a new concept and what follows is only a... Continue →