I'm no longer doing lettering professionally, to re-focus on web development. A newer version of this site is being built to reflect this.
This version is kept as an archive to ensure its content don't disappear as I update my site

Running Worpdress with PHP built in server

— An article about: - Built in server - PHP - Wordpress

Running Worpdress with PHP built in server

Having to set up Apache to serve each WordPress project on my machine is a bit of a pain.
Fortunately, PHP comes with a built-in server since its version 5.4. And that server is enough to get WordPress running.
You’ll still need a MySQL database, but that’ll reduce the logistics a bit.

Launching the build-in server

You start the built-in server with php -S. The command just needs the host and port to which you want to attach the server. For example:

php -S localhost:8000

Navigate with the command line into the folder containing the index.php of your WordPress project. Run the above command. And there you go, you have a server hosting your WordPress project at http://localhost:8000.

Rewriting URLs

It’ll work fine for index.php?p=N kind of URLs. But chances are you prefer pretty permalinks. On Apache, it relies on URL rewriting to route the requests to index.php. The php -S command can do just the same, except instead of relying on some configuration file, it’ll rely on PHP code. It accepts a file as a 3rd argument which will be the file handling the requests.

“Easy, let’s use index.php as that 3rd argument and we’re done!”. It’s not quite that simple. WordPress admin links to different PHP files, for example. So WordPress’ index.php can’t be the one handling all requests. We’ll need a new file to handle the URL rewriting. If the PHP file exist, run that. Otherwise, run the index.php. Let’s call it routing.php and put it right next to the index.php file.

// Extracted from the `wp-cli` project. https://wp-cli.org/

$path = '/'. ltrim( parse_url( urldecode( $_SERVER['REQUEST_URI'] ) )['path'], '/' );

if ( file_exists( $root.$path ) ) {

    // Enforces trailing slash, keeping links tidy in the admin
    if ( is_dir( $root.$path ) && substr( $path, -1 ) !== '/' ) {
        header( "Location: $path/" );

    // Runs PHP file if it exists
    if ( strpos( $path, '.php' ) !== false ) {
        chdir( dirname( $root.$path ) );
        require_once $root.$path;
    } else {
        return false;
} else {

    // Otherwise, run `index.php`
    chdir( $root );
    require_once 'index.php';

With this file, we get the equivalent of Apache’s RewriteRules . Nice permalinks will be routed to index.php when running:

php -S localhost:8000 routing.php

There’s still one last step to get the permalinks handled properly by WordPress. Letting it know that URLs are rewriten, otherwise it’ll insist on using index.php in the URL.

Telling WordPress URLs are rewriten

To decide wether to put an index.php inside its URLs, WordPress tries to detect if the server uses URL rewrites. Unfortunately, it cannot see our routing.php file handles that, so it acts like if there’s no rewriting for now. The got_url_rewrite function defines a filter that can be used to alter its returned value and force it to true. You can put it in the functions.php file of your theme, a plugin you activate when developing, or a must use plugin.

function enforce_got_url_rewrite() {
  return true;

add_filter('got_url_rewrite', 'enforce_got_url_rewrite');

No more need to setup a VHost on Apache for each project. Download your project, setup the DB, setup the wp-config file and php -S your way!