This article is part of my #100DaysOfCode and #100DaysOfBlogging challenge. R1D2


Whenever starting a new Zend Expressive project, I use the handy zendframework/zend-expressive-skeleton. It creates an almost empty Expressive application structure with your choice of

  • code structure,
  • DI container,
  • router,
  • template engine and
  • error handler.

It comes also with two exemplary handlers and conditions for various routers and template engines. I wondered, what a cleaned-up skeleton would look like and how many bits and pieces were actually there which could be removed.

Create a new project

To create a new skeleton application, I used composer create-project.

composer create-project zendframework/zend-expressive-skeleton clean-skeleton

composer.json

First stop is the composer.json. I update the following section to my needs.

  • name
  • description
  • homepage
  • license

Then I removed the following sections - you may want to update these to your needs, especially if you plan to publish your project/library on Packagist.

  • keywords
  • extra
  • support

Then I removed the post-create-project-cmd from the scripts section.

Further changes

If you’re using some other code style tool like PHP-CS-Fixer, you may want to update the require-dev and in the scripts section the cs-check and cs-fix commands accordingly. Since I sticked to the defaults, I left them as they were.

In the end, my composer.json looked like the following.

{
  "name": "arueckauer/clean-skeleton",
  "description": "A zend expressive skeleton purged of all unnecessary items",
  "type": "project",
  "homepage": "https://github.com/arueckauer/clean-skeleton",
  "license": "MIT",
  "config": {
    "sort-packages": true
  },
  "require": {
    "php": "^7.1",
    "zendframework/zend-component-installer": "^2.1.1",
    "zendframework/zend-config-aggregator": "^1.0",
    "zendframework/zend-diactoros": "^1.7.1 || ^2.0",
    "zendframework/zend-expressive": "^3.0.1",
    "zendframework/zend-expressive-helpers": "^5.0",
    "zendframework/zend-stdlib": "^3.1",
    "zendframework/zend-servicemanager": "^3.3",
    "zendframework/zend-expressive-fastroute": "^3.0"
  },
  "require-dev": {
    "phpunit/phpunit": "^7.0.1",
    "roave/security-advisories": "dev-master",
    "squizlabs/php_codesniffer": "^2.9.1",
    "zendframework/zend-expressive-tooling": "^1.0",
    "zfcampus/zf-development-mode": "^3.1",
    "filp/whoops": "^2.1.12"
  },
  "autoload": {
    "psr-4": {
      "App\\": "src/App/src/"
    }
  },
  "autoload-dev": {
    "psr-4": {
      "AppTest\\": "test/AppTest/"
    }
  },
  "scripts": {
    "development-disable": "zf-development-mode disable",
    "development-enable": "zf-development-mode enable",
    "development-status": "zf-development-mode status",
    "expressive": "expressive --ansi",
    "check": ["@cs-check", "@test"],
    "clear-config-cache": "php bin/clear-config-cache.php",
    "cs-check": "phpcs",
    "cs-fix": "phpcbf",
    "serve": "php -S 0.0.0.0:8080 -t public/",
    "test": "phpunit --colors=always",
    "test-coverage": "phpunit --colors=always --coverage-clover clover.xml"
  }
}

A composer update confirmed that no updates were required after making the adjustments.

License

I replaced the LICENSE file with the license of my choice.

Coding Standard

If desired, you can update name and rules in phpcs.xml.dist. For the purpose of this test, they remained unchanged in my case.

Readme

I emptied the readme file, leaving only an h1 with the project name. Usually I fill the readme up with information about the package, setup etc. as the project grows.

Shipped Handlers

Next, I removed the Handler classes with its containing folder, tests and configuration references.

Deleted directories:

  • src/App/src/Handler
  • test/AppTest/Handler

Also, I removed the defined routes in config/routes.php and the dependency definitions in src/App/src/ConfigProvider.php.

Configuration

In config/config.php I removed Swoole config. If you’re using Swoole, you can replace it by an explicit inclusion of the ConfigProvider.

Done

To be honest, my first impression of what can be purged of the skeleton was much more. But there is no clutter whatsoever, just some examples. This challenge has helped me better understand the setup of the skeleton package and showed me just how neat it is organized. I love it.

Other Skeleton resources

There are two other skeletons for PHP applications which I want to mention at this point. They both are a closer look worth it, if you’re starting new PHP projects on a fairly regular basis or want some reference from time to time.

  1. thephpleague/skeleton and
  2. php-pds/skeleton

The thephpleague/skeleton comes with templates for GitHub issues and pull-requests. And also, a prefill command which replaces variables like vendor and package names and urls throughout the cloned repo.