A close-to plain PHP boilerplate featuring modern routing, templating, migrations, localization and assets powered by great single-purpose packages like Slim, Pug, Phinx, Babel, SCSS and gettext.
Simple Answer : 💦 💨 💦 💨 💦
Long Answer : PHP is still everywhere. Maintaining old PHP projects with files all other the place and routing like we're in the 90's doesn't make for a happy developer. And I strive for happiness.
Rewriting in a different language (RoR) is always more pain than expected. I wanted to gradually augment my PHP skills and the level of my PHP codebase. Without going through the hassle of a Big Framework™ .
So I found some good and simple packages + a structure that will increase my productivity and mental state without being very hard to manage.
This repo and resources can be useful for anyone looking to improving his game in PHP. I particularly loved this amazing guide that became my bible.
http://www.phptherightway.com/
It will become yours too.
- You need PHP > 5.6 (Also in the command line, if you want the local dev server)
- Configure the
config.php
file with your own db credentials and stuff - Install composer depencies:
$ php composer.phar install
- Install babel:
$ npm run install
- Run local PHP server:
$ php -S localhost:8000 -t public_html/ public_html/index.php
- Enjoy my magnificient home template.
We use the Slim framework v3 as base for the project. https://www.slimframework.com/docs/
It's a very simple router, but very well supported in the community. Equivalent to Flask in Python. See the project slim-skeleton for a complete Slim setup and their docs.
See index.php
for initial setup, and follow the white rabbit 🐇 ...
Ahem, no, it's better to follow require_once
and function calls ! 💩
App settings are in config.php
.
Packages Dependencies injection and Slim App Setup are in app.php
.
Routes are declared in router.php
.
Controllers are in app/classes/controllers
.
Yep. What a boring set of names and paths.
We're rolling our custom login hooks, with anonymous functions returned by a class inspired by: http://stackoverflow.com/questions/26108746/authentication-in-slim-is-a-combined-middleware-singleton-and-hook-approach-sm
I'll let you extend the auth class with your own custom admin callbacks depending on your needs :)
This package implements a middleware based login, with session variables, ACl, and tutti quanti but was too complicated for me to setup given my needs. But I recommend you take a look at it: https://github.com/jeremykendall/slim-auth/tree/slim-3.x
We use https://phinx.org/ . It's simple and powerful enough to get you out of your local vs prod db sync problems.
After composer install
to access phinx commands you need to do $ php vendor/bin/phinx [command]
For example:
$ php vendor/bin/phinx init
will give you yaml file with configuration
We've provided some sample migrations and relevant seeding so you can see:
- How you can do all those things.
- How it can be useful to handle an example problem common in old PHP apps: passing from a old pasword hash like
md5
to a securebcrypt
one. Seeapp/classes/lib/authentication.php
for more info.
Once db config setup, you can try:
-
First migration, users table setup.
$ php vendor/bin/phinx migrate -e development -t 20161128175922
-
Some users seed.
$ php vendor/bin/phinx seed:run -s UserSeeder
-
Hash their md5 passwords with new bcrypt
password_hash
and rest of the migrations.$ php vendor/bin/phinx migrate -e development
We use j4mie/idiorm
, for a very simple ORM. You can do more if you want to. See the docs here: https://idiorm.readthedocs.io/en/latest/
We're using autocomposer to autoload our controllers and models classes with PSR4. See composer.json "autoload".
Also, all classes in app/lib are loaded with psr-0 to allow more flexible naming.
Ref: http://phpenthusiast.com/blog/how-to-autoload-with-composer
We provide a sample setup of Monolog\Logger
I'm a big fan of pug, coming from Node and Javascript land.
Perfect: awesome people are creating a php version of pug right now :)
- Pug-php: https://github.com/pug-php/pug
- Pug-Assets: https://github.com/pug-php/pug-assets for minification etc...
- Static markdown filters: https://github.com/cebe/markdown
The available filters are :markdown :github-markdown :inline-github-markdown :markdown-extra
We use a php scss package creating its own server with cache management. It's https://github.com/leafo/scssphp
See style.php
to understand what this is about.
We route css requests to it using /css/*
route redirection in router.php
.
We use oscaro/gettext, but without the hard to install gettext extension. Ref: https://github.com/oscarotero/Gettext
We just use php arrays atm, see the Translation class
There is a bit of magic happening here:
In all template calls to trs($token)
we translate the token if it exists, or add the new token to the translation files.
You can add a markdown prefix to your tokens like md-*
to specify that some token should be parsed as markdown after being translated.
So when a client wants to modify a string, you just have to send him your new.php
file. He finds the string he wants to modify, send it back to you, you run the build scripts, commit, and it's over.
You need to have you system configured for Babel.
$ npm install
Babel will compile all files from views/es6
to public_html/js
to do so:
$ npm run build
We want to allow clients to customize the page texts without asking the dev to copy paste their stuff from excel spreadsheet, so we are going to use grunt to load current traductions from remote gettext editor (like https://poeditor.com/) and then do something like this https://github.com/Philoozushi/grunt-poeditor-pz
Functional programming functions for PhP to replace stuff I liked in underscore.js https://github.com/lstrojny/functional-php
cf http://stackoverflow.com/questions/7959673/directory-structure-for-mvc
public_html/ (for public files) (should be public, place only index.php in here)
public_html/images
public_html/js (for your js files, or custom generated ones)
lib/ (for my libs) (should be private)
lib/vendor/ (for 3rd party libs)
locales/
app/ (for the whole app) (should be private)
app/class (classes that make the app work such as mainApp, Controller, Model, View, etc...)
app/class/models (all the models)
app/class/views (all the views)
app/class/views/pug (Pug templates used by the views)
app/class/controllers (all controllers)
app/class/helpers (helper functions, not used atm)
app/class/lib (libs that you develop for the app)
app/config.php (config files)
app/router.php (router.php)
app/logs (log files)
app/cache (cached library files => pug and scss)
app/cron (scheduled jobs)
app/db/seeds+migrations (for database migration and seed scripts)
node_modules/ (for babel)
- Clarify example views
- Add support for remote localization file edit and syncing in build phase or through an api
- Set up assets minification
- Setup page headers lib
- Deployment documentation