Merge branch 'gh-pages' of github.com:codeguy/php-the-right-way into gh-pages

This commit is contained in:
Phil Sturgeon
2012-07-10 00:13:58 +01:00
39 changed files with 2396 additions and 290 deletions

View File

@@ -2,7 +2,7 @@
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][fig] (formerly known as the 'PHP Standards Group') has proposed and approved a series of style recommandations, known as [PSR-0][psr0], [PSR-1][psr1] and [PSR-2][psr2]. Don't let the funny names confuse you, these recommendations are merely a set of rules that some projects like Drupal, Zend, CakePHP, phpBB, AWS SDK, FuelPHP, Lithium, etc are starting to adopt. You can use them for your own projects, or continue to use your own personal style.
The [Framework Interop Group][fig] (formerly known as the 'PHP Standards Group') has proposed and approved a series of style recommendations, known as [PSR-0][psr0], [PSR-1][psr1] and [PSR-2][psr2]. Don't let the funny names confuse you, these recommendations are merely a set of rules that some projects like Drupal, Zend, CakePHP, phpBB, AWS SDK, FuelPHP, Lithium, etc are starting to adopt. You can use them for your own projects, or continue to use your own personal style.
Ideally you should write PHP code that adheres to one or more of these standards so that other developers can easily read and work with your code. They all add on to the recommendation before, so using PSR-1 requires PSR-0, but does not require PSR-2.

View File

@@ -1,47 +0,0 @@
# Command Line Interface
PHP was created primarily to write web applications, but it's also useful for scripting command line interface (CLI) programs, too. Command line PHP programs can help you automate common tasks like testing, deployment, and application administrativia.
CLI PHP programs are powerful because you can use your app's code directly without having to create and secure a web GUI for it. Just be sure not to put your CLI PHP scripts in your public web root!
Try running PHP from your command line:
> php -i
The `-i` option will print your PHP configuration just like the [`phpinfo`][0] function. There are a number of other useful [command line options][1], too.
Let's write a simple "Hello, $name" CLI program. To try it out, create a file named `hello.php`, as below.
<?php
if($argc != 2) {
die("Usage: php hello.php [name].\n");
}
$name = $argv[1];
echo "Hello, $name\n";
PHP sets up two special variables based on the arguments your script is run with. [`$argc`][2] is an integer variable containing the argument *count* and [`$argv`][3] is an array variable containing each argument's *value*. The first argument is always the name of your PHP script file, in this case `hello.php`.
To run our script, above, from the command line:
> php hello.php
Usage: php hello.php [name]
> php hello.php world
Hello, world
## Built-in, command line web server
Starting with PHP 5.4, you can develop locally on a PHP-enabled web server without the hassle of installing and configuring a full-fledged web server. To start the server, from your web root:
> php -S localhost:8000
* [Learn about running PHP from the command line][5]
* [Learn about the built-in, command line web server][4]
[Back to Top](#top){.top}
[0]: http://php.net/manual/en/function.phpinfo.php
[1]: http://www.php.net/manual/en/features.commandline.options.php
[2]: http://php.net/manual/en/reserved.variables.argc.php
[3]: http://php.net/manual/en/reserved.variables.argv.php
[4]: http://www.php.net/manual/en/features.commandline.webserver.php
[5]: http://php.net/manual/en/features.commandline.php

View File

@@ -15,13 +15,19 @@ This is terrible code. You are inserting a raw query parameter into a SQL query.
<?php
$pdo = new PDO('sqlite:users.db');
$stmt = $pdo->prepare('SELECT name FROM users WHERE id = :id');
$stmt->bindParam(':id', filter_input(FILTER_GET, 'id', FILTER_SANITIZE_NUMBER_INT), PDO::PARAM_INT);
$stmt->bindParam(':id', filter_input(INPUT_GET, 'id', FILTER_SANITIZE_NUMBER_INT), 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.
* [Learn about PDO][1]
* [Doctrine2 DBAL][2]
* [ZF2 Db][4]
* [ZF1 Db][3]
[Back to Top](#top){.top}
[1]: http://www.php.net/manual/en/book.pdo.php
[2]: http://www.doctrine-project.org/projects/dbal.html
[3]: http://framework.zend.com/manual/en/zend.db.html
[4]: http://packages.zendframework.com/docs/latest/manual/en/zend.db.html

View File

@@ -10,12 +10,32 @@ There are already a lot of PHP libraries that are compatible with Composer, read
### 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:
You can install Composer locally (in your current working directory; though this is no longer recommended) 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. <strong>Please Note:</strong> If you pipe downloaded code directly into an interpreter, please read the code online first to confirm it is safe.
### How to Install Composer (manually)
Manually installing composer is an advanced technique; however, there are various reasons why a developer might prefer this method vs. using the interactive installation routine. The interactive installation checks your PHP installation to ensure that:
- a sufficient version of PHP is being used
- `.phar` files can be executed correctly
- certain directory permissions are sufficient
- certain problematic extensions are not loaded
- certain `php.ini` settings are set
Since a manual installation performs none of these checks, you have to decide whether the trade-off is worth it for you. As such, below is how to obtain Composer manually:
> curl -s http://getcomposer.org/composer.phar -o $HOME/local/bin/composer ; chmod +x $HOME/local/bin/composer
`$HOME/local/bin` (or a directory of your choice) should be in your `$PATH` environment variable. This will result in a `composer` command being available.
When you come across documentation that states to run Composer as `php composer.phar install`, you can substitute that with:
> composer install
### 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][2] as a project dependency.

View File

@@ -0,0 +1,39 @@
# Getting Started
## Use the Current Stable Version (5.4)
If you are just getting started with PHP make sure to start with the current stable release of [PHP 5.4][php-release]. PHP has made great strides adding powerful [new features](#language_highlights) over the last few years. Don't let the minor version number difference between 5.2 and 5.4 fool you, it represents _major_ improvements.
## Built-in web server
You can start learning PHP without the hassle of installing and configuring a full-fledged web server (PHP 5.4 required). To start the server, run the following from your terminal in your project's web root:
> php -S localhost:8000
* [Learn about the built-in, command line web server][cli-server]
[php-release]: http://www.php.net/downloads.php
[cli-server]: http://www.php.net/manual/en/features.commandline.webserver.php
## Mac Setup
OS X comes prepackaged with PHP. As of Mountain Lion, it is _not_ the current stable version of PHP, though. You can get the PHP executable through a number of Mac [package managers][mac-package-managers] or [compile it yourself][mac-compile] (if compiling, be sure to have Xcode installed, or Apple's substitute ["Command Line Tools for Xcode" downloadable from Apple's Mac Developer Center][apple-developer]). For a complete Apache, MySQL, and PHP installation check out [MAMP2][mamp-downloads].
[mac-package-managers]: http://www.php.net/manual/en/install.macosx.packages.php
[mac-compile]: http://www.php.net/manual/en/install.macosx.compile.php
[xcode-gcc-substitution]: https://github.com/kennethreitz/osx-gcc-installer
[apple-developer]: https://developer.apple.com/downloads
[mamp-downloads]: http://www.mamp.info/en/downloads/index.html
## Windows Setup
You can install PHP on windows from an install executable found on the official [PHP Downloads][php-downloads] page. For a complete Apache, MySQL, and PHP installation check out [WAMP][wamp-installer].
* [Read more about the official PHP Windows Installer][windows-installer]
[php-downloads]: http://www.php.net/downloads.php
[windows-installer]: http://www.php.net/manual/en/install.windows.installer.msi.php
[wamp-installer]: http://www.wampserver.com/
[Back to Top](#top){.top}

View File

@@ -1,15 +0,0 @@
# 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.
* [Learn about `filter_var`][1]
* [Learn about `filter_input`][2]
[Back to Top](#top){.top}
[1]: http://php.net/manual/en/function.filter-var.php
[2]: http://www.php.net/manual/en/function.filter-input.php

View File

@@ -0,0 +1,89 @@
# Language Highlights
## Programming Paradigms
PHP is a flexible, dynamic language that supports a variety of programming techniques. It has evolved dramatically over the years, notably adding a solid object-oriented model in PHP 5.0 (2004), anonymous functions and namespaces in PHP 5.3 (2009), and traits in PHP 5.4 (2012).
### Object-oriented Programming
* [Read about Object-oriented PHP][oop]
* [Read about Traits][traits]
### Functional Programming
* [Read about Anonymous functions][anonymous-functions]
* [Read about dynamically invoking functions with `call_user_func_array`][call-user-func-array]
### Meta Programming
* [Read about Magic Methods][magic-methods]
* [Read about Reflection][reflection]
## Namespaces
As 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.
* [Read about Namespaces][namespaces]
## Standard PHP Library
The Standard PHP Library (SPL) is packaged with PHP and provides a collection of classes and interfaces. It is made up primarily of commonly needed datastructure classes (stack, queue, heap, and so on), and iterators which can traverse over these datastructures or your own classes which implement SPL interfaces.
* [Read about the SPL][spl]
## Command Line Interface
PHP was created primarily to write web applications, but it's also useful for scripting command line interface (CLI) programs, too. Command line PHP programs can help you automate common tasks like testing, deployment, and application administrativia.
CLI PHP programs are powerful because you can use your app's code directly without having to create and secure a web GUI for it. Just be sure not to put your CLI PHP scripts in your public web root!
Try running PHP from your command line:
> php -i
The `-i` option will print your PHP configuration just like the [`phpinfo`][phpinfo] function. There are a number of other useful [command line options][cli-options], too.
Let's write a simple "Hello, $name" CLI program. To try it out, create a file named `hello.php`, as below.
<?php
if($argc != 2) {
die("Usage: php hello.php [name].\n");
}
$name = $argv[1];
echo "Hello, $name\n";
PHP sets up two special variables based on the arguments your script is run with. [`$argc`][argc] is an integer variable containing the argument *count* and [`$argv`][argv] is an array variable containing each argument's *value*. The first argument is always the name of your PHP script file, in this case `hello.php`.
To run our script, above, from the command line:
> php hello.php
Usage: php hello.php [name]
> php hello.php world
Hello, world
* [Learn about running PHP from the command line][php-cli]
* [Learn about setting up Windows to run PHP from the command line][php-cli-windows]
[Back to Top](#top){.top}
[namespaces]: http://php.net/manual/en/language.namespaces.php
[oop]: http://www.php.net/manual/en/language.oop5.php
[spl]: http://php.net/manual/en/book.spl.php
[anonymous-functions]: http://www.php.net/manual/en/functions.anonymous.php
[magic-methods]: http://php.net/manual/en/language.oop5.magic.php
[reflection]: http://www.php.net/manual/en/intro.reflection.php
[traits]: http://www.php.net/traits
[call-user-func-array]: http://php.net/manual/en/function.call-user-func-array.php
[phpinfo]: http://php.net/manual/en/function.phpinfo.php
[cli-options]: http://www.php.net/manual/en/features.commandline.options.php
[argc]: http://php.net/manual/en/reserved.variables.argc.php
[argv]: http://php.net/manual/en/reserved.variables.argv.php
[php-cli]: http://php.net/manual/en/features.commandline.php
[php-cli-windows]: http://www.php.net/manual/en/install.windows.commandline.php

View File

@@ -1,10 +1,12 @@
# Popular Frameworks
# Libraries and Frameworks
## Web 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
### Full-Stack Frameworks
* [CakePHP](http://cakephp.org/)
* [CodeIgniter](http://codeigniter.com/)
@@ -17,11 +19,10 @@ _You do not need to use a framework for every project_. Sometimes, plain PHP is
* [Yii](http://www.yiiframework.com/)
* [Zend](http://framework.zend.com/)
## Micro Frameworks
### Micro Frameworks
* [Fat-Free](http://bcosca.github.com/fatfree/)
* [Limonade](http://limonade-php.github.com/)
* [Silex](http://silex.sensiolabs.org/)
* [Slim](http://www.slimframework.com/)
[Back to Top](#top){.top}

View File

@@ -1,13 +0,0 @@
# 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.
* [Read about Namespaces][1]
[Back to Top](#top){.top}
[1]: http://php.net/manual/en/language.namespaces.php

View File

@@ -1,17 +0,0 @@
# 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.
* [Read "How to Safely Store a Password" by Coda Hale][1]
* [Use Bcrypt with PHPAss][2] (odd name, I know)
[Back to Top](#top){.top}
[1]: http://codahale.com/how-to-safely-store-a-password/
[2]: http://www.openwall.com/phpass/

View File

@@ -1,6 +1,4 @@
# Links and Resources
Here are some miscellaneous resources that are worth a read.
# Resources
## From the Source
@@ -23,5 +21,6 @@ Here are some miscellaneous resources that are worth a read.
* [Red Hat OpenShift Platform](http://www.redhat.com/products/cloud-computing/openshift/)
* [dotCloud](http://docs.dotcloud.com/services/php/)
* [AWS Elastic Beanstalk](http://aws.amazon.com/elasticbeanstalk/)
* [cloudControl](https://www.cloudcontrol.com/)
[Back to Top](#top){.top}

43
_includes/security.md Normal file
View File

@@ -0,0 +1,43 @@
# Security
## 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][1] (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.
* [Read the OWASP Security Guide][2]
[1]: https://www.owasp.org/
[2]: https://www.owasp.org/index.php/Guide_Table_of_Contents
## 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.
* [Read "How to Safely Store a Password" by Coda Hale][3]
* [Use Bcrypt with PHPAss][4] (odd name, I know)
[3]: http://codahale.com/how-to-safely-store-a-password/
[4]: http://www.openwall.com/phpass/
## Input Filtering and Sanitizing
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.
* [Learn about `filter_var`][5]
* [Learn about `filter_input`][6]
[5]: http://php.net/manual/en/function.filter-var.php
[6]: http://www.php.net/manual/en/function.filter-input.php
[Back to Top](#top){.top}

View File

@@ -0,0 +1,29 @@
# Servers and Deployment
PHP applications can be deployed and run on production web servers in a number of ways.
## Platform as a Service (PaaS)
In recent years cloud platforms have become popular ways of deploying, hosting, and scaling PHP applications. These can be a great if you're learning PHP and don't have experience or interest in server admin work, too. You can find a list of [PHP PaaS "Platform as a Service" providers](#php_paas_providers) in our [resources section](#resources).
## Virtual or Dedicated Servers
If you are comfortable with systems administration, or are interested in learning it, virtual or dedicated servers give you complete control of your application's production environment.
### nginx and PHP-FPM
PHP, via PHP's built-in FastCGI Process Manager (FPM), pairs really nicely with [nginx](http://nginx.org), which is a lightweight, high-performance web server. It uses less memory than Apache and can better handle more concurrent requests. This is especially important on virtual servers that don't have much memory to spare. If you are working to put a new PHP app on its own server in production today, choose nginx and PHP-FPM.
* [Read more on nginx](http://nginx.org)
* [Read more on PHP-FPM](http://php.net/manual/en/install.fpm.php)
* [Read more on setting up nginx and PHP-FPM securely](https://nealpoole.com/blog/2011/04/setting-up-php-fastcgi-and-nginx-dont-trust-the-tutorials-check-your-configuration/)
### Apache and PHP
PHP and Apache have a long history together. Apache is wildly configurable and allows sites to control their configurations dynamically, via `.htaccess` files, on a per-directory basis. This has made it a popular choice for shared servers and an easy setup for PHP frameworks and open source apps like WordPress. Unfortunately, Apache uses more resources than nginx and cannot handle as many visitors at the same time. If you are on your own virtual/dedicated server and do not need the configurability of Apache, choose nginx and PHP-FPM.
## Shared Servers
PHP has shared servers to thank for its popularity. It is hard to find a host without PHP installed, but be sure it's the latest version. Shared servers allow you and other developers to deploy websites to a single machine. The upside to this is that it has become a cheap commodity. The downside is that you never know what kind of a ruckus your neighboring tenants are going to create; loading down the server or opening up security holes are the main concerns. If your project's budget can afford to avoid shared servers you should.
[Back to Top](#top){.top}

13
_includes/testing.md Normal file
View File

@@ -0,0 +1,13 @@
# Testing
Writing automated tests for your PHP code is considered a best practice and can lead to well-built
applications. Automated tests are a great tool for making sure your application
does not break when you are making changes or adding new functionality.
Some common tools are:
* [PHPUnit](http://phpunit.de)
* [Behat](http://behat.org)
* [Selenium](http://seleniumhq.org/)
[Back to Top](#top){.top}

View File

@@ -1,11 +0,0 @@
# 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][1] (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.
* [Read the OWASP Security Guide][2]
[Back to Top](#top){.top}
[1]: https://www.owasp.org/
[2]: https://www.owasp.org/index.php/Guide_Table_of_Contents

View File

@@ -1,4 +1,4 @@
# Introduction
# Welcome
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_ is an easy-to-read, quick reference for PHP best practices, accepted coding standards, and links to authoritative tutorials around the Web.