Search by

A small PHP 8.2 modular application foundation for shared hosting.

Package info

github.com/stougeiro/app

Type:project

pkg:composer/stougeiro/app

Fund package maintenance!

Buymeacoffee

Statistics

Installs: 3

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v0.4.0 2026-11-09 13:26 UTC

This package is auto-updated.

Last update: 2026-11-10 02:15:43 UTC


README

PHP PHPStan-Level Pest-php License

App

A small PHP 8.2 application foundation for shared hosting.

The application runs on Apache with PHP-FPM or mod_php and follows the shared-hosting layout: the application lives outside the public directory, while public contains only the front controller, .htaccess and public assets.

It is built on stougeiro/base, stougeiro/base-contract, stougeiro/router, stougeiro/http, stougeiro/view, stougeiro/cache, stougeiro/session, stougeiro/event and stougeiro/pdo-database.

The goal is an explicit, inspectable application with no hidden module discovery, no build step required at runtime, and behavior that is predictable on ordinary shared servers.

Reference

  • Architecture: boundaries, dependency direction and where each kind of code belongs.
  • Code tool: deployment configuration, commands and operations.
  • Schema tool: structural database state versioning.
  • AGENTS: operational rules for agents and contributors.

Features

  • Shared-hosting layout: application in application/, web root in public/.
  • Explicit wiring: providers and modules are registered in application/config/app.php.
  • Module example: HelloWorld controller, view and middlewares.
  • Error handling: separate development and production error pages.
  • Log separation: application errors, security events and PHP errors are written to different files.
  • Daily logs: application logs use YYYYMMDD file suffixes.
  • Services: cache, view, session, events, routing, database and logging are registered explicitly.
  • Security primitives: optional CSRF, rate limit and security headers middleware under application/core/Security.
  • Docker development: PHP 8.2 + Apache with the vendor directory kept inside the image.
  • Code tool: repeatable SSH deploys with per-target layout, overrides, maintenance mode, automatic backups and rollback.
  • Schema tool: structural database state versioning for SQLite, with immutable releases and SQL artifacts.
  • Quality tooling: PHPStan Level 9 and a Pest suite.

Requirements

  • PHP 8.2 or newer.
  • ext-json.
  • ext-pdo_sqlite for the default database configuration.
  • Apache with mod_rewrite for the front controller.
  • A writable application/storage directory.

Installation

git clone https://github.com/stougeiro/app.git
cd app

composer install
cp application/env-example.json application/env.json

For production dependencies, generate the vendor externally:

composer install --no-dev --optimize-autoloader

Layout

.
├── application/
│   ├── bootstrap/    runtime bootstrap
│   ├── config/       application configuration
│   ├── core/         app-level foundations
│   ├── database/     database-facing code
│   ├── module/       application modules
│   ├── provider/     service providers
│   └── storage/      cache, logs, sessions, uploads and temporary files
├── docs/             architecture, Code and Schema reference
├── tests/            Pest tests
├── tools/
│   ├── contract/     shared tool contracts
│   ├── manager/      CLI runtime, registry and Dockerfile
│   ├── code/         Code tool source and example
│   ├── schema/       Schema tool source and example
│   └── support/      shared tool support
├── .sourcerer/       local tool control, configs and secrets (not versioned)
├── schema/           versioned Schema state (database structure)
├── public/           document root
├── vendor/           Composer dependencies
├── sourcerer         unified tool entrypoint
├── composer.json
└── composer.lock

The application must never be exposed through the web server. The document root is public.

Configuration

Environment:

{
    "environment": "development"
}

Use production on a deployed server.

Providers and modules are declared explicitly in application/config/app.php:

return [
    'providers' => [
        // ...
    ],

    'modules' => [
        // ...
    ],
];

The default database configuration uses SQLite in application/storage.

Logging

Logs are written under application/storage/log. Files are separated by purpose and date:

error-YYYYMMDD.log
security-YYYYMMDD.log
php-error-YYYYMMDD.log
  • error-*: application 5xx errors;
  • security-*: request 4xx events such as 404 and 405;
  • php-error-*: PHP-level errors and the final fallback.

The php-error daily path is configured on a best-effort basis. If the hosting environment blocks ini_set, the application keeps running and the host/PHP configuration remains in use. See application/core/Log/PhpErrorLog.php.

Log retention is an operational concern and is not implemented by the application.

Docker development

Docker is a development convenience, not a production requirement.

# from the repository root
composer install
docker compose up -d

Open http://localhost/.

The development container uses PHP 8.2 + Apache, serves public as the document root, keeps vendor/ inside the image and bind-mounts application/ for real-time code and log inspection. Apache access and error logs are also written under application/storage/log.

Tool setup

Configure the shared operator and install the local control layout:

./sourcerer operator --name="Developer" --email="developer@example.com"
./sourcerer install

This creates .sourcerer/operator.json, .sourcerer/code/ and .sourcerer/schema/. All tool commands require the operator.

Code tool

The repository includes an optional Code tool for repeatable SSH deployments. It runs through the unified ./sourcerer entrypoint, requires Docker locally and keeps the application runtime independent from deployment concerns.

./sourcerer code check --target=staging
./sourcerer code push --target=staging
./sourcerer code promote --from=staging
./sourcerer code releases
./sourcerer code rollback --target=staging --list

Targets are declared in .sourcerer/code/config.json, with separate root and webroot paths, per-target overrides, maintenance mode, remote backups and rollback. Remote .deploy/ remains the deployment state on the server.

See docs/CODE.md for configuration, commands and operational details.

Schema tool

The Schema tool versions database structure without creating control tables in the database.

./sourcerer schema init
./sourcerer schema status
./sourcerer schema status --target=local

Configuration lives in .sourcerer/schema/config.json; local scratch data lives in .sourcerer/schema/local. Versioned structural state lives in schema/.

It captures Genesis, maintains immutable releases, and will generate release.sql and migration.sql artifacts. Triggers, procedures and functions are deliberately unsupported.

See docs/SCHEMA.md for configuration and the complete model.

Shared hosting

The production deployment is a normal PHP application. Docker is not required. The manual upload flow below remains valid when the Code tool is not used.

application/   -> application directory outside the web root
public/        -> contents go to the document root (often public_html)
vendor/        -> Composer dependencies outside the web root

Steps:

  1. install dependencies externally with --no-dev;
  2. upload application/, public/ and vendor/ to the server;
  3. create application/env.json;
  4. make application/storage writable by the application user;
  5. point the document root to the uploaded public contents (often public_html).

On shared hosting, Apache access/error logs and HTTP-level rate limiting usually belong to the provider. Application logs remain under application/storage/log.

Development

From the repository root:

composer validate --strict
composer stan
composer pest
composer cover:app
composer cover:code
composer cover:schema

Run the suite as a non-root user. The permission tests exercise real filesystem behavior and must not be skipped.

The test suite covers the application bootstrap, module rendering, error pages, log classification, daily PHP error log configuration, security primitives, maintenance/fallback entrypoint behavior, the Code tool and the Schema tool.

Tool coverage is measured separately so the application coverage scope stays unchanged.

Why?

Shared hosting is heterogeneous and constrained. The application is designed around those limits:

  • no long-running workers or persistent application state;
  • the web root is a fixed public directory;
  • dependencies are resolved before deployment;
  • modules and providers are explicit and easy to inspect;
  • error handling and logs remain useful without requiring platform-specific infrastructure.

Contracts live in stougeiro/base-contract; the FPM runtime lives in stougeiro/base; this repository shows how the application wires both together.

Contributions

Contributions are welcome. Feel free to open issues or submit pull requests.