Skip to content

PHP Project Skeleton: 5 Days You Never Invoice

PHP Project Skeleton: 5 Days You Never Invoice

Every project starts with the same week: a repository, a config loader, an error handler, a login page, a migration for users, three folders that nobody agrees on. A php project skeleton converts that week into one command, and the first ticket about business rules arrives four days earlier.

Code: Atomic-Framework-Application, GPL-3.0-or-later.

The skeleton is the official start for Atomic Framework, PHP 8.1 or newer, on the same GPL licence:

composer create-project globus-studio/atomic-framework-application myapp
cd myapp
cp .env.example .env
php atomic init/key
php -S localhost:8000 -t public

What a php project skeleton replaces in week one

Composer pulls the framework, the ORM and the autoloader. init/key generates the encryption keys, which is the step teams forget before the first session leaks a plaintext cookie. The application boots at localhost:8000 with a welcome page, and the repository has a .env.example that lists what the server needs.

That is a day of setup that does not need a senior developer, and it is the day that usually lands on the most expensive person in the room because nobody else knows the framework yet.

The folders say where things go

app/ holds controllers, models, middleware and the user provider. bootstrap/ holds constants, the config loader and error handling. config/ holds database, cache, mail, auth and queue. routes/ is split into web.php, api.php and cli.php, so a CLI command cannot accidentally become a URL. public/ is the web root with themes and uploads, database/ holds migrations and seeds, resources/ the templates, storage/ the logs, cache and sessions.

The listing looks boring and it is the point. A new developer opens the repository and knows where to add a file without asking, and code review stops arguing about structure in week two.

Auth arrives as a working example

Three controllers ship with the skeleton: a landing page, a dashboard behind authentication, and one for login, register and logout. The middleware Authenticate guards the dashboard, the User model carries uuid, email, password and role, the provider reads users from the database, and the users table has a migration.

That is a vertical slice, not a stub. The client can log in on the first day and see a protected page, which ends the meeting about whether the environment works.

Requirements are written down

PHP 8.1 with json, session, mbstring, fileinfo, pdo, pdo_mysql and curl. MySQL or MariaDB for data, Redis recommended for cache, queues, sessions and WebSockets, Composer for dependencies.

A hosting conversation needs that list on screen, and it is in the readme rather than in someone’s memory. Half of the delays in a first sprint come from a missing extension, and a missing extension costs a support ticket and a restart of the deploy.

What the skeleton does not decide

It does not choose a page builder, a CSS framework or an admin panel. It does not generate CRUD screens, and migrations stay hand-written files.

For a product with a strong opinion about its interface that is freedom. For a team that wanted a generator, it is work that stays in the estimate, and pretending otherwise would be a worse surprise in week three.

What it costs

An hour to install and read the folders, against a week that no longer appears in the invoice. The licence question is identical to the framework: GPL-3.0-or-later, which suits a client site and needs a legal look for a closed product.

Related: php framework for business apps for what the framework underneath carries, and PHP development for how an application scope is quoted.