Discover PHPAML
Understand the platform, choose the right project type, and create a first runnable application.
Official documentation
Practical guides and technical reference for creating, testing, and deploying applications with PHPAML.
Structured documentation
Read the chapters in order to learn PHPAML progressively, or open a part directly when you need a specific command, concept, or solution.
Understand the platform, choose the right project type, and create a first runnable application.
Learn the request lifecycle, MVC organization, configuration, persistence, and security.
Build declarative pages in PHP and understand what View and Engine each do.
Create APIs, persist typed data, or run pure PHP programs in the terminal.
Use the CLI, diagnose problems, test, optimize, and deploy with confidence.
AML bundles PHP and Composer, creates the selected structure, and installs its dependencies automatically. Choose Classic for MVC, View for a reactive interface, API for JSON, or Console to learn and run pure PHP.
aml create my-project
cd my-project
aml serveaml create-view my-interface
cd my-interface
aml serveaml create-api my-api
cd my-api
aml serveaml create-console my-program
cd my-program
aml runFor the three Web paths, then open http://127.0.0.1:8910. Use aml doctor to verify the environment.
Creation commands produce a runnable project directly. The browser then reloads after each supported change.
PHPAML separates responsibilities without adding empty folders. Classic and View applications use src. An API removes views and uses one route class per resource. A Console program keeps only the PHP required to run it.
src/ ├── controllers/ ├── models/ ├── middleware/ ├── routes/WebApp.php └── views/ public/index.php
src/
├── controllers/
├── models/
├── middleware/
├── locales/
└── views/
├── pages/
├── components/
├── layouts/
├── states/
└── stylesheets/
routes/WebApp.phpsrc/
├── controllers/
├── models/
├── repositories/
├── requests/
├── resources/
├── middleware/
└── routes/
└── MovieRoute.php
public/index.phpIn 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.
The Console path generates a pure, strict, object-oriented PHP program. It has no HTTP server, routes, controllers, or HTML. echo writes to the terminal, fgets() reads input, and the value returned by main() becomes the process exit code.
aml create-console hello
cd hello
aml run
aml run -- Andre
aml make:class Domain/User
aml testfinal class Program
{
/** @param list<string> $arguments */
public static function main(array $arguments): int
{
$name = $arguments[0] ?? 'PHP';
echo "Hello, {$name}!\n";
return 0;
}
}Engine is not a complete PHP interpreter in the browser. It receives initial state and frontend instructions produced by View, then updates only the affected nodes. Supported assignments, calculations, conditions, collections, API requests, and effects can therefore remain expressed in PHP by the author.
Button('Calculate')->onClick(function (): void {
$subtotal = $this->price * $this->quantity;
$this->total = $subtotal - $this->discount;
});In debug mode, frontend-closure compilation errors identify the file, line, and unsupported construct. In production, sensitive details remain hidden.
create-api prepares a structure dedicated to controllers, validated requests, resources, repositories, middleware, and class-based routes. It does not install AML View: the application responds with JSON and can remain independent of a frontend.
aml create-api movies-api
cd movies-api
aml serve
aml routes
aml testPHPAML Data is optional. make:model always creates a plain PHP class; make:entity creates a persistent entity after Data is installed. SQLite, MySQL, MariaDB, and PostgreSQL are covered by the real-database test matrix. MongoDB remains available through a separate alpha adapter.
aml install data --driver sqlite
aml make:entity User
aml make:migration create_users_table
aml make:seeder UserSeeder
aml data:migrate
aml data:doctor#[Table('users')]
final class User extends Entity
{
#[Key]
public int $id;
public string $name;
public string $email;
}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.
aml migrate:structure
aml migrate:structure --apply --yes
aml doctor --offline
aml testruntime/storage/migrations/structure-<date>/
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 folderaml create my-projectCreate a classic MVC applicationaml create-view my-uiCreate an AML View applicationaml create-api my-apiCreate a JSON APIaml create-console helloCreate a pure PHP console programaml runRun the console programaml installInstall runtime and dependenciesaml serveStart from port 8910 with live reloadaml routesList registered routesaml testRun project testsaml buildCreate a verified production archiveaml deploy production --dry-runPreview the exact remote changesaml deploy:status productionCompare local and production manifestsaml deploy productionDeploy only added and modified filesaml deploy:history productionShow the private local deployment historyaml deploy:rollback productionRestore the previous releaseaml make:controller UserGenerate a controlleraml make:class ServiceGenerate a plain PHP classaml make:model UserGenerate a plain modelaml make:entity UserGenerate a persistent Data entityaml make:middleware AuthGenerate middlewareaml make:migration create_users_tableGenerate a migrationaml env:initCreate .env from .env.exampleaml env:listList variables and mask secretsaml env:get APP_DEBUGRead one variableaml env:set APP_DEBUG falseCreate or update one variableaml db:showShow database configurationaml doctorCheck AML and the projectaml cache:clearClear application cacheaml update --checkCheck for a new releaseaml updateInstall the latest releaseaml language frChange the CLI languageaml 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'GET /users/{id}' => [
'handler' => [UserController::class, 'show'],
'middleware' => [AuthMiddleware::class],
'name' => 'users.show',
],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.
return Response::html('<h1>Hello</h1>');
return Response::json(['ok' => true], 201);
return Response::redirect('/login');
return $this->view('users/show.php', ['user' => $user]);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.
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.svgaml env:init
aml env:set APP_DEBUG false
aml env:get APP_DEBUG
aml env:listenv:init copies .env.example; --force replaces an existing file. env:list masks passwords, secrets, keys, and tokens. Never commit .env to Git.
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.
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 rootaml make:migration create_users_table
aml migrate
aml migrate:rollback --steps 1Migrations 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.
$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.
aml test
aml install --production
aml doctor --production --json
aml routesaml test uses AML's private PHP and runs tests/run.php. --production excludes development dependencies and optimizes the autoloader.
aml serve is for development only. In production: a PHP-compatible HTTP server, HTTPS, APP_DEBUG=false, minimal permissions, backups, and appropriate authentication.
Open a new terminal and check PATH: %LOCALAPPDATA%\Programs\PHPAML\bin on Windows, /usr/local/bin on macOS/Linux.
From the project root, run aml install.
Check /public/, filename casing, and run aml serve from the folder containing public/index.php.
aml doctor --port 8080aml serve 127.0.0.1:8080
Use aml create project --offline or aml install --offline to reuse the cache.
AML centralizes metadata, generates search-engine files, and audits the published HTML.
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 --jsonseo: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.
A disallow rule guides crawlers but does not protect a page. Use authentication and middleware for private areas.
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/.
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 --dry-run
aml deploy:status production
aml deploy production
aml deploy:history production
aml deploy:rollback production
aml deploy:prune production --keep 5After the first upload, AML compares SHA-256 fingerprints and transfers only added or modified files. It removes deleted files and reports transferred size, savings, and progress through activation. --dry-run and deploy:status remain strictly read-only.
[ 25%] Comparison completed
+ public/version.txt
~ src/controllers/HomeController.php
- public/obsolete.txt
Transfer: 42.3 KB of 8.40 MB — 99.5% saved
[100%] Deployment completedreleasesTimestamped releases, current symlink, and atomic rollbackpublic-htmlShared hosting with a separate public_htmlsftp-onlyServer without SSH shell accessaml 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_ed25519The private profile is stored in ~/.phpaml/deploy.json and history in ~/.phpaml/deploy-history.json, both with 600 permissions. History retains up to 100 results without storing the host, path, user, or secrets.
AML verifies checksums, rejects unsafe archive paths, writes history atomically, and stops previews when the remote manifest cannot be reached.
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.
composer require \
phpaml/view:^0.1@beta \
phpaml/engine:^0.1@betacomposer require \
phpaml/data:^0.2@alpha \
phpaml/data-mongodb:^0.1@alphaEngine, Data, and i18n can also be installed alone. The MongoDB adapter requires the PHP mongodb extension, while SQL Data requires PDO.
AML View is PHPAML’s optional frontend layer. PHP renders the first document, then Engine manages state, effects, collections, themes, and navigation locally.
aml create-view my-interface
cd my-interface
aml serve
# http://127.0.0.1:8910src/
├── 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/.
use AML\View\{Page, State, View};
use function AML\View\{Button, Text, VStack, import};
import('pages/home.css');
final class HomePage extends Page
{
#[State]
private int $count = 0;
public function body(): View
{
return VStack(
Text('Count: {count}'),
Button('Add one')->onClick(fn () => $this->count++),
);
}
}#[State] properties are read and changed like ordinary PHP. View compiles supported frontend closures; Engine then runs the interaction in the browser without a server request for every click. Effects provide dependencies, debounce, throttle, latest cancellation, and loading/success/error states.
Engine replaces only the RouterView boundary, preserves the document, updates history, metadata, and focus, then uses Loading, Error, or NotFound for the response state.
aml install i18n
aml i18n:add es
aml i18n:list
aml i18n:check
aml i18n:missing fr
aml i18n:set-default enOrganize 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.