Introduction
There's a lot of bad information on the Web (I'm looking at you, W3Schools) that leads
new PHP users astray, propagating bad practices and bad code. This must stop. PHP: The Right Way provides an
easy-to-read, quick reference for PHP best practices, accepted coding standards, and links to
authoritative tutorials around the Web.
It is important to understand there is no canonical way to use PHP. That's the beauty of it.
This website introduces new PHP developers to best practices, available options, and good information.
Disclaimer
This is a living document and will continue to be updated with more helpful information and examples
as they become available.
How to Contribute
Help make this website the best resource for new PHP programmers! Contribute on GitHub
Code Style Guide
The PHP community is large and diverse, composed of innumerable libraries, frameworks, and components.
It is common for PHP developers to choose several of these and combine them into a single project. It is
important that PHP code adhere (as close as possible) to a common code style to make it easy for developers
to mix and match various libraries for their projects.
The Framework Interop Group (a.k.a. PHP Standards Group) has proposed and approved
a code style standard — PSR-1
and PSR-2. Don't let the
funny names confuse you. These two standards are merely a "shared set of rules and expectations about how to
format PHP code." That's all.
You should write PHP code that adheres to one or both of these standards so that other developers
can easily read and work with your code.
↑ Back to Top
Namespaces
As I mentioned above, the PHP community has a lot of developers creating lots of code. This means
that one library's PHP code may use the same class
name as another library. When both
libraries are used in the same namespace, they collide and cause trouble.
Namespaces solve this problem. As described in the PHP reference manual, namespaces may
be compared to operating system directories that namespace files; two files with the same
name may co-exist in separate directories. Likewise, two PHP classes with the same name may co-exist
in separate PHP namespaces. It's as simple as that.
It is important for you to namespace your code so that it may be used by other developers without
fear of colliding with other libraries.
↑ Back to Top
Input Filtering
Never ever (ever) trust foreign input introduced to your PHP code. That leads to dark
and dangerous places. Instead, always filter foreign input before you use it in your code.
PHP provides the filter_var
and filter_input
functions to help
you do this. These two functions can sanitize text, verify formats (e.g. email addresses),
and escape characters.
For example, if you accept code from an HTML form, you'll want to use filter_input
before inserting the input into a database or inserting the input into an HTML response.
↑ Back to Top
Databases and PDO
Many times your PHP code will use a database to persist information. If you use a database,
use PDO
to talk with it. PDO is a database abstraction library — (usually) built-into
PHP — that provides a common interface to talk with many different databases.
More importantly, PDO
allows you to safely inject foreign input (e.g. IDs)
into your SQL queries without worrying about database SQL injection attacks. This is possible
using PDOStatements and bound parameters.
Let's assume a PHP script receives a numeric ID as a query parameter. This ID
should be used to fetch a user record from a database. This is the wrong
way to do this:
<?php
$pdo = new PDO('sqlite:users.db');
$pdo->query("SELECT * FROM users WHERE id = " . $_GET['id']); // <-- NO!
This is terrible code. You are inserting a raw query parameter into a SQL query. This will get
you hacked in a heartbeat. Instead, you should sanitize the ID input using PDO bound parameters.
<?php
$pdo = new PDO('sqlite:users.db');
$stmt = $pdo->prepare('SELECT * FROM users WHERE id = :id');
$stmt->bindParam(':id', (int)$_GET['id'], PDO::PARAM_INT);
$stmt->execute();
This is correct code. It uses a bound parameter on a PDO statement. This escapes the foreign
input ID before it is introduced to the database preventing potential SQL injection attacks.
↑ Back to Top
Password Hashing with Bcrypt
Eventually everyone builds a PHP application that relies on user login. Usernames and
(hashed) passwords are stored in a database and later used to authenticate users upon login.
It is important that you properly hash passwords that are stored in a database.
If passwords are not hashed, and your database is hacked or accessed by an unauthorized
third-party, all user accounts are now compromised.
Hash passwords with Bcrypt. It's super simple, and (for all
intents and purposes) Bcrypt makes it impossible for someone to reverse-engineer the
plain-text version of a password should the database be compromised.
There are several Bcrypt libraries for PHP that you may use.
↑ Back to Top
Dependency Management
There are a ton of PHP libraries, frameworks, and components to choose from. Your project
will likely use several of them — these are project dependencies. Until recently, PHP did
not have a good way to manage these project dependencies. Even if you managed them manually,
you still had to worry about autoloaders. No more.
Composer and Packagist
Composer is a brilliant dependency manager for PHP. List your project's
dependencies in a composer.json
file and, with a few simple commands,
Composer will automatically download your project's dependencies and setup autoloading
for you.
There are already a lot of PHP libraries that are compatible with Composer, ready
to be used in your project. These "packages" are listed on Packagist,
the official repository for Composer-compatible PHP libraries.
How to Install Composer
You can install Composer locally (in your current working directory) or globally (e.g. /usr/local/bin).
Let's assume you want to install Composer locally. From your project's root directory:
curl -s http://getcomposer.org/installer | php
This will download composer.phar
(a PHP binary archive). You can run this with php
to manage your project dependencies. Please Note: If you pipe downloaded code directly into an interpreter, please read the code online first to confirm it is safe.
How to Define and Install Dependencies
First, create a composer.json
file in the same directory as composer.phar
.
Here's an example that lists Twig as a project dependency.
{
"require": {
"twig/twig": ">=1.8.0,<2.0-dev"
}
}
Next, run this command from your project root directory.
php composer.phar install
This will download and install the project dependencies into a vendors/
directory.
Next, add this line to your application's primary PHP file; this will
tell PHP to use Composer's autoloader for your project dependencies.
<?php require 'vendor/autoload.php'; ?>
Now you can use your project dependencies, and they'll be autoloaded on demand.
PEAR
Another veteran package manager that many PHP developers enjoy is PEAR. It behaves much the same way, and is also worth researching for your projects.
↑ Back to Top
Web Application Security
There are bad people ready and willing to exploit your web application. It is important that you
take necessary precautions to harden your web application's security. Luckily, the fine folks at
The Open Web Application Security Project (OWASP) have compiled a comprehensive list of known security issues and methods to protect yourself against them. This is a must read
for the security-conscious developer.
↑ Back to Top
Popular Frameworks
Rather than re-invent the wheel, many PHP developers use frameworks
to build out web applications. Frameworks abstract away many of the low-level
concerns and provide helpful, easy-to-use interfaces to complete common tasks.
You do not need to use a framework for every project. Sometimes, plain
PHP is the right way to go. But if you do need a framework, here are a few
of the most popular ones (in alphabetical order):
Full-Stack Frameworks
Micro Frameworks
↑ Back to Top
Links and Resources
Here are some miscellaneous resources that are worth a read.
From the Source
People to Follow
PHP PaaS Providers
↑ Back to Top