Official documentation

Build with PHPAML.
From first project to production.

Complete guide to the autonomous AML environment and the PHPAML MVC mini-framework.

13 chapters30+ commandsEN / FR bilingual reference
01 — Getting started

Three paths, a first result in under five minutes

AML bundles PHP and Composer, creates the selected structure, and installs its dependencies automatically. Choose the classic application for MVC, AML View for a declarative reactive interface, or API for a focused JSON service.

01 · CLASSIC APPLICATION
phpaml — zsh
aml create my-project
cd my-project
aml serve
02 · AML VIEW
phpaml — zsh
aml create-view-app my-interface
cd my-interface
aml serve
03 · API
phpaml — zsh
aml create-api my-api
cd my-api
aml serve

Then open http://127.0.0.1:8910. Use aml doctor whenever you want to verify the environment. For the current folder, use aml create ..

Automatic installation and live reload

Creation commands produce a runnable project directly. The browser then reloads after each supported change.

02 — Concepts

Three readable structures, one configuration model

PHPAML separates responsibilities without adding empty folders. The classic project keeps app and its WebApp route map. AML View organizes backend and interface code under src. An API removes views and uses one route class per resource.

CLASSIC APPLICATION
app/
├── Controllers/
├── Models/
└── views/
routes/WebApp.php
public/index.php
AML VIEW
src/
├── controllers/
├── models/
├── middleware/
├── locales/
└── views/
    ├── pages/
    ├── components/
    ├── layouts/
    ├── states/
    └── stylesheets/
routes/WebApp.php
API
src/
├── controllers/
├── models/
├── repositories/
├── requests/
├── resources/
├── middleware/
└── routes/
    └── MovieRoute.php
public/index.php

Configuration without a configs folder

In new projects, phpaml.json stores shareable choices while .env stores secrets and machine-specific values. PHPAML builds runtime/config/app.php automatically. That generated file belongs to the runtime and must never be edited.

Request lifecycle

  1. public/index.php loads phpaml.json and .env.
  2. Middleware processes the request.
  3. The router discovers routes/ or src/routes/.
  4. The container injects controller dependencies.
  5. The action returns HTML, JSON, or a redirect.
02.1 — Migration

Move from aml_env to runtime

Older projects use aml_env, info.json, or app/View. The migration also renames app/View to app/UI. Always preview the conversion before applying it. AML creates a backup under runtime/storage/migrations before renaming files and updating known references.

phpaml — zsh
aml migrate:structure
aml migrate:structure --apply --yes
aml doctor --offline
aml test
Automatic backup

runtime/storage/migrations/structure-<date>/

03 — CLI

AML command reference

On first launch, AML asks for English or French. Output, diagnostics, and errors follow that choice. AML_LANG=en or AML_LANG=fr temporarily overrides it.

aml create .Create in the current folder
aml create my-projectCreate a classic app folder
aml create-view-app my-uiCreate an AML View application
aml create-api my-apiCreate a focused JSON API
aml installInstall engine and dependencies
aml serveStart from port 8910 with live reload
aml routesList registered routes
aml testRun tests/run.php
aml buildCreate a verified production archive
aml deploy productionBuild and deploy a configured profile
aml deploy:rollback productionRestore the previous release
aml make:controller UserGenerate a controller
aml make:model UserGenerate a model
aml make:middleware AuthGenerate middleware
aml make:migration create_users_tableGenerate a migration
aml env:initCreate .env from .env.example
aml env:listList variables and mask secrets
aml env:get APP_DEBUGRead one variable
aml env:set APP_DEBUG falseCreate or update one variable
aml db:showShow database configuration
aml doctorCheck AML and the project
aml cache:clearClear application cache
aml update --checkCheck for a new release
aml updateInstall the latest release
aml language frChange the CLI language

Useful options

phpaml — zsh
aml create project --version 0.1.0
aml create project --offline
aml install --production
aml install --refresh
aml doctor --offline
aml doctor --port 8080
aml doctor --production --json
aml update --version 1.3.0
04 — HTTP & MVC

Routes, requests, and controllers

phpaml — zsh
'GET /users/{id}' => [
    'handler' => [UserController::class, 'show'],
    'middleware' => [AuthMiddleware::class],
    'name' => 'users.show',
],
phpaml — zsh
public function show(Request $request): Response
{
    return $this->json(['id' => $request->attribute('id')]);
}

Request provides method(), path(), query(), input(), cookie(), header(), server(), and attribute(). JSON is decoded automatically. An unknown route returns 404; an unsupported method returns 405.

phpaml — zsh
return Response::html('<h1>Hello</h1>');
return Response::json(['ok' => true], 201);
return Response::redirect('/login');
return $this->view('users/show.php', ['user' => $user]);
05 — UI

Declarative views and assets

Classic applications may keep PHP templates and partials. An AML View application places pages, components, layouts, and states in src/views. Stylesheets are discovered automatically under src/views/stylesheets, while AML serves the JavaScript engine automatically.

phpaml — zsh
src/views/pages/home/page.php
src/views/components/Navigation.php
src/views/layouts/DashboardLayout.php
src/views/stylesheets/pages/home.css
assets/images/hero.webp
public/favicon.svg
06 — ENV

Configure .env from the command line

phpaml — zsh
aml env:init
aml env:set APP_DEBUG false
aml env:get APP_DEBUG
aml env:list

env:init copies .env.example; --force replaces an existing file. env:list masks passwords, secrets, keys, and tokens. Never commit .env to Git.

07 — Data

SQLite, MySQL, and migrations

SQLite is the default local database. AML creates runtime/storage/database.sqlite and records root/root by convention; SQLite does not actually use these credentials.

phpaml — zsh
aml db:configure sqlite
aml db:configure sqlite --path storage/app.sqlite
aml db:show

aml db:configure mysql --host 127.0.0.1 --port 3306 \
  --database phpaml --user root --password root

Transactional migrations

phpaml — zsh
aml make:migration create_users_table
aml migrate
aml migrate:rollback --steps 1

Migrations are recorded in aml_migrations. Migrations are ordered and locked. migrate:rollback runs down() in reverse order. QueryBuilder provides all() and insert(); use prepared PDO for everything else.

08 — Security

Validation, CSRF, and middleware

phpaml — zsh
$valid = $validator->validate($request->input(), [
  'email' => ['required', 'email'],
  'name' => ['required', 'string', 'min:2', 'max:100'],
]);

Rules: required, email, string, min:n, and max:n. Protect write routes with CsrfMiddleware and add <?= $this->csrfField() ?> to forms. For an API, use X-CSRF-Token.

SecurityHeadersMiddleware adds security headers; error details are hidden when APP_DEBUG=false.

09 — Shipping

Test and prepare for production

phpaml — zsh
aml test
aml install --production
aml doctor --production --json
aml routes

aml test uses AML's private PHP and runs tests/run.php. --production excludes development dependencies and optimizes the autoloader.

Important

aml serve is for development only. In production: a PHP-compatible HTTP server, HTTPS, APP_DEBUG=false, minimal permissions, backups, and appropriate authentication.

10 — Support

Solve common problems

The aml command is not found

Open a new terminal and check PATH: %LOCALAPPDATA%\Programs\PHPAML\bin on Windows, /usr/local/bin on macOS/Linux.

The AML environment is missing

From the project root, run aml install.

CSS or JavaScript does not load

Check /public/, filename casing, and run aml serve from the folder containing public/index.php.

Port 8000 is busy

aml doctor --port 8080
aml serve 127.0.0.1:8080

GitHub is unavailable

Use aml create project --offline or aml install --offline to reuse the cache.

11 — SEO

Control SEO from AML

AML centralizes metadata, generates search-engine files, and audits the published HTML.

phpaml — zsh
aml seo:init
aml seo:set base_url "https://example.com"
aml seo:set title "My website"
aml seo:set description "A clear description between 50 and 160 characters."
aml seo:disallow /admin
aml seo:allow /admin/public
aml seo:generate
aml seo:audit https://example.com --json

seo:generate creates public/sitemap.xml and public/robots.txt from static GET routes. Disallowed routes are removed from the sitemap. seo:audit checks the title, description, canonical URL, Open Graph, Twitter Cards, JSON-LD, language, viewport, H1, images, and HTTPS.

Indexing and security

A disallow rule guides crawlers but does not protect a page. Use authentication and middleware for private areas.

12 — Deploy

Build and deploy anywhere

aml build runs the tests, checks public/.htaccess, and creates a ZIP archive, manifest, and SHA-256 checksum in output/. Secrets and non-runtime material are excluded: .env, logs, SQLite databases, tests, temporary files, output/, and deliverables/.

phpaml — zsh
aml build
aml build --skip-tests

aml deploy:configure production --host example.com --user deploy \
  --path /home/deploy/site --port 22 --key ~/.ssh/id_ed25519
aml deploy:check production
aml deploy production
aml deploy:rollback production

Choose a strategy

releasesTimestamped releases, current symlink, and atomic rollback
public-htmlShared hosting with a separate public_html
sftp-onlyServer without SSH shell access
phpaml — zsh
aml deploy:configure hostinger --host example.com --user deploy \
  --path /home/user/domains/example.com \
  --strategy public-html \
  --public-path /home/user/domains/example.com/public_html \
  --key ~/.ssh/id_ed25519

The private profile is stored in ~/.phpaml/deploy.json with 600 permissions. AML stores no passwords: use an SSH key. The domain must point to public/ or, with public-html, to the configured public path. Visitors get /about, never /index.php/about.

Interrupted build or HTTP 503

AML removes incomplete archives when disk space or output/ access fails. Temporary GitHub errors are retried automatically up to three times.

Ready to build your first application?Install AML
02.2 — PACKAGIST

Install components independently

AML creation commands configure the correct components automatically. In an existing Composer project, declare collaborating prerelease packages together so the root project explicitly accepts their stability level.

AML VIEW + ENGINE
phpaml — zsh
composer require \
  phpaml/view:^0.1@beta \
  phpaml/engine:^0.1@beta
DATA + MONGODB
phpaml — zsh
composer require \
  phpaml/data:^0.2@alpha \
  phpaml/data-mongodb:^0.1@alpha

Engine, Data, and i18n can also be installed alone. The MongoDB adapter requires the PHP mongodb extension, while SQL Data requires PDO.

13 — AML View

Build a declarative, reactive interface

AML View is PHPAML’s optional frontend layer. PHP renders the first document, then Engine manages state, effects, collections, themes, and navigation locally.

phpaml — zsh
aml create-view-app my-interface
cd my-interface
aml serve
# http://127.0.0.1:8910
src/
├── controllers/
├── models/
├── middleware/
└── views/
    ├── pages/{route}/page.php
    ├── components/
    ├── layouts/
    ├── states/{Loading,Error,NotFound}.php
    ├── stylesheets/
    ├── themes/
    └── assets/

src/views, src/controllers, and src/models are required. CSS is collected from src/views/stylesheets. Imported assets stay in assets; favicon, robots.txt, and sitemap.xml stay in public/.

phpaml — zsh
#[State]
public int $count = 0;

public function body(): View
{
    return VStack(
        Heading('AML View')->class('page-title'),
        Text("Count: {$this->count}"),
        Button('Add one')->onClick(fn () => $this->count++),
    );
}

Compiled interactions run in the browser without calling PHP again. Effects provide dependencies, cleanup, debounce, throttle, latest cancellation, loading/success/error states, and cycle protection.

Navigation without reload

Engine replaces only the RouterView boundary, preserves the document, updates history, metadata, and focus, then uses Loading, Error, or NotFound for the response state.

14 — i18n

JSON internationalization

phpaml — zsh
aml install i18n
aml i18n:add es
aml i18n:list
aml i18n:check
aml i18n:missing fr
aml i18n:set-default en

Organize files freely under src/locales/{locale}. Paths become dotted keys, parameters use :name, one/other plural forms use the count, and LocaleResolver selects a supported locale from the route, cookie, or Accept-Language.