Best practicesDOs and DONT's of common CakePHP problems.
ConfigThe easiest approach for the beginning is a local config file that is not under version control per environment/server.
- app.php (CakePHP core configs)
- app_custom.php (project overwriting on top)
- app_local.php (env specific, contains sensitive keys/pwds, in gitignore!)
Configure::load('app', 'default', false); Configure::load('app_custom'); Configure::load('app_local');
The main idea here is to ease upgrading in minors as the app.php one is the one from cakephp/app repo always and it makes it easy to diff and know what new config keys are added with each minor. If you overwrite it directly, this will get very messy otherwise.
Check this applications's config folder on how it is done.
Note: You can also leave out the app_local file, and instead use
env() wrapper to read from environment variables.
People often use the env() approach on the server, and the local file on the development machine locally.
RoutingBest to use the DashedRoute class (see conventions) as default one:
This way your URLs are `my-prefix/my-plugin/controller-name/action-name` whereas your URL contains the CamelCase variants:
use Cake\Routing\Route\DashedRoute; Router::defaultRouteClass(DashedRoute::class);
The idea of CakePHP 3.x is to inflect internally as less as possible.
'prefix' => 'my-prefix // unmodified 'plugin' => 'MyPlugin, // camelCased 'controller' => 'ControllerName', // camelCased 'action' => 'actionName' // camelBacked
URLsUse array URLs wherever possible, this saves you a lot of trouble once you actually want to customize the routing:
You can then alter the URLs via Routing and all those URLs change cleanly. The speed issue can be neglected compared to the advantages of the flexibility. You can also use "named routes", of course (`['_name' => 'admin:account:password']`). This centralizes the arrays into the routes config.
// URL /my-controller/my-action echo $this->Html->link($title, ['controller' => 'MyController', 'action' => 'myAction']);
Don't sanitize the heck out your dataUse Sanitization wisely, and not blindly.
Not without reason the Sanitize class has been kicked out of the core files.
Sanitization is useful and necessary, when working with HTML content, that needs to be stripped of invalid/dangerous markup. But here it is best to use plugins specifically written for this job.
For most normal use cases, by using save(), SQL injections are already prevented. No need to modify the data upon save. Only use h() in the view to secure (stringish) output by escaping potentially dangerous chars:
LoggingBy default the log streams catch all, even scoped logs that should only go to those scoped listeners. As a result they are duplicated.
So I would change the scopes to false here for all default listeners:
// in your app.php config 'Log' => [ 'debug' => [ 'scopes' => false, ], 'error' => [ 'scopes' => false, ], ... ],
Another very useful addition is to log 404s separately from actual (internal) errors happening using Tools.ErrorHandler.
Use AJAX wiselyDon't over-ajaxify your views. It can easily create complications and become error-prone. Use it wisely where it makes sense.
Also always try to provide a non-JS fallback solution in case the JS breaks or cannot work properly in some browsers. It might also be a good idea for search engines to properly pick up your site content (e.g. when using pagination and AJAX).
So the smart approach is: First code the non-JS functionality. And then you can add JS-functionality for it on top. In case the JS breaks, the non-js part can take over without users being unable to proceed.
You should automate your deployment process, e.g. via basic deploy.sh file. Then you can just execute `./deploy.sh`.
Always use your `www-data` user for this and never root, otherwise you will have some serious permissions problems afterwards.
The following file is an example sh script for a very very basic single server update process:
#!/bin/bash bin/cake Setup.MaintenanceMode activate echo "### CODE ###"; git pull php composer.phar install --prefer-dist --no-dev --optimize-autoloader --no-interaction mkdir -p ./tmp mkdir -p ./logs mkdir -p ./webroot/js/cjs/ mkdir -p ./webroot/css/ccss/ echo "### DB MIGRATION ###"; bin/cake Migrations migrate -p Geo // and all other plugin migrations bin/cake Migrations migrate echo "### ASSETS ###"; bower install // or npm -i etc mkdir -p ./webroot/css/fonts cp -R ./webroot/assets/bootstrap/dist/fonts/* ./webroot/css/fonts/ bin/cake AssetCompress.AssetCompress build echo "### CLEANUP ###"; bin/cake clear cache echo "### CACHE WARMING ###; bin/cake orm_cache build echo "### DONE ###"; bin/cake Setup.MaintenanceMode deactivate
It should at least contain:
- composer install (from lock file!)
- DB Migration
- Asset update
- Cache invalidation
Wrapping it with maintenance mode can help to avoid side effects for users currently on the website.Note that the above script is after initial deployment. For a first checkout you will need to clone the repository and probably set up a few more things like your app_local.php.