CakePHP: Routing, Middleware, Bake & Plugins
Routing
<?php
// config/routes.php
use Cake\Routing\RouteBuilder;
return function (RouteBuilder $routes): void {
// RESTful conventional routes: index/view/add/edit/delete
$routes->resources('Articles');
// Explicit route
$routes->connect('/articles/:id', ['controller' => 'Articles', 'action' => 'view'])
->setPatterns(['id' => '\d+']);
};Middleware (PSR-15)
<?php
// src/Application.php
public function middleware(MiddlewareQueue $middlewareQueue): MiddlewareQueue
{
$middlewareQueue
->add(new ErrorHandlerMiddleware())
->add(new AssetMiddleware())
->add(new RoutingMiddleware($this))
->add(new CsrfProtectionMiddleware(['httponly' => true]))
->add(new AuthenticationMiddleware($this)); // WHO the user is
// Authorization (WHAT they can do) is a separate, composable
// plugin layer, not the same middleware
return $middlewareQueue;
}Bake: Scaffolding
# Inspects the existing 'articles' table and generates a working
# Table, Controller, and full CRUD view templates from it
bin/cake bake all Articles
# Just one piece at a time
bin/cake bake model Articles
bin/cake bake controller Articles
bin/cake bake template Articles
# Schema migrations -- version-controlled, reproducible schema changes
bin/cake bake migration CreateArticles title:string body:text author_id:integer
bin/cake migrations migrateFormHelper & Flash Messages
<!-- templates/Articles/add.php -- FormHelper binds fields to the
entity and its validation errors automatically -->
<?= $this->Form->create($article) ?>
<?= $this->Form->control('title') ?>
<?= $this->Form->control('body', ['type' => 'textarea']) ?>
<?= $this->Form->button('Save') ?>
<?= $this->Form->end() ?>
<!-- templates/layout/default.php -- displays and clears any flash
message set via $this->Flash->success()/error() before a redirect -->
<?= $this->Flash->render() ?>Cache
<?php
use Cake\Cache\Cache;
// Abstracts over the configured backend (file, APCu, Redis, Memcached)
$stats = Cache::remember('dashboard_stats', function () {
return $this->Articles->find()->select(['count' => 'COUNT(*)'])->first();
}, 'default');Keep your own version of these notes — editable, searchable, and organised by your stack.
Start free