From f2eb42f35a3713212c30b00da3c670d7a2916077 Mon Sep 17 00:00:00 2001 From: Zeev Suraski Date: Sun, 22 Jul 2012 10:48:10 +0300 Subject: [PATCH 001/843] Add Zend Server CE to list of All-in-ones and Zend Server Developer Cloud to list of PaaS --- _posts/01-05-01-Windows-Setup.md | 5 +++-- _posts/11-01-01-Resources.md | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/_posts/01-05-01-Windows-Setup.md b/_posts/01-05-01-Windows-Setup.md index 9265acfb2..237e86c60 100644 --- a/_posts/01-05-01-Windows-Setup.md +++ b/_posts/01-05-01-Windows-Setup.md @@ -9,7 +9,7 @@ installer. The installer is no longer supported and stops at PHP 5.3.0. For learning and local development you can use the built in webserver with PHP 5.4 so you don't need to worry about configuring it. If you would like an "all-in-one" which includes a full-blown webserver and MySQL too then tools such as the [Web Platform Installer][wpi], -[XAMPP][xampp] and [WAMP][wamp] will help get a Windows development environment up and running fast. That said, these tools will be +[Zend Server CE][zsce], [XAMPP][xampp] and [WAMP][wamp] will help get a Windows development environment up and running fast. That said, these tools will be a little different from production so be careful of environment differences if you are working on Windows and deploying to Linux. If you need to run your production system on Windows then IIS7 will give you the most stable and best performance. You can use @@ -24,9 +24,10 @@ sounds tricky, but using [Vagrant][vagrant] you can set up simple wrappers, then [php-downloads]: http://windows.php.net [phpmanager]: http://phpmanager.codeplex.com/ [wpi]: http://www.microsoft.com/web/downloads/platform.aspx +[zsce]: http://www.zend.com/en/products/server-ce/ [xampp]: http://www.apachefriends.org/en/xampp.html [wamp]: http://www.wampserver.com/ [php-iis]: http://php.iis.net/ [vagrant]: http://vagrantup.com/ [puppet]: http://www.puppetlabs.com/ -[chef]: http://www.opscode.com/ \ No newline at end of file +[chef]: http://www.opscode.com/ diff --git a/_posts/11-01-01-Resources.md b/_posts/11-01-01-Resources.md index 957c84d9e..a53ea6216 100644 --- a/_posts/11-01-01-Resources.md +++ b/_posts/11-01-01-Resources.md @@ -29,3 +29,4 @@ * [AWS Elastic Beanstalk](http://aws.amazon.com/elasticbeanstalk/) * [cloudControl](https://www.cloudcontrol.com/) * [Windows Azure](http://www.windowsazure.com/) +* [Zend Developer Cloud](http://my.phpcloud.com/) From 60931927c7df393189b7634f4017d6b355e7dec8 Mon Sep 17 00:00:00 2001 From: Zeev Suraski Date: Mon, 23 Jul 2012 16:31:42 +0300 Subject: [PATCH 002/843] Change URL per request --- _posts/11-01-01-Resources.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/11-01-01-Resources.md b/_posts/11-01-01-Resources.md index a53ea6216..94810412e 100644 --- a/_posts/11-01-01-Resources.md +++ b/_posts/11-01-01-Resources.md @@ -29,4 +29,4 @@ * [AWS Elastic Beanstalk](http://aws.amazon.com/elasticbeanstalk/) * [cloudControl](https://www.cloudcontrol.com/) * [Windows Azure](http://www.windowsazure.com/) -* [Zend Developer Cloud](http://my.phpcloud.com/) +* [Zend Developer Cloud](http://www.phpcloud.com/develop) From 6636bebf3a8a5d6d801212b81cdff9106cc660f1 Mon Sep 17 00:00:00 2001 From: = Date: Mon, 23 Jul 2012 13:14:07 -0400 Subject: [PATCH 003/843] Add note about pending translations --- _includes/welcome.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/_includes/welcome.md b/_includes/welcome.md index 3ea1a43d0..371c43eef 100644 --- a/_includes/welcome.md +++ b/_includes/welcome.md @@ -10,6 +10,9 @@ _PHP: The Right Way_ is (or soon will be) translated into many different languag * [English](http://www.phptherightway.com) * [Chinese](http://wulijun.github.com/php-the-right-way) +* Japanese (Coming Soon) +* Russian (Coming Soon) +* Spanish (Coming Soon) ## Disclaimer From c8916491b5d5bc65550b2c18f37c6be669d31f97 Mon Sep 17 00:00:00 2001 From: Phil Sturgeon Date: Tue, 24 Jul 2012 17:16:40 +0200 Subject: [PATCH 004/843] Made the register_global text more explicit, and removed PHP 4.2.x references. Don't use PHP 4.2.x. --- _posts/07-06-01-Register-Globals.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/_posts/07-06-01-Register-Globals.md b/_posts/07-06-01-Register-Globals.md index 55b6727e0..6be52708c 100644 --- a/_posts/07-06-01-Register-Globals.md +++ b/_posts/07-06-01-Register-Globals.md @@ -4,15 +4,14 @@ isChild: true ## Register Globals -NOTE: As of the introduction of PHP 5.4, the `register_globals` setting has been removed and can no -longer be used. +NOTE: As of PHP 5.4.0 the `register_globals` setting has been removed and can no +longer be used. This is only included as a warning for anyone in the process of upgrading a legacy application. When enabled, the `register_globals` configuration setting that makes several types of variables (including ones from -`$_POST`, `$_GET` and `$_REQUEST`) globals, available in the global scope of your application. This can easily lead to +`$_POST`, `$_GET` and `$_REQUEST`) available in the global scope of your application. This can easily lead to security issues as your application cannot effectively tell where the data is coming from. -If you are using a version of PHP that's prior to 4.2.0, please be aware that you may still be at risk of this setting -causing problems. As of PHP 4.2.0, the `register_globals` setting has been defaulted to "off". To ensure the security -of your application, ensure that this setting is always set to "off" if available. +For example: `$_GET['foo']` would be available via `$foo`, which can override variables that have not been declared. +If you are using PHP < 5.4.0 __make sure__ that `register_globals` is __off__. * [Register_globals in the PHP manual](http://www.php.net/manual/en/security.globals.php) \ No newline at end of file From c981ee10d0460f65f8e92fe65d567ec735bf2c08 Mon Sep 17 00:00:00 2001 From: = Date: Wed, 25 Jul 2012 08:26:52 -0400 Subject: [PATCH 005/843] Add note about Portuguese translation to welcome --- _includes/welcome.md | 1 + 1 file changed, 1 insertion(+) diff --git a/_includes/welcome.md b/_includes/welcome.md index 371c43eef..c33b8e779 100644 --- a/_includes/welcome.md +++ b/_includes/welcome.md @@ -11,6 +11,7 @@ _PHP: The Right Way_ is (or soon will be) translated into many different languag * [English](http://www.phptherightway.com) * [Chinese](http://wulijun.github.com/php-the-right-way) * Japanese (Coming Soon) +* Portuguese (Coming Soon) * Russian (Coming Soon) * Spanish (Coming Soon) From 2d01726b32a23eda22408ec565feaf5e6dfbe035 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josef=20=C4=8Cech?= Date: Thu, 26 Jul 2012 11:43:08 +0300 Subject: [PATCH 006/843] Fix Zend Framework 2 Db link --- _posts/06-01-01-Databases.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/06-01-01-Databases.md b/_posts/06-01-01-Databases.md index d29597028..15f3df473 100644 --- a/_posts/06-01-01-Databases.md +++ b/_posts/06-01-01-Databases.md @@ -68,7 +68,7 @@ Some abstraction layers have been built using the PSR-0 namespace standard so ca [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 +[4]: http://packages.zendframework.com/docs/latest/manual/en/index.html#zend-db [mysql]: http://uk.php.net/mysql [mysqli]: http://uk.php.net/mysqli From 5cea23136d3d694ab8be1941cc4f76c07cdd7b19 Mon Sep 17 00:00:00 2001 From: iflista Date: Thu, 26 Jul 2012 13:13:07 +0300 Subject: [PATCH 007/843] Added new coming soon language (Ukrainian) --- _includes/welcome.md | 1 + 1 file changed, 1 insertion(+) diff --git a/_includes/welcome.md b/_includes/welcome.md index c33b8e779..9d5619a8d 100644 --- a/_includes/welcome.md +++ b/_includes/welcome.md @@ -14,6 +14,7 @@ _PHP: The Right Way_ is (or soon will be) translated into many different languag * Portuguese (Coming Soon) * Russian (Coming Soon) * Spanish (Coming Soon) +* Ukrainian (Coming Soon) ## Disclaimer From c48437c2650ed7a41bb4a6ac86ab99674653b199 Mon Sep 17 00:00:00 2001 From: iflista Date: Thu, 26 Jul 2012 13:53:21 +0300 Subject: [PATCH 008/843] Added Ukrainian language --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 4a44ccc16..e003a0662 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,7 @@ developers know where to find good information! * [English](http://www.phptherightway.com) * [Chinese](http://wulijun.github.com/php-the-right-way) +* [Ukrainian](http://iflista.github.com/php-the-right-way) ### Translations From 66f0f13f7e16b0f0222815e340bf9251df50847c Mon Sep 17 00:00:00 2001 From: = Date: Thu, 26 Jul 2012 17:02:23 -0400 Subject: [PATCH 009/843] Update translation links --- _includes/welcome.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_includes/welcome.md b/_includes/welcome.md index 9d5619a8d..89a76d916 100644 --- a/_includes/welcome.md +++ b/_includes/welcome.md @@ -10,10 +10,10 @@ _PHP: The Right Way_ is (or soon will be) translated into many different languag * [English](http://www.phptherightway.com) * [Chinese](http://wulijun.github.com/php-the-right-way) -* Japanese (Coming Soon) +* [Japanese](http://ja.phptherightway.com) * Portuguese (Coming Soon) * Russian (Coming Soon) -* Spanish (Coming Soon) +* [Spanish](http://es.phptherightway.com) * Ukrainian (Coming Soon) ## Disclaimer From 003071c6b7c0861b921bdf410c07516bc057591a Mon Sep 17 00:00:00 2001 From: Sydney Arikan Date: Fri, 27 Jul 2012 14:05:24 +0300 Subject: [PATCH 010/843] changed the grammar used to define Factory pattern --- pages/Design-Patterns.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/Design-Patterns.md b/pages/Design-Patterns.md index 81df23e87..53b0f923b 100644 --- a/pages/Design-Patterns.md +++ b/pages/Design-Patterns.md @@ -14,7 +14,7 @@ your code easier to manage and easier for others to understand. ## Factory -One of the most commonly used design patterns is the factory pattern. This is a pattern is simply a class that creates +One of the most commonly used design patterns is the factory pattern. In this pattern, a class simply creates the object you want to use. Consider the following example of the factory pattern: {% highlight php %} From fee352d7741ff8af99fe51ec94dfba485a1276fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rados=C5=82aw=20Benkel?= Date: Sat, 28 Jul 2012 22:30:41 +0200 Subject: [PATCH 011/843] Fixed Maruku's style warning in "Register Globals" chapter --- _posts/07-06-01-Register-Globals.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/07-06-01-Register-Globals.md b/_posts/07-06-01-Register-Globals.md index 6be52708c..19bdc8c5e 100644 --- a/_posts/07-06-01-Register-Globals.md +++ b/_posts/07-06-01-Register-Globals.md @@ -4,7 +4,7 @@ isChild: true ## Register Globals -NOTE: As of PHP 5.4.0 the `register_globals` setting has been removed and can no +**NOTE:** As of PHP 5.4.0 the `register_globals` setting has been removed and can no longer be used. This is only included as a warning for anyone in the process of upgrading a legacy application. When enabled, the `register_globals` configuration setting that makes several types of variables (including ones from From 92afe9dde1fd3b507e943f2fae11d8aa97185879 Mon Sep 17 00:00:00 2001 From: = Date: Thu, 2 Aug 2012 07:49:37 -0400 Subject: [PATCH 012/843] Add coming soon note for Polish translation --- _includes/welcome.md | 1 + 1 file changed, 1 insertion(+) diff --git a/_includes/welcome.md b/_includes/welcome.md index 89a76d916..738505ccc 100644 --- a/_includes/welcome.md +++ b/_includes/welcome.md @@ -11,6 +11,7 @@ _PHP: The Right Way_ is (or soon will be) translated into many different languag * [English](http://www.phptherightway.com) * [Chinese](http://wulijun.github.com/php-the-right-way) * [Japanese](http://ja.phptherightway.com) +* Polish (Coming Soon) * Portuguese (Coming Soon) * Russian (Coming Soon) * [Spanish](http://es.phptherightway.com) From 1cba4665d60b048a2e4f9fc0d9de2438f0c6a3f0 Mon Sep 17 00:00:00 2001 From: Brian Nesbitt Date: Sat, 4 Aug 2012 00:05:08 -0300 Subject: [PATCH 013/843] Added simple SQL injection example Its possible (read: highly probable) newer developers will not understand a SQL injection vulnerability without a real example. --- _posts/06-01-01-Databases.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/_posts/06-01-01-Databases.md b/_posts/06-01-01-Databases.md index 15f3df473..ad517069c 100644 --- a/_posts/06-01-01-Databases.md +++ b/_posts/06-01-01-Databases.md @@ -36,8 +36,10 @@ $pdo = new PDO('sqlite:users.db'); $pdo->query("SELECT name FROM users WHERE id = " . $_GET['id']); // <-- NO! {% endhighlight %} -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. +This is terrible code. You are inserting a raw query parameter into a SQL query. This will get you hacked in a +heartbeat. Just imagine if a hacker passes in an inventive `id` parameter by calling a URL like +`http://domain.com/?id=1%3BDELETE+FROM+users`. This will set the `$id` variable to `id=1;DELETE FROM users` +which will delete all of your users! Instead, you should sanitize the ID input using PDO bound parameters. {% highlight php %} Date: Sat, 4 Aug 2012 00:36:16 -0300 Subject: [PATCH 014/843] Added small paragraph on connections MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some developers (maybe not newbies, but more coming from other languages) will be wondering if you have to close connections.  I think a quick touch on database connections and their automatic closing on script end is a helpful addition. --- _posts/06-01-01-Databases.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/_posts/06-01-01-Databases.md b/_posts/06-01-01-Databases.md index 15f3df473..eae1d69fd 100644 --- a/_posts/06-01-01-Databases.md +++ b/_posts/06-01-01-Databases.md @@ -52,6 +52,14 @@ database preventing potential SQL injection attacks. * [Learn about PDO][1] +You should also be aware that database connections use up resources and it was not unheard-of to have resources +exhausted if connections were not implicitly closed, however this was more common in other languages. Using PDO you +can implicitly close the connection by destroying the object by ensuring all remaining references to it are deleted, +ie. set to NULL. If you don't do this explicitly, PHP will automatically close the connection when your script ends +unless of course you are using persistent connections. + +* [Learn about PDO connections][5] + ## Abstraction Layers Many frameworks provide their own abstraction layer which may or may not sit on top of PDO. These will often emulate features for @@ -69,6 +77,7 @@ Some abstraction layers have been built using the PSR-0 namespace standard so ca [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/index.html#zend-db +[5]: http://php.net/manual/en/pdo.connections.php [mysql]: http://uk.php.net/mysql [mysqli]: http://uk.php.net/mysqli From 2684f69b95334ecbe0e1f90e0255862bd71c0dc7 Mon Sep 17 00:00:00 2001 From: Fran Moreno Date: Sat, 4 Aug 2012 14:15:18 +0300 Subject: [PATCH 015/843] Fix typo in Error reporting --- _posts/07-07-01-Error-Reporting.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/07-07-01-Error-Reporting.md b/_posts/07-07-01-Error-Reporting.md index d79405e16..4a9090861 100644 --- a/_posts/07-07-01-Error-Reporting.md +++ b/_posts/07-07-01-Error-Reporting.md @@ -4,7 +4,7 @@ isChild: true ## Error Reporting -Error logging can be useful in finding the problem spots in your application, but it can also expose infromation about +Error logging can be useful in finding the problem spots in your application, but it can also expose information about the structure of your application to the outside world. To effectively protect your application from issues that could be caused by the output of these messages, you need to configure your server differently in development versus production (live). From 45b3dcef9ada8a52e697e10bfaaf8f7cae577546 Mon Sep 17 00:00:00 2001 From: Brian Nesbitt Date: Sun, 5 Aug 2012 00:51:09 -0300 Subject: [PATCH 016/843] Changed $id to $_GET['id'] Updated variable name in text to match code. --- _posts/06-01-01-Databases.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/06-01-01-Databases.md b/_posts/06-01-01-Databases.md index ad517069c..c9c46c780 100644 --- a/_posts/06-01-01-Databases.md +++ b/_posts/06-01-01-Databases.md @@ -38,7 +38,7 @@ $pdo->query("SELECT name 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. Just imagine if a hacker passes in an inventive `id` parameter by calling a URL like -`http://domain.com/?id=1%3BDELETE+FROM+users`. This will set the `$id` variable to `id=1;DELETE FROM users` +`http://domain.com/?id=1%3BDELETE+FROM+users`. This will set the `$_GET['id']` variable to `id=1;DELETE FROM users` which will delete all of your users! Instead, you should sanitize the ID input using PDO bound parameters. {% highlight php %} From e6c68e6a9dd9c9ddb25e2aeaaf155bfa912539ec Mon Sep 17 00:00:00 2001 From: Phil Sturgeon Date: Mon, 6 Aug 2012 20:16:56 +0100 Subject: [PATCH 017/843] Added the component section. --- _posts/11-02-01-Frameworks.md | 6 +++++- _posts/11-03-01-Components.md | 25 +++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 _posts/11-03-01-Components.md diff --git a/_posts/11-02-01-Frameworks.md b/_posts/11-02-01-Frameworks.md index da59c4ca8..86ed9db3c 100644 --- a/_posts/11-02-01-Frameworks.md +++ b/_posts/11-02-01-Frameworks.md @@ -1,4 +1,8 @@ -# Frameworks +--- +isChild: true +--- + +## 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. diff --git a/_posts/11-03-01-Components.md b/_posts/11-03-01-Components.md new file mode 100644 index 000000000..50e2ae1e1 --- /dev/null +++ b/_posts/11-03-01-Components.md @@ -0,0 +1,25 @@ +--- +isChild: true +--- + +## Components + +As mentioned above "Components" are another approach to the common goal of creating, distributing and implementing shared code. Various +component repositories exist, the main two of which are: + +* [Packagist](/#composer_and_packagist) +* [PEAR](/#pear) + +Both of these repositories have command line tools associated with them to help the installaiton and upgrade processes, and have been +explained in more detail in the [Dependency Management][dm] section. + +There are also component-based frameworks, which allow you to use their components with minimal (or no) requirements. For example, you +can use the [FuelPHP Validation package][fuelval], without needing to use the FuelPHP framework itself. These projects are essentially +just another repository for reusable components: + + [dm]: /#dependency_management + [fuelval]: https://github.com/fuelphp/validation + +* [Aura](http://auraphp.github.com/) +* [FuelPHP (2.0 only)](https://github.com/fuelphp) +* [Symfony Components](http://symfony.com/doc/current/components/index.html) \ No newline at end of file From 4b564bdf86e7fd3022fc38d3180811ae3f96d451 Mon Sep 17 00:00:00 2001 From: Marcin Wawrzyniak Date: Tue, 7 Aug 2012 12:31:28 +0200 Subject: [PATCH 018/843] Created "The Basics" section Including common '=' operator misunderstandings, unneded if/else, ternary and short_tags --- _posts/05-03-01-The-Basics.md | 119 ++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 _posts/05-03-01-The-Basics.md diff --git a/_posts/05-03-01-The-Basics.md b/_posts/05-03-01-The-Basics.md new file mode 100644 index 000000000..149219f2e --- /dev/null +++ b/_posts/05-03-01-The-Basics.md @@ -0,0 +1,119 @@ +--- +isChild: true +--- + +## The Basics + +In this paragraph you will get familiar with a few of the most common beginner mistakes. + + +### Using correct number of = + +The most common mistake is not to distinguish three different ``=`` operators: + + +1. ``=`` which means assignment, +2. ``==`` which means comparison **without** type checking (equality), +3. ``===`` which means comparison **with** type checking (identicality) + +Comparison operators are used always when you want to make sure that two variables or values are equal, for example: + +{% highlight php %} +if ($user->isAuthorized() === true) { +{% endhighlight %} +But you can also use assignment operators within condition blocks: + +{% highlight php %} +if ( ($myObject = Cache::read('my-cache-key')) === false ) { +{% endhighlight %} +Notice: first, the assignment is made, which is exactly what we want, and then it is evaluated against ``boolean false``. + +Not understanding comparison operators may result in logic errors. One of the most common happens when using ``strpos``. + +{% highlight php %} +$str = strpos('http://phptherightway.com', 'http://'); +{% endhighlight %} + +Notice: ``$str`` will become ``integer`` 0 as ``'http://'`` is found right at the beginning. +Keep in mind that when no occurences is found, ``strpos`` will return ``boolean false``. + +So following code will cast ``integer`` 0, to ``boolean`` false: + +{% highlight php %} +if ($str) { +{% endhighlight %} + +Which is clearly a logic error, because the ``http://`` substring was found. + +That's where `comparison operator with type checking` comes in: + +{% highlight php %} +if ($str !== false) { +{% endhighlight %} + +No type casting will occur, and that's why your logic is fine. + +### Unneded if/else and ternary + +Beginners very often tend to write following code: + +{% highlight php %} +if($user->isAuthorized()) { + return true; +} else { + return false; +} +{% endhighlight %} + +Notice that isAuthorized() is actually a ``boolean``, so you can write: + +{% highlight php %} +return $user->isAuthorized(); +{% endhighlight %} + +Another very common example would be: + +{% highlight php %} +if ($user->isAuthorized()) { + echo 'User authorized'; +} else { + echo 'Authorization error.'; +} +{% endhighlight %} + +Here you can simply use ternary operator: + +{% highlight php %} +echo $user->isAuthorized() ? 'User authorized' : 'Authorization error.'; +{% endhighlight %} + +As you can see above, ternary operator is just a more compact form of an ``if`` block. + +Keep in mind, that when you need to use nested ``if`` blocks, it is not recommended to use ternary operator, +as it may result in unreadable and error prone code: + +{% highlight php %} +echo (true?'true':false?'t':'f'); +{% endhighlight %} + +### Short tags + +Since PHP 5.4 , short tags are always safe to use. Regardless : + +``short_open_tag = Off`` + +Short tags are especially convenient to use in your presentation layer and that's where you should incorporate them. + +_When using PHP < 5.4, be aware that if short tags are supported or not, depends on your php.ini settings._ + +So, enjoy writing: + +{% highlight php %} +getLogin() ?> +{% endhighlight %} + +Instead of: + +{% highlight php %} +getLogin() ?>`` +{% endhighlight %} \ No newline at end of file From 2d1af2cb0f4a85225a3b25c906e1c1b2e7f972f1 Mon Sep 17 00:00:00 2001 From: elazar Date: Tue, 7 Aug 2012 17:01:05 -0500 Subject: [PATCH 019/843] Changed some UK subdomain-specific php.net links to be language-agnostic --- _posts/03-02-01-Programming-Paradigms.md | 2 +- _posts/06-01-01-Databases.md | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/_posts/03-02-01-Programming-Paradigms.md b/_posts/03-02-01-Programming-Paradigms.md index 692021fac..39c67b624 100644 --- a/_posts/03-02-01-Programming-Paradigms.md +++ b/_posts/03-02-01-Programming-Paradigms.md @@ -48,7 +48,7 @@ available as `__call()` and `__callStatic()`. * [Read about Reflection][reflection] [namespaces]: http://php.net/manual/en/language.namespaces.php -[overloading]: http://uk.php.net/manual/en/language.oop5.overloading.php +[overloading]: http://php.net/manual/en/language.oop5.overloading.php [oop]: http://www.php.net/manual/en/language.oop5.php [anonymous-functions]: http://www.php.net/manual/en/functions.anonymous.php [closure-class]: http://php.net/manual/en/class.closure.php diff --git a/_posts/06-01-01-Databases.md b/_posts/06-01-01-Databases.md index df82762a8..6bcf4be4c 100644 --- a/_posts/06-01-01-Databases.md +++ b/_posts/06-01-01-Databases.md @@ -81,6 +81,6 @@ Some abstraction layers have been built using the PSR-0 namespace standard so ca [4]: http://packages.zendframework.com/docs/latest/manual/en/index.html#zend-db [5]: http://php.net/manual/en/pdo.connections.php -[mysql]: http://uk.php.net/mysql -[mysqli]: http://uk.php.net/mysqli -[pgsql]: http://uk.php.net/pgsql +[mysql]: http://php.net/mysql +[mysqli]: http://php.net/mysqli +[pgsql]: http://php.net/pgsql From f8fc0e147d6818bb793422df9ac8d659a13dbaf6 Mon Sep 17 00:00:00 2001 From: Marcin Wawrzyniak Date: Thu, 9 Aug 2012 21:45:18 +0200 Subject: [PATCH 020/843] * fixed a typo --- _posts/05-03-01-The-Basics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/05-03-01-The-Basics.md b/_posts/05-03-01-The-Basics.md index 149219f2e..498630c99 100644 --- a/_posts/05-03-01-The-Basics.md +++ b/_posts/05-03-01-The-Basics.md @@ -53,7 +53,7 @@ if ($str !== false) { No type casting will occur, and that's why your logic is fine. -### Unneded if/else and ternary +### Unnecessary if/else and ternary Beginners very often tend to write following code: From 6dc756bed51ed2db12b081a6ba9f3dfb4251bbdf Mon Sep 17 00:00:00 2001 From: Marcin Wawrzyniak Date: Thu, 9 Aug 2012 22:17:32 +0200 Subject: [PATCH 021/843] Created print.css for printing --- _layouts/default.html | 179 +++++++++++++++++++++--------------------- styles/print.css | 12 +++ 2 files changed, 102 insertions(+), 89 deletions(-) create mode 100644 styles/print.css diff --git a/_layouts/default.html b/_layouts/default.html index 7bcd73c80..a233022c2 100644 --- a/_layouts/default.html +++ b/_layouts/default.html @@ -1,89 +1,90 @@ - - - - - {% if page.title %}{{ page.title }} - {% endif %}PHP: The Right Way - - - - - - - - - - - - - - - - - -
- - - Fork me on GitHub - - - - {{ content }} - -
- - - - - - + + + + + {% if page.title %}{{ page.title }} - {% endif %}PHP: The Right Way + + + + + + + + + + + + + + + + + + +
+ + + Fork me on GitHub + + + + {{ content }} + +
+ + + + + + diff --git a/styles/print.css b/styles/print.css new file mode 100644 index 000000000..e9b865afd --- /dev/null +++ b/styles/print.css @@ -0,0 +1,12 @@ +body, .site-title, h1, h2, h3{ + font-family: 'Georgia' !important; +} + + +nav.site-navigation, a.fork-me, a.top{ + display:none; +} + +div.site-content{ + padding: 20px 40px 40px 20px; +} \ No newline at end of file From 78be54a75ae7898a6284c732b0e799086ab73c28 Mon Sep 17 00:00:00 2001 From: Marcin Wawrzyniak Date: Thu, 9 Aug 2012 22:18:49 +0200 Subject: [PATCH 022/843] Fixed line endings... --- _layouts/default.html | 180 +++++++++++++++++++++--------------------- 1 file changed, 90 insertions(+), 90 deletions(-) diff --git a/_layouts/default.html b/_layouts/default.html index a233022c2..aeb97c599 100644 --- a/_layouts/default.html +++ b/_layouts/default.html @@ -1,90 +1,90 @@ - - - - - {% if page.title %}{{ page.title }} - {% endif %}PHP: The Right Way - - - - - - - - - - - - - - - - - - -
- - - Fork me on GitHub - - - - {{ content }} - -
- - - - - - + + + + + {% if page.title %}{{ page.title }} - {% endif %}PHP: The Right Way + + + + + + + + + + + + + + + + + + +
+ + + Fork me on GitHub + + + + {{ content }} + +
+ + + + + + From 6824c3ce3476d598061c37508c041587c4eee9e6 Mon Sep 17 00:00:00 2001 From: Marcin Wawrzyniak Date: Thu, 9 Aug 2012 22:22:01 +0200 Subject: [PATCH 023/843] Revert "* fixed a typo" This reverts commit f8fc0e147d6818bb793422df9ac8d659a13dbaf6. --- _posts/05-03-01-The-Basics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/05-03-01-The-Basics.md b/_posts/05-03-01-The-Basics.md index 498630c99..149219f2e 100644 --- a/_posts/05-03-01-The-Basics.md +++ b/_posts/05-03-01-The-Basics.md @@ -53,7 +53,7 @@ if ($str !== false) { No type casting will occur, and that's why your logic is fine. -### Unnecessary if/else and ternary +### Unneded if/else and ternary Beginners very often tend to write following code: From a5076f05406b70f6c4159352a1d5a6019bbc9de8 Mon Sep 17 00:00:00 2001 From: Marcin Wawrzyniak Date: Thu, 9 Aug 2012 22:22:07 +0200 Subject: [PATCH 024/843] Revert "Created "The Basics" section" This reverts commit 4b564bdf86e7fd3022fc38d3180811ae3f96d451. --- _posts/05-03-01-The-Basics.md | 119 ---------------------------------- 1 file changed, 119 deletions(-) delete mode 100644 _posts/05-03-01-The-Basics.md diff --git a/_posts/05-03-01-The-Basics.md b/_posts/05-03-01-The-Basics.md deleted file mode 100644 index 149219f2e..000000000 --- a/_posts/05-03-01-The-Basics.md +++ /dev/null @@ -1,119 +0,0 @@ ---- -isChild: true ---- - -## The Basics - -In this paragraph you will get familiar with a few of the most common beginner mistakes. - - -### Using correct number of = - -The most common mistake is not to distinguish three different ``=`` operators: - - -1. ``=`` which means assignment, -2. ``==`` which means comparison **without** type checking (equality), -3. ``===`` which means comparison **with** type checking (identicality) - -Comparison operators are used always when you want to make sure that two variables or values are equal, for example: - -{% highlight php %} -if ($user->isAuthorized() === true) { -{% endhighlight %} -But you can also use assignment operators within condition blocks: - -{% highlight php %} -if ( ($myObject = Cache::read('my-cache-key')) === false ) { -{% endhighlight %} -Notice: first, the assignment is made, which is exactly what we want, and then it is evaluated against ``boolean false``. - -Not understanding comparison operators may result in logic errors. One of the most common happens when using ``strpos``. - -{% highlight php %} -$str = strpos('http://phptherightway.com', 'http://'); -{% endhighlight %} - -Notice: ``$str`` will become ``integer`` 0 as ``'http://'`` is found right at the beginning. -Keep in mind that when no occurences is found, ``strpos`` will return ``boolean false``. - -So following code will cast ``integer`` 0, to ``boolean`` false: - -{% highlight php %} -if ($str) { -{% endhighlight %} - -Which is clearly a logic error, because the ``http://`` substring was found. - -That's where `comparison operator with type checking` comes in: - -{% highlight php %} -if ($str !== false) { -{% endhighlight %} - -No type casting will occur, and that's why your logic is fine. - -### Unneded if/else and ternary - -Beginners very often tend to write following code: - -{% highlight php %} -if($user->isAuthorized()) { - return true; -} else { - return false; -} -{% endhighlight %} - -Notice that isAuthorized() is actually a ``boolean``, so you can write: - -{% highlight php %} -return $user->isAuthorized(); -{% endhighlight %} - -Another very common example would be: - -{% highlight php %} -if ($user->isAuthorized()) { - echo 'User authorized'; -} else { - echo 'Authorization error.'; -} -{% endhighlight %} - -Here you can simply use ternary operator: - -{% highlight php %} -echo $user->isAuthorized() ? 'User authorized' : 'Authorization error.'; -{% endhighlight %} - -As you can see above, ternary operator is just a more compact form of an ``if`` block. - -Keep in mind, that when you need to use nested ``if`` blocks, it is not recommended to use ternary operator, -as it may result in unreadable and error prone code: - -{% highlight php %} -echo (true?'true':false?'t':'f'); -{% endhighlight %} - -### Short tags - -Since PHP 5.4 , short tags are always safe to use. Regardless : - -``short_open_tag = Off`` - -Short tags are especially convenient to use in your presentation layer and that's where you should incorporate them. - -_When using PHP < 5.4, be aware that if short tags are supported or not, depends on your php.ini settings._ - -So, enjoy writing: - -{% highlight php %} -getLogin() ?> -{% endhighlight %} - -Instead of: - -{% highlight php %} -getLogin() ?>`` -{% endhighlight %} \ No newline at end of file From 3a02de8d8f3262bf76862f72720c690483f14f37 Mon Sep 17 00:00:00 2001 From: Nick Adams Date: Sat, 11 Aug 2012 03:08:19 +1200 Subject: [PATCH 025/843] Added "The Basics" section --- ...atterns.md => 05-04-01-Design-Patterns.md} | 0 _posts/05-05-01-The-Basics.md | 12 + pages/The-Basics.md | 322 ++++++++++++++++++ 3 files changed, 334 insertions(+) rename _posts/{05-03-01-Design-Patterns.md => 05-04-01-Design-Patterns.md} (100%) create mode 100644 _posts/05-05-01-The-Basics.md create mode 100644 pages/The-Basics.md diff --git a/_posts/05-03-01-Design-Patterns.md b/_posts/05-04-01-Design-Patterns.md similarity index 100% rename from _posts/05-03-01-Design-Patterns.md rename to _posts/05-04-01-Design-Patterns.md diff --git a/_posts/05-05-01-The-Basics.md b/_posts/05-05-01-The-Basics.md new file mode 100644 index 000000000..11d3000b9 --- /dev/null +++ b/_posts/05-05-01-The-Basics.md @@ -0,0 +1,12 @@ +--- +isChild: true +--- + +## The Basics + +PHP is a vast language that allows coders of all levels the ability to produce code not only quickly, but efficiently. +However while advancing through the language, we often forget the basics that we first learnt (or overlooked) in favor +of short cuts and/or bad habits. To help combat this common issue, this section is aimed at reminding coders of the +basic coding practices within PHP. + +* Continue reading on [The Basics](/pages/The-Basics.html) \ No newline at end of file diff --git a/pages/The-Basics.md b/pages/The-Basics.md new file mode 100644 index 000000000..da7af36c2 --- /dev/null +++ b/pages/The-Basics.md @@ -0,0 +1,322 @@ +--- +layout: page +title: The Basics +--- + +# The Basics + +## Comparison operators + +Comparison operators are an often overlooked aspect of PHP, which can lead to many unexpected outcomes. One such +problem stems from strict comparisons (the comparison of booleans as integers). + +{% highlight php %} + Date: Fri, 10 Aug 2012 13:03:52 -0400 Subject: [PATCH 026/843] Bump The Basics to top of section --- _posts/{05-05-01-The-Basics.md => 05-02-01-The-Basics.md} | 0 _posts/{05-02-01-Exceptions.md => 05-05-01-Exceptions.md} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename _posts/{05-05-01-The-Basics.md => 05-02-01-The-Basics.md} (100%) rename _posts/{05-02-01-Exceptions.md => 05-05-01-Exceptions.md} (100%) diff --git a/_posts/05-05-01-The-Basics.md b/_posts/05-02-01-The-Basics.md similarity index 100% rename from _posts/05-05-01-The-Basics.md rename to _posts/05-02-01-The-Basics.md diff --git a/_posts/05-02-01-Exceptions.md b/_posts/05-05-01-Exceptions.md similarity index 100% rename from _posts/05-02-01-Exceptions.md rename to _posts/05-05-01-Exceptions.md From 26628985dd36151c8acd6036e091ed5666cfd107 Mon Sep 17 00:00:00 2001 From: = Date: Fri, 10 Aug 2012 13:42:40 -0400 Subject: [PATCH 027/843] Tweak perf example in The Basics --- pages/The-Basics.md | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/pages/The-Basics.md b/pages/The-Basics.md index da7af36c2..26f52652f 100644 --- a/pages/The-Basics.md +++ b/pages/The-Basics.md @@ -7,7 +7,7 @@ title: The Basics ## Comparison operators -Comparison operators are an often overlooked aspect of PHP, which can lead to many unexpected outcomes. One such +Comparison operators are an often overlooked aspect of PHP, which can lead to many unexpected outcomes. One such problem stems from strict comparisons (the comparison of booleans as integers). {% highlight php %} @@ -40,8 +40,8 @@ if (strpos('testing', 'test') !== false) { // true, as strict comparison was ### If statements -While using 'if/else' statements within a function or class, there is a common misconception that 'else' must be used -in conjunction to declare potential outcomes. However if the outcome is to define the return value, 'else' is not +While using 'if/else' statements within a function or class, there is a common misconception that 'else' must be used +in conjunction to declare potential outcomes. However if the outcome is to define the return value, 'else' is not necessary as 'return' will end the function, causing 'else' to become moot. {% highlight php %} @@ -104,7 +104,7 @@ function test($a) ## Global namespace -While using namespaces, you may find your code being executed in the wrong scope for internal methods. To fix this, +While using namespaces, you may find your code being executed in the wrong scope for internal methods. To fix this, define the method globally by using a backslash before the method. {% highlight php %} @@ -153,12 +153,12 @@ $a = 'Multi-line example' // concatenation operator (.) ### String types -String types are a constant feature within the PHP community, but hopefully this section will explain the +String types are a constant feature within the PHP community, but hopefully this section will explain the differences between the string types and their benefits/uses. #### Single quotes -Single quotes are the simplest way to define a string and are often the quickest. Their quickness stems from PHP not +Single quotes are the simplest way to define a string and are often the quickest. Their quickness stems from PHP not parsing the string (doesn't parse for variables). They're best suited for: - Strings that do not need to be parsed @@ -179,7 +179,7 @@ echo 'This is my string, look at how pretty it is.'; // no need to parse a si #### Double quotes -Double quotes are the Swiss army knife of strings, but are slower due to the string being parsed. They're best +Double quotes are the Swiss army knife of strings, but are slower due to the string being parsed. They're best suited for: - Escaped strings @@ -198,8 +198,8 @@ echo "phptherightway's is $adjective.\n I love learning $code!" // Instead of m // enables us to use a parsable string {% endhighlight %} -While using double quotes that contain variables, it's often the case that the variable will be touching another -character. This will result in PHP not parsing the variable due to the variable being camouflaged. To fix this problem, +While using double quotes that contain variables, it's often the case that the variable will be touching another +character. This will result in PHP not parsing the variable due to the variable being camouflaged. To fix this problem, wrap the variable within a pair of curly brackets. {% highlight php %} @@ -224,7 +224,7 @@ echo "I drank some juice made of {$juice[1]}s"; // $juice[1] will be parsed #### Nowdoc syntax -Nowdoc syntax was introduced in 5.3 and internally behaves the same way as single quotes except it's suited toward the +Nowdoc syntax was introduced in 5.3 and internally behaves the same way as single quotes except it's suited toward the use of multi-line strings without the need for concatenating. {% highlight php %} @@ -250,7 +250,7 @@ EOD; // closing 'EOD' must be on it's own line, and to th #### Heredoc syntax -Heredoc syntax internally behaves the same way as double quotes except it's suited toward the use of multi-line +Heredoc syntax internally behaves the same way as double quotes except it's suited toward the use of multi-line strings without the need for concatenating. {% highlight php %} @@ -278,7 +278,7 @@ EOD; // closing 'EOD' must be on it's own line, and to th ## Ternary operators -Ternary operators are a great way to condense code, but are often used in excess. While ternary operators can be +Ternary operators are a great way to condense code, but are often used in excess. While ternary operators can be stacked/nested, it is advised to use one per line for readability. {% highlight php %} @@ -305,18 +305,18 @@ echo ($a == 5) ? return true : return false; // this example will output an e ## Variable declarations -At times, coders attempt to make their code "cleaner" by declaring predefined variables with a different name. What -this does in reality is to double the memory consumption of said script. For the example below, let's say -$_GET\['about_me'\] contains 1MB worth of data, by copying the variable you've increased the scripts execution to 2MB. +At times, coders attempt to make their code "cleaner" by declaring predefined variables with a different name. What +this does in reality is to double the memory consumption of said script. For the example below, let's say +an example string of text contains 1MB worth of data, by copying the variable you've increased the scripts execution to 2MB. {% highlight php %} Date: Sat, 11 Aug 2012 07:01:01 +0900 Subject: [PATCH 028/843] Remove single quotes from heredoc identifier --- pages/The-Basics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/The-Basics.md b/pages/The-Basics.md index 26f52652f..21169fbed 100644 --- a/pages/The-Basics.md +++ b/pages/The-Basics.md @@ -257,7 +257,7 @@ strings without the need for concatenating. Date: Sat, 11 Aug 2012 16:59:18 +1200 Subject: [PATCH 029/843] Grammar/Spelling corrections --- pages/The-Basics.md | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/pages/The-Basics.md b/pages/The-Basics.md index 21169fbed..e7a6f3f88 100644 --- a/pages/The-Basics.md +++ b/pages/The-Basics.md @@ -14,10 +14,10 @@ problem stems from strict comparisons (the comparison of booleans as integers). Date: Tue, 14 Aug 2012 23:15:25 +1200 Subject: [PATCH 030/843] Unified conditional arguments and replaced APC example --- _posts/03-05-01-Command-Line-Interface.md | 2 +- _posts/05-03-01-Date-and-Time.md | 13 ++++++------- _posts/10-03-01-Object-Caching.md | 11 ++++------- 3 files changed, 11 insertions(+), 15 deletions(-) diff --git a/_posts/03-05-01-Command-Line-Interface.md b/_posts/03-05-01-Command-Line-Interface.md index 337182309..8790591c8 100644 --- a/_posts/03-05-01-Command-Line-Interface.md +++ b/_posts/03-05-01-Command-Line-Interface.md @@ -22,7 +22,7 @@ Let's write a simple "Hello, $name" CLI program. To try it out, create a file na {% highlight php %} format('m/d/Y') . "\n"; +echo 'Start date: ' . $start->format('m/d/Y') . "\n"; {% endhighlight %} Calculating with DateTime is possible with the DateInterval class. DateTime has methods like `add()` and `sub()` that @@ -30,18 +30,18 @@ $end = clone $start; $end->add(new \DateInterval('P1M6D')); $diff = $end->diff($start); -echo "Difference: " . $diff->format('%m month, %d days (total: %a days)') . "\n"; +echo 'Difference: ' . $diff->format('%m month, %d days (total: %a days)') . "\n"; // Difference: 1 month, 6 days (total: 37 days) {% endhighlight %} On DateTime objects you can use standard comparison: {% highlight php %} format('m/d/Y') . " "; + echo $date->format('m/d/Y') . ' '; } {% endhighlight %} diff --git a/_posts/10-03-01-Object-Caching.md b/_posts/10-03-01-Object-Caching.md index c072aeae1..b2966895e 100644 --- a/_posts/10-03-01-Object-Caching.md +++ b/_posts/10-03-01-Object-Caching.md @@ -28,15 +28,12 @@ Example logic using APC: {% highlight php %} Date: Tue, 14 Aug 2012 22:17:20 -0300 Subject: [PATCH 031/843] Equalizing the information at BDD links list. On the "BDD links" list is important keeping the same level of information given about each item. Thus, as the second item of the list shows that PHPSpec is the SpecBDD implementation for PHP, the first line, about Behat, has been changed to inform the reader that it is the StoryBDD implementation for PHP. --- _posts/08-03-01-Behavior-Driven-Development.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/_posts/08-03-01-Behavior-Driven-Development.md b/_posts/08-03-01-Behavior-Driven-Development.md index 9fb44fa88..253c82c88 100644 --- a/_posts/08-03-01-Behavior-Driven-Development.md +++ b/_posts/08-03-01-Behavior-Driven-Development.md @@ -17,6 +17,6 @@ by the [RSpec project](http://rspec.info/) for Ruby. ### BDD Links -* [Behat](http://behat.org/) is inspired by Ruby's [Cucumber](http://cukes.info/) project -* [PHPSpec](http://www.phpspec.net/) the SpecBDD framework for PHP -* [Codeception](http://www.codeception.com) is a full-stack testing framework that uses BDD principles +* [Behat](http://behat.org/), the StoryBDD framework for PHP, inspired by Ruby's [Cucumber](http://cukes.info/) project; +* [PHPSpec](http://www.phpspec.net/), the SpecBDD framework for PHP, inspired by Ruby's [RSpec](http://rspec.info/) project; +* [Codeception](http://www.codeception.com) is a full-stack testing framework that uses BDD principles. From 4881145493ccf90de417c99631349038030c024f Mon Sep 17 00:00:00 2001 From: Arlo O'Keeffe Date: Wed, 15 Aug 2012 15:42:41 -0600 Subject: [PATCH 032/843] PHP_CodeSniffer includes PSR1+2 sniffs It pointed me in the wrong direction when trying to use the recommendations of the document. --- _posts/02-01-01-Code-Style-Guide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/02-01-01-Code-Style-Guide.md b/_posts/02-01-01-Code-Style-Guide.md index 5196c9d07..90aa4d68a 100644 --- a/_posts/02-01-01-Code-Style-Guide.md +++ b/_posts/02-01-01-Code-Style-Guide.md @@ -18,7 +18,7 @@ not require PSR-2. * [Read about PSR-1][psr1] * [Read about PSR-2][psr2] -You can use the [phpcs-psr][phpcs-psr] sniff for [PHP_CodeSniffer][phpcs] to check code against these recommendations. +You can use [PHP_CodeSniffer][phpcs] to check code against these recommendations. Use Fabien Potencier's [PHP Coding Standards Fixer][phpcsfixer] to automatically modify your code syntax so that it conforms with these standards, saving you from fixing each problem by hand. From 75cc75e7128acd4099deb6ea0b2eb2ae2b10cdd7 Mon Sep 17 00:00:00 2001 From: Cristobal Rodriguez Date: Thu, 16 Aug 2012 17:03:36 -0700 Subject: [PATCH 033/843] Fix typo in Components section --- _posts/11-03-01-Components.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/11-03-01-Components.md b/_posts/11-03-01-Components.md index 50e2ae1e1..a416666b4 100644 --- a/_posts/11-03-01-Components.md +++ b/_posts/11-03-01-Components.md @@ -10,7 +10,7 @@ component repositories exist, the main two of which are: * [Packagist](/#composer_and_packagist) * [PEAR](/#pear) -Both of these repositories have command line tools associated with them to help the installaiton and upgrade processes, and have been +Both of these repositories have command line tools associated with them to help the installation and upgrade processes, and have been explained in more detail in the [Dependency Management][dm] section. There are also component-based frameworks, which allow you to use their components with minimal (or no) requirements. For example, you From 207250fbe36e293fb3147357da91c3de69a59733 Mon Sep 17 00:00:00 2001 From: Andrea Date: Mon, 20 Aug 2012 12:24:40 +0200 Subject: [PATCH 034/843] optimized images with Yahoo Smush.it --- images/banners/btn1-120x90.png | Bin 6980 -> 6057 bytes images/banners/btn2-120x60.png | Bin 5261 -> 4338 bytes images/banners/leaderboard-728x90.png | Bin 24101 -> 23177 bytes images/banners/lg-rect-386x280.png | Bin 44699 -> 43789 bytes images/banners/med-rect-300x250.png | Bin 32008 -> 31141 bytes images/banners/rect-180x150.png | Bin 12650 -> 11727 bytes images/banners/sq-btn-125x125.png | Bin 9155 -> 8232 bytes images/banners/vert-rect-240x400.png | Bin 37941 -> 37168 bytes images/favicon.png | Bin 368 -> 262 bytes images/og-logo.png | Bin 4968 -> 4113 bytes 10 files changed, 0 insertions(+), 0 deletions(-) diff --git a/images/banners/btn1-120x90.png b/images/banners/btn1-120x90.png index 437714639260382166da1b05013acdd178772281..a38b7371e0daa4bad3fb971dcd8e1c0a61b54f25 100644 GIT binary patch delta 47 zcmX?Nwo-qB^5#9vy^I`BJY5_^GVaaY9LRb{RFqwGg-ZQ(&T2~rAnDu2BwVUA5;?N9H;t9pYu4Mw$;A>s z03W~yzy%3$LE-=hE=YU<;>?v_V7G}Y4ry8WusfdjX6DVzJNV6fT`ekmyf@~@bix;y zkxD0|Cj<;)d`gA{hszh=NxM?HF^xuJKK7s30gY8GebhWoEAq4t@)QR%!odkSjS@%s z^ZAPcqR>&E8NTMHE}2G;SBxC54oAUi7FeNj@CdYXTM)#g;27lbJjv|bQ7(vWagPbd zPyrV{eC8Jdy=0N_j*RASv+) zJ>!ldQeD>&r@p^ohA_!CQVG#uj#G$K4aTu7?7}63h?Y#M zC0fXLeI)59(y^biNc08IJsO;Biu?%R6>+27lj>o@2fdhff>U;YIspfKM6 diff --git a/images/banners/btn2-120x60.png b/images/banners/btn2-120x60.png index 664b4c37e0cb0629de37501eb96b9840d6031218..d413586fda61f75e4b1a78a48b3d5ccc09b18666 100644 GIT binary patch delta 47 zcmeCx{G>QRdGj9TUPcaGPZ!6Kh{IDi2ePX2i?TlbEn=7^;VQ!b1fH&bF6*2UngD>! B4$%Mr delta 975 zcmah|F>ljA6i&s$#sWet=;{iom59&h#CBrUREf_Ok#MQfNJLD%+Ly*k?K9^Kak^My zM=jyYu&b@4fHd`@Q~h>-9!ayCb}zIA9|& zBb?ScAv>a=7n5V!rzD&|`$D&CwQJ*OFcd@oksYvDB_&49Vbw3FijOT4bw#TfvzDPYVtGdsA(Ifty^HV6d8_( zBfF1xSFz;DQN}`~b^+mRHdAK}mGNVU+U<5JqU&`Dsb}*tt| oyAFG}GswTadH-SU-i_P04r@RD+(bXWeqM}U&)dUqyN56S0u9$P0ssI2 diff --git a/images/banners/leaderboard-728x90.png b/images/banners/leaderboard-728x90.png index 664f0475ba719bb1070bc3aaca5dc62165ce5d3c..bbe562af6a057b973fbeaf4b7a2901b21b087948 100644 GIT binary patch delta 49 zcmZ3whp}@j;{@f+dzgC}IgWU`IEGZ*I=eZLbx(w-JmdKI;Vst E0PL_5mjD0& delta 978 zcmah|F>ljA6n0dESlM7fhs#hT;`2GNlUOm8<4Z&&T&gq@8M)e*#!Bro=PPl$SYl&> zKhYI|011goU62qGGXsBuAHc%7i7SS-oIKo}zwdkRefQq0PqpKd+MD%4xh?t=vBRcf zK{!?1knK`1jL9AyQ4$_L|4zG#vNnsx6EX20+X0I;Qew0`PL*Xo7++#riCCNkN1nk*p~a4 z3IbJdh7of|U1l}$w}Hnv1*X=h2RcH)vNY5*EekyWhK>xV%g?H#rfpib(E_Wb%5XfK z+9Nzz#gZpSoe7cJ1%!*mLR&O6#`hrVbULMoVbmq0o*gEFaaq_IIuj#WREb;y&&G!-g(I4=10KjH znXXrCY2Ve6N}x=~e!?U9E@U6G;2@@n7-C12f3z?PZM`ts(#Td*ZyCDPMyRc~8`v_j z+cH~t&~q!1i^xsvdS0(R@K94S`>5Bn8rbv<&+NC{PXC-cOfo@|fL4Jc8FUfoA2+w quHE=H#O^r%_2a|m+R5bBsj{YA``GM diff --git a/images/banners/lg-rect-386x280.png b/images/banners/lg-rect-386x280.png index 84bd12ef4fcf447f908896742931d9eb1e9434eb..10cec2940a335351287d38491d90668caa0b4283 100644 GIT binary patch delta 43693 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 literal 44699 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 M07*qoM6N<$f|@Ya761SM diff --git a/images/banners/med-rect-300x250.png b/images/banners/med-rect-300x250.png index cd8451e44727e119c82a0e0140bbd27ee59ceaf9..f93da0972a9a4195b4fd1ff2d0237c9eab768907 100644 GIT binary patch delta 30964 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
wPM5S&*) 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 literal 32008 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 z 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 diff --git a/images/banners/sq-btn-125x125.png b/images/banners/sq-btn-125x125.png index ce7f08194f4d2a40f3a517ec9a679ddc3c55ce47..e15f3f31509533b7b34ee5b2cf9c8e8e2d1248b2 100644 GIT binary patch delta 47 zcmX@?zQSRG^5#9vy^I{mo-U3d8TaOH4rGm%6J;zsDAn@&*5O_TAn#n!N?Zpys z;RGMR2XI0{T#z^*#EDGiBFDx()C8;+AJAQ#3X#|L@d>b^3lsQZ>Y1rS>_} z-(SCJAcDD+pJ&3xowz&b;OGgr0wqlrK_D0JMx}V zL7)cCe8hpPEwY+~JHTU{0#k1_BZM)qEFHH^%fk18fv^FQ{H!K!JEr9rHdr1_hU4+n z8To@{EctS^nGm^CK{%h!^?6HYd>`U&x2s4DqbXgQ#YrYe+02Tyn!=|=#FJbkECY&? z?6G6vYBJSD4QU>ROJ)eOVkwmr4VEN_SVu5TRbgk|g&5JQPUI5zVtkTQIHCnR=8+9U^2UDbH6${i3yzRtIZW^#47+>z~9?Wdpayj{62 mh3k#WU++JES$Vd4^9E`heZT$Me)FfJ)^8YW`5*hwU;YKq5HPO* diff --git a/images/banners/vert-rect-240x400.png b/images/banners/vert-rect-240x400.png index 315e7fadd3d63c258310a2e29529f0745139d60f..8be5a98e71df36dbdbe3211527a77230a4168b06 100644 GIT binary patch delta 37040 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 literal 37941 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 diff --git a/images/favicon.png b/images/favicon.png index 68c71571e71b7b66a6489ba0c6f1c9f0a4eb2cee..cacdef657e98ff337214d01782f9bd7675bb7bcb 100644 GIT binary patch delta 234 zcmVnGEz#=M2=Ss@m7&xbaFI)t66n|j^?|7FI6<`W7oqvKn@|ymMM)xJX4CX6! zIWw-+K%|KuM6a-N#F?~a4X($~?pYr|#|R@$gEh)N<{`JG8@d7AMiK+EcrXj{Hhe}k z{p~wlH6im5Vy#wr!=Jd=jl`GKC(!xF>}~LcsTP^Cj`@vx{1SH^?9ZTr@Po5fF>hEe z*gwN9cq8knmQJaSF~6|Zq2bXaB{kS4yIoQuecEjgW?LO$e(>?}2cfr!ZU*jf(&X|K nO*CnJRgdrunDVDr(BX%iaP+H|pCmZdFNFS65Qwhi6M#L3jAy#)LP zdhqVq!@}ZG#ETa}`~m&~4}yQenKoI4wZj}{hUa=!nQaQ%#p5w z4TjGhb?a*E9f2-o7&Nq6#Wze7K&YAZ288B)P&Le|Zio#lX5DT;yV?Z#QbjlxoY({R zAde+(jymH!wliH{E|=P}rcpN4P0O;RNVQrKkV>+OI7%x~QZ6K1ocJt^c}OE5CDDW~ zxT6ZI+Z;%o>*{)x8~o*VE_1V-EGL4*BD9NH z_!0*Pj1sU(+YWb|XP5S1K>zZ zJrm>o{`vUf`R(hatKa)>XO#Z<^`TYza_#1gW97=Hv-5Y~_TI{$)9)R+XOE6w{Q>ib B9Mk{+ From f731160dedbbf22e97222b332c631f5cdfa79f1e Mon Sep 17 00:00:00 2001 From: andrea Date: Mon, 20 Aug 2012 15:02:13 +0200 Subject: [PATCH 035/843] Fixed maruku warning: Unclosed span (waiting for ["*"]) --- pages/The-Basics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/The-Basics.md b/pages/The-Basics.md index e7a6f3f88..7b2e8937a 100644 --- a/pages/The-Basics.md +++ b/pages/The-Basics.md @@ -274,7 +274,7 @@ EOD; // closing 'EOD' must be on it's own line, and to th */ {% endhighlight %} -*[Heredoc syntax](http://www.php.net/manual/en/language.types.string.php#language.types.string.syntax.heredoc) +* [Heredoc syntax](http://www.php.net/manual/en/language.types.string.php#language.types.string.syntax.heredoc) ## Ternary operators From d5d5d0725bb7658460b09489065ad29d13663af1 Mon Sep 17 00:00:00 2001 From: andrea Date: Mon, 20 Aug 2012 16:20:00 +0200 Subject: [PATCH 036/843] Fixed w3c validator errors for "Duplicate ID" --- _posts/01-01-01-Getting-Started.md | 2 +- _posts/01-02-01-Use-the-Current-Stable-Version.md | 2 +- _posts/01-03-01-Built-in-Web-Server.md | 2 +- _posts/01-04-01-Mac-Setup.md | 2 +- _posts/01-05-01-Windows-Setup.md | 2 +- _posts/02-01-01-Code-Style-Guide.md | 2 +- _posts/03-01-01-Language-Highlights.md | 2 +- _posts/03-02-01-Programming-Paradigms.md | 2 +- _posts/03-03-01-Namespaces.md | 2 +- _posts/03-04-01-Standard-PHP-Library.md | 2 +- _posts/03-05-01-Command-Line-Interface.md | 2 +- _posts/04-01-01-Dependency-Management.md | 2 +- _posts/04-02-01-Composer-and-Packagist.md | 2 +- _posts/04-03-01-PEAR.md | 2 +- _posts/05-01-01-Coding-Practices.md | 2 +- _posts/05-02-01-The-Basics.md | 2 +- _posts/05-03-01-Date-and-Time.md | 2 +- _posts/05-04-01-Design-Patterns.md | 2 +- _posts/05-05-01-Exceptions.md | 2 +- _posts/06-01-01-Databases.md | 2 +- _posts/07-01-01-Security.md | 2 +- _posts/07-02-01-Web-Application-Security.md | 2 +- _posts/07-03-01-Password-Hashing-with-Bcrypt.md | 2 +- _posts/07-04-01-Data-Filtering.md | 2 +- _posts/07-05-01-Configuration-Files.md | 2 +- _posts/07-06-01-Register-Globals.md | 2 +- _posts/07-07-01-Error-Reporting.md | 2 +- _posts/08-01-01-Testing.md | 2 +- _posts/08-02-01-Test-Driven-Development.md | 2 +- _posts/08-03-01-Behavior-Driven-Development.md | 2 +- _posts/08-04-01-Complementary-Testing-Tools.md | 2 +- _posts/09-01-01-Servers-and-Deployment.md | 2 +- _posts/09-02-01-Platform-as-a-Service.md | 2 +- _posts/09-03-01-Virtual-or-Dedicated-Servers.md | 2 +- _posts/09-04-01-Shared-Servers.md | 2 +- _posts/10-01-01-Caching.md | 2 +- _posts/10-02-01-Bytecode-Cache.md | 2 +- _posts/10-03-01-Object-Caching.md | 2 +- _posts/11-01-01-Resources.md | 2 +- _posts/11-02-01-Frameworks.md | 2 +- _posts/11-03-01-Components.md | 2 +- _posts/12-01-01-Community.md | 2 +- 42 files changed, 42 insertions(+), 42 deletions(-) diff --git a/_posts/01-01-01-Getting-Started.md b/_posts/01-01-01-Getting-Started.md index 31dd91e80..b3a75a0bf 100644 --- a/_posts/01-01-01-Getting-Started.md +++ b/_posts/01-01-01-Getting-Started.md @@ -1,2 +1,2 @@ -# Getting Started +# Getting Started {#getting_started_title} diff --git a/_posts/01-02-01-Use-the-Current-Stable-Version.md b/_posts/01-02-01-Use-the-Current-Stable-Version.md index c54a34e39..ccb0b3599 100644 --- a/_posts/01-02-01-Use-the-Current-Stable-Version.md +++ b/_posts/01-02-01-Use-the-Current-Stable-Version.md @@ -3,7 +3,7 @@ title: Use the Current Stable Version (5.4) isChild: true --- -## Use the Current Stable Version (5.4) +## Use the Current Stable Version (5.4) {#use_the_current_stable_version_54_title} 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. If you are looking for a function or it's usage, the documentation on the [php.net][php-docs] website will have the answer. diff --git a/_posts/01-03-01-Built-in-Web-Server.md b/_posts/01-03-01-Built-in-Web-Server.md index aa46c77f8..076a04ea2 100644 --- a/_posts/01-03-01-Built-in-Web-Server.md +++ b/_posts/01-03-01-Built-in-Web-Server.md @@ -3,7 +3,7 @@ title: Built-in Web Server isChild: true --- -## Built-in web server +## Built-in web server {#builtin_web_server_title} 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: diff --git a/_posts/01-04-01-Mac-Setup.md b/_posts/01-04-01-Mac-Setup.md index c646ce954..ae9157d55 100644 --- a/_posts/01-04-01-Mac-Setup.md +++ b/_posts/01-04-01-Mac-Setup.md @@ -2,7 +2,7 @@ isChild: true --- -## Mac Setup +## Mac Setup {#mac_setup_title} OSX comes prepackaged with PHP but it is normally a little behind the latest stable. Lion comes with PHP 5.3.6 and Mountain Lion has 5.3.10. diff --git a/_posts/01-05-01-Windows-Setup.md b/_posts/01-05-01-Windows-Setup.md index 237e86c60..351977368 100644 --- a/_posts/01-05-01-Windows-Setup.md +++ b/_posts/01-05-01-Windows-Setup.md @@ -2,7 +2,7 @@ isChild: true --- -## Windows Setup +## Windows Setup {#windows_setup_title} PHP is available in several ways for Windows. You can [download the binaries](php-downloads) and until recently you could use a '.msi' installer. The installer is no longer supported and stops at PHP 5.3.0. diff --git a/_posts/02-01-01-Code-Style-Guide.md b/_posts/02-01-01-Code-Style-Guide.md index 5196c9d07..7c20cdacf 100644 --- a/_posts/02-01-01-Code-Style-Guide.md +++ b/_posts/02-01-01-Code-Style-Guide.md @@ -1,4 +1,4 @@ -# Code Style Guide +# Code Style Guide {#code_style_guide_title} 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 diff --git a/_posts/03-01-01-Language-Highlights.md b/_posts/03-01-01-Language-Highlights.md index 7f662a602..9251ef3b0 100644 --- a/_posts/03-01-01-Language-Highlights.md +++ b/_posts/03-01-01-Language-Highlights.md @@ -1 +1 @@ -# Language Highlights +# Language Highlights {#language_highlights_title} diff --git a/_posts/03-02-01-Programming-Paradigms.md b/_posts/03-02-01-Programming-Paradigms.md index 39c67b624..57958d121 100644 --- a/_posts/03-02-01-Programming-Paradigms.md +++ b/_posts/03-02-01-Programming-Paradigms.md @@ -2,7 +2,7 @@ isChild: true --- -## Programming Paradigms +## Programming Paradigms {#programming_paradigms_title} 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 diff --git a/_posts/03-03-01-Namespaces.md b/_posts/03-03-01-Namespaces.md index 7a2d9217f..bc6eed8dd 100644 --- a/_posts/03-03-01-Namespaces.md +++ b/_posts/03-03-01-Namespaces.md @@ -2,7 +2,7 @@ isChild: true --- -## Namespaces +## Namespaces {#namespaces_title} 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. diff --git a/_posts/03-04-01-Standard-PHP-Library.md b/_posts/03-04-01-Standard-PHP-Library.md index 22f6a7149..6ad4caaa7 100644 --- a/_posts/03-04-01-Standard-PHP-Library.md +++ b/_posts/03-04-01-Standard-PHP-Library.md @@ -3,7 +3,7 @@ title: Standard PHP Library isChild: true --- -## Standard PHP Library +## Standard PHP Library {#standard_php_library_title} 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. diff --git a/_posts/03-05-01-Command-Line-Interface.md b/_posts/03-05-01-Command-Line-Interface.md index 8790591c8..9e844e9ff 100644 --- a/_posts/03-05-01-Command-Line-Interface.md +++ b/_posts/03-05-01-Command-Line-Interface.md @@ -2,7 +2,7 @@ isChild: true --- -## Command Line Interface +## Command Line Interface {#command_line_interface_title} 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. diff --git a/_posts/04-01-01-Dependency-Management.md b/_posts/04-01-01-Dependency-Management.md index 1c414c874..6937a7269 100644 --- a/_posts/04-01-01-Dependency-Management.md +++ b/_posts/04-01-01-Dependency-Management.md @@ -1,4 +1,4 @@ -# Dependency Management +# Dependency Management {#dependency_management_title} 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. diff --git a/_posts/04-02-01-Composer-and-Packagist.md b/_posts/04-02-01-Composer-and-Packagist.md index 93748661e..d80a72fa5 100644 --- a/_posts/04-02-01-Composer-and-Packagist.md +++ b/_posts/04-02-01-Composer-and-Packagist.md @@ -2,7 +2,7 @@ isChild: true --- -## Composer and Packagist +## Composer and Packagist {#composer_and_packagist_title} 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. diff --git a/_posts/04-03-01-PEAR.md b/_posts/04-03-01-PEAR.md index a6d162630..e0f019461 100644 --- a/_posts/04-03-01-PEAR.md +++ b/_posts/04-03-01-PEAR.md @@ -2,7 +2,7 @@ isChild: true --- -## PEAR +## PEAR {#pear_title} Another veteran package manager that many PHP developers enjoy is [PEAR][1]. It behaves much the same way, and is also worth researching for your projects. [Learn about PEAR][1]. diff --git a/_posts/05-01-01-Coding-Practices.md b/_posts/05-01-01-Coding-Practices.md index c5e80a383..eff0ab3e2 100644 --- a/_posts/05-01-01-Coding-Practices.md +++ b/_posts/05-01-01-Coding-Practices.md @@ -1 +1 @@ -# Coding Practices +# Coding Practices {#coding_practices_title} diff --git a/_posts/05-02-01-The-Basics.md b/_posts/05-02-01-The-Basics.md index 11d3000b9..1e73d6ea2 100644 --- a/_posts/05-02-01-The-Basics.md +++ b/_posts/05-02-01-The-Basics.md @@ -2,7 +2,7 @@ isChild: true --- -## The Basics +## The Basics {#the_basics_title} PHP is a vast language that allows coders of all levels the ability to produce code not only quickly, but efficiently. However while advancing through the language, we often forget the basics that we first learnt (or overlooked) in favor diff --git a/_posts/05-03-01-Date-and-Time.md b/_posts/05-03-01-Date-and-Time.md index 6adf1230f..e7af15918 100644 --- a/_posts/05-03-01-Date-and-Time.md +++ b/_posts/05-03-01-Date-and-Time.md @@ -2,7 +2,7 @@ isChild: true --- -## Date and Time +## Date and Time {#date_and_time_title} PHP has a class named DateTime to help you when reading, writing, comparing or calculating with date and time. There are many date and time related functions in PHP besides DateTime, but it provides nice object-oriented interface to most diff --git a/_posts/05-04-01-Design-Patterns.md b/_posts/05-04-01-Design-Patterns.md index 211049d78..eaf7f0eb9 100644 --- a/_posts/05-04-01-Design-Patterns.md +++ b/_posts/05-04-01-Design-Patterns.md @@ -2,7 +2,7 @@ isChild: true --- -## Design Patterns +## Design Patterns {#design_patterns_title} When you are building your application it is helpful to use common patterns in your code and common patterns for the overall structure of your project. Using common patterns is helpful because it makes it much easier to manage your code diff --git a/_posts/05-05-01-Exceptions.md b/_posts/05-05-01-Exceptions.md index 254d05f22..67262a797 100644 --- a/_posts/05-05-01-Exceptions.md +++ b/_posts/05-05-01-Exceptions.md @@ -2,7 +2,7 @@ isChild: true --- -## Exceptions +## Exceptions {#exceptions_title} Exceptions are a standard part of most popular programming languages, but they are often overlooked by PHP programmers. Languages like Ruby are extremely Exception heavy, so whenever something goes wrong such as a HTTP request failing, or diff --git a/_posts/06-01-01-Databases.md b/_posts/06-01-01-Databases.md index 6bcf4be4c..930297c9e 100644 --- a/_posts/06-01-01-Databases.md +++ b/_posts/06-01-01-Databases.md @@ -2,7 +2,7 @@ title: Databases --- -# Databases +# Databases {#databases_title} Many times your PHP code will use a database to persist information. You have a few options to connect and interact with your database. The recommended option _until PHP 5.1.0_ was to use native drivers such as [mysql][mysql], [mysqli][mysqli], [pgsql][pgsql], etc. diff --git a/_posts/07-01-01-Security.md b/_posts/07-01-01-Security.md index 8dbb2f9bc..9c0b0007a 100644 --- a/_posts/07-01-01-Security.md +++ b/_posts/07-01-01-Security.md @@ -1 +1 @@ -# Security +# Security {#security_title} diff --git a/_posts/07-02-01-Web-Application-Security.md b/_posts/07-02-01-Web-Application-Security.md index f84dfad5d..91709574e 100644 --- a/_posts/07-02-01-Web-Application-Security.md +++ b/_posts/07-02-01-Web-Application-Security.md @@ -2,7 +2,7 @@ isChild: true --- -## Web Application Security +## Web Application Security {#web_application_security_title} 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. diff --git a/_posts/07-03-01-Password-Hashing-with-Bcrypt.md b/_posts/07-03-01-Password-Hashing-with-Bcrypt.md index be9d3cc62..bb8471c29 100644 --- a/_posts/07-03-01-Password-Hashing-with-Bcrypt.md +++ b/_posts/07-03-01-Password-Hashing-with-Bcrypt.md @@ -2,7 +2,7 @@ isChild: true --- -## Password Hashing with Bcrypt +## Password Hashing with Bcrypt {#password_hashing_with_bcrypt_title} 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. diff --git a/_posts/07-04-01-Data-Filtering.md b/_posts/07-04-01-Data-Filtering.md index d3ebe41d0..7dcdcdd77 100644 --- a/_posts/07-04-01-Data-Filtering.md +++ b/_posts/07-04-01-Data-Filtering.md @@ -2,7 +2,7 @@ isChild: true --- -## Data Filtering +## Data Filtering {#data_filtering_title} Never ever (ever) trust foreign input introduced to your PHP code. Always sanitize and validate foreign input before using it in code. The `filter_var` and `filter_input` functions can sanitize text and validate text formats (e.g. diff --git a/_posts/07-05-01-Configuration-Files.md b/_posts/07-05-01-Configuration-Files.md index 9215a3e67..2d27e6b7b 100644 --- a/_posts/07-05-01-Configuration-Files.md +++ b/_posts/07-05-01-Configuration-Files.md @@ -2,7 +2,7 @@ isChild: true --- -## Configuration Files +## Configuration Files {#configuration_files_title} When creating configuration files for your applications, best practices recommend that one of the following methods be followed: diff --git a/_posts/07-06-01-Register-Globals.md b/_posts/07-06-01-Register-Globals.md index 19bdc8c5e..d7c8268a9 100644 --- a/_posts/07-06-01-Register-Globals.md +++ b/_posts/07-06-01-Register-Globals.md @@ -2,7 +2,7 @@ isChild: true --- -## Register Globals +## Register Globals {#register_globals_title} **NOTE:** As of PHP 5.4.0 the `register_globals` setting has been removed and can no longer be used. This is only included as a warning for anyone in the process of upgrading a legacy application. diff --git a/_posts/07-07-01-Error-Reporting.md b/_posts/07-07-01-Error-Reporting.md index 4a9090861..3aaae6a37 100644 --- a/_posts/07-07-01-Error-Reporting.md +++ b/_posts/07-07-01-Error-Reporting.md @@ -2,7 +2,7 @@ isChild: true --- -## Error Reporting +## Error Reporting {#error_reporting_title} Error logging can be useful in finding the problem spots in your application, but it can also expose information about the structure of your application to the outside world. To effectively protect your application from issues that could diff --git a/_posts/08-01-01-Testing.md b/_posts/08-01-01-Testing.md index b2e74ae70..2eac35cd7 100644 --- a/_posts/08-01-01-Testing.md +++ b/_posts/08-01-01-Testing.md @@ -1,4 +1,4 @@ -# Testing +# Testing {#testing_title} 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 diff --git a/_posts/08-02-01-Test-Driven-Development.md b/_posts/08-02-01-Test-Driven-Development.md index 449855587..19302c37a 100644 --- a/_posts/08-02-01-Test-Driven-Development.md +++ b/_posts/08-02-01-Test-Driven-Development.md @@ -2,7 +2,7 @@ isChild: true --- -## Test Driven Development +## Test Driven Development {#test_driven_development_title} From [Wikipedia](http://en.wikipedia.org/wiki/Test-driven_development): diff --git a/_posts/08-03-01-Behavior-Driven-Development.md b/_posts/08-03-01-Behavior-Driven-Development.md index 253c82c88..9fa148c9d 100644 --- a/_posts/08-03-01-Behavior-Driven-Development.md +++ b/_posts/08-03-01-Behavior-Driven-Development.md @@ -2,7 +2,7 @@ isChild: true --- -## Behavior Driven Development +## Behavior Driven Development {#behavior_driven_development_title} There are two different types of Behavior-Driven Development (BDD): SpecBDD and StoryBDD. SpecBDD focuses on technical behavior or code, while StoryBDD focuses on business or feature behaviors or interactions. PHP has frameworks for both types of BDD. diff --git a/_posts/08-04-01-Complementary-Testing-Tools.md b/_posts/08-04-01-Complementary-Testing-Tools.md index 7abc24b78..709d10acb 100644 --- a/_posts/08-04-01-Complementary-Testing-Tools.md +++ b/_posts/08-04-01-Complementary-Testing-Tools.md @@ -2,7 +2,7 @@ isChild: true --- -## Complementary Testing Tools +## Complementary Testing Tools {#complementary_testing_tools_title} Besides individual testing and behavior driven frameworks, there are also a number of generic frameworks and helper libraries useful for any preferred approach taken. diff --git a/_posts/09-01-01-Servers-and-Deployment.md b/_posts/09-01-01-Servers-and-Deployment.md index e51a620b1..700ca16e6 100644 --- a/_posts/09-01-01-Servers-and-Deployment.md +++ b/_posts/09-01-01-Servers-and-Deployment.md @@ -1,3 +1,3 @@ -# Servers and Deployment +# Servers and Deployment {#servers_and_deployment_title} PHP applications can be deployed and run on production web servers in a number of ways. diff --git a/_posts/09-02-01-Platform-as-a-Service.md b/_posts/09-02-01-Platform-as-a-Service.md index ea9282ffa..e2aa16635 100644 --- a/_posts/09-02-01-Platform-as-a-Service.md +++ b/_posts/09-02-01-Platform-as-a-Service.md @@ -3,7 +3,7 @@ title: Platform as a Service (PaaS) isChild: true --- -## Platform as a Service (PaaS) +## Platform as a Service (PaaS) {#platform_as_a_service_paas_title} PaaS provides the system and network architecture necessary to run PHP applications on the web. This means little to no configuration for launching PHP applications or PHP frameworks. diff --git a/_posts/09-03-01-Virtual-or-Dedicated-Servers.md b/_posts/09-03-01-Virtual-or-Dedicated-Servers.md index 92aef5cf3..2c1e72550 100644 --- a/_posts/09-03-01-Virtual-or-Dedicated-Servers.md +++ b/_posts/09-03-01-Virtual-or-Dedicated-Servers.md @@ -2,7 +2,7 @@ isChild: true --- -## Virtual or Dedicated Servers +## Virtual or Dedicated Servers {#virtual_or_dedicated_servers_title} 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. diff --git a/_posts/09-04-01-Shared-Servers.md b/_posts/09-04-01-Shared-Servers.md index f1ffedb92..3334bc893 100644 --- a/_posts/09-04-01-Shared-Servers.md +++ b/_posts/09-04-01-Shared-Servers.md @@ -2,6 +2,6 @@ isChild: true --- -## Shared Servers +## Shared Servers {#shared_servers_title} 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. diff --git a/_posts/10-01-01-Caching.md b/_posts/10-01-01-Caching.md index cdcfdaeeb..b09726b4a 100644 --- a/_posts/10-01-01-Caching.md +++ b/_posts/10-01-01-Caching.md @@ -1,4 +1,4 @@ -# Caching +# Caching {#caching_title} PHP is pretty quick by itself, but bottlenecks can arise when you make remote connections, load files, etc. Thankfully, there are various tools available to speed up certain parts of your application, or reduce the number of times these various time consuming tasks need to run. \ No newline at end of file diff --git a/_posts/10-02-01-Bytecode-Cache.md b/_posts/10-02-01-Bytecode-Cache.md index 432b063c6..eaeaffcb8 100644 --- a/_posts/10-02-01-Bytecode-Cache.md +++ b/_posts/10-02-01-Bytecode-Cache.md @@ -2,7 +2,7 @@ isChild: true --- -## Bytecode Cache +## Bytecode Cache {#bytecode_cache_title} When a PHP file is executed, under the hood it is first compiled to bytecode (also known as opcode) and, only then, the bytecode is executed. If a PHP file is not modified, the bytecode will always be the same. This means that the compilation step is a waste of CPU resources. diff --git a/_posts/10-03-01-Object-Caching.md b/_posts/10-03-01-Object-Caching.md index b2966895e..df9420df6 100644 --- a/_posts/10-03-01-Object-Caching.md +++ b/_posts/10-03-01-Object-Caching.md @@ -2,7 +2,7 @@ isChild: true --- -## Object Caching +## Object Caching {#object_caching_title} There are times when it can be beneficial to cache individual objects in your code, such as with data that is expensive to get or database calls where the result is unlikely to change. You can use object caching software to hold these diff --git a/_posts/11-01-01-Resources.md b/_posts/11-01-01-Resources.md index 94810412e..e06c56fae 100644 --- a/_posts/11-01-01-Resources.md +++ b/_posts/11-01-01-Resources.md @@ -1,4 +1,4 @@ -# Resources +# Resources {#resources_title} ## From the Source diff --git a/_posts/11-02-01-Frameworks.md b/_posts/11-02-01-Frameworks.md index 86ed9db3c..11e96f252 100644 --- a/_posts/11-02-01-Frameworks.md +++ b/_posts/11-02-01-Frameworks.md @@ -2,7 +2,7 @@ isChild: true --- -## Frameworks +## Frameworks {#frameworks_title} 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. diff --git a/_posts/11-03-01-Components.md b/_posts/11-03-01-Components.md index a416666b4..ffc058d1a 100644 --- a/_posts/11-03-01-Components.md +++ b/_posts/11-03-01-Components.md @@ -2,7 +2,7 @@ isChild: true --- -## Components +## Components {#components_title} As mentioned above "Components" are another approach to the common goal of creating, distributing and implementing shared code. Various component repositories exist, the main two of which are: diff --git a/_posts/12-01-01-Community.md b/_posts/12-01-01-Community.md index 3b876685c..3986e7f1d 100644 --- a/_posts/12-01-01-Community.md +++ b/_posts/12-01-01-Community.md @@ -1,4 +1,4 @@ -# Community +# Community {#community_title} The PHP community is as diverse as it is large, and it's members are ready and willing to support new PHP programmers. You should consider joining your local PHP user group (PUG) or attending larger PHP conferences to learn more about the best practices shown here. You can also hang out on IRC in the #phpc channel on irc.freenode.com and follow the [@phpc][phpc-twitter] twitter account. Get out there, meet new developers, learn new topics and, above all, make new friends. From a53aae0c91445d87ec17aaa233d472cb7fb7ad89 Mon Sep 17 00:00:00 2001 From: Julien BIANCHI Date: Mon, 3 Sep 2012 10:18:58 +0300 Subject: [PATCH 037/843] Add atoum to the list of available PHP unit test framework --- _posts/08-02-01-Test-Driven-Development.md | 1 + 1 file changed, 1 insertion(+) diff --git a/_posts/08-02-01-Test-Driven-Development.md b/_posts/08-02-01-Test-Driven-Development.md index 449855587..07b549d1a 100644 --- a/_posts/08-02-01-Test-Driven-Development.md +++ b/_posts/08-02-01-Test-Driven-Development.md @@ -33,6 +33,7 @@ applications, but there are several alternatives * [SimpleTest](http://simpletest.org) * [Enhance PHP](http://www.enhance-php.com/) * [PUnit](http://punit.smf.me.uk/) +* [atoum](https://github.com/mageekguy/atoum) ### Integration Testing From 4c6b2b54f300c9223dbd96146047874325279d80 Mon Sep 17 00:00:00 2001 From: Christoph Date: Sun, 9 Sep 2012 18:22:18 +0200 Subject: [PATCH 038/843] added note about fastcgi and APC --- _posts/10-03-01-Object-Caching.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/_posts/10-03-01-Object-Caching.md b/_posts/10-03-01-Object-Caching.md index b2966895e..9ce54cda5 100644 --- a/_posts/10-03-01-Object-Caching.md +++ b/_posts/10-03-01-Object-Caching.md @@ -19,6 +19,10 @@ one real limitation of APC is that it is tied to the server it's installed on. M as a separate service and can be accessed across the network, meaning that you can store objects in a hyper-fast data store in a central location and many different systems can pull from it. +Note that when running PHP as a (Fast-)CGI application inside your webserver, every PHP processes will have its own +cache, i.e. APC data is not shared between your worker processes. In these cases, you might want to consider using +memcached instead, as it's not tied to the PHP processes. + In a networked configuration APC will usually outperform memcached in terms of access speed, but memcached will be able to scale up faster and further. If you do not expect to have multiple servers running your application, or do not need the extra features that memcached offers then APC is probably your best choice for object caching. From ca9e844a3a7cecfb5ac59e0c837db1952977b5e3 Mon Sep 17 00:00:00 2001 From: Gerard Roche Date: Mon, 17 Sep 2012 14:46:56 +0200 Subject: [PATCH 039/843] Update _posts/07-07-01-Error-Reporting.md This is a corrected version of pull request https://github.com/codeguy/php-the-right-way/pull/164 --- _posts/07-07-01-Error-Reporting.md | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/_posts/07-07-01-Error-Reporting.md b/_posts/07-07-01-Error-Reporting.md index 4a9090861..ec0750fc8 100644 --- a/_posts/07-07-01-Error-Reporting.md +++ b/_posts/07-07-01-Error-Reporting.md @@ -14,9 +14,24 @@ production (live). To show errors in your development environment, configure the following settings in your `php.ini`: - display_errors: On -- error_reporting: E_ALL +- error_reporting: -1 - log_errors: On +From [php.net](http://php.net/manual/function.error-reporting.php): + +> Passing in the value -1 will show every possible error, even when new levels and constants are added in future PHP versions. The E_ALL constant also behaves this way as of PHP 5.4. + +The `E_STRICT` error level constant was introduced in 5.3.0 and is not +part of `E_ALL`, however it became part of `E_ALL` in 5.4.0. What does this mean? +In terms of reporting every possible error in version 5.3 it means you must +use either `-1` or `E_ALL | E_STRICT`. + +**Reporting Every Possibly Error by PHP Version** + +* < 5.3 `-1` or `E_ALL` +* 5.3 `-1` or `E_ALL | E_STRICT` +* > 5.3 `-1` or `E_ALL` + ### Production To hide the errors on your production environment, configure your `php.ini` as: From 88754f8173398695bf6fdb00acc9824eb3c7e583 Mon Sep 17 00:00:00 2001 From: iflista Date: Thu, 20 Sep 2012 16:25:47 +0300 Subject: [PATCH 040/843] Added Ukrainian Translation --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 4a44ccc16..e003a0662 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,7 @@ developers know where to find good information! * [English](http://www.phptherightway.com) * [Chinese](http://wulijun.github.com/php-the-right-way) +* [Ukrainian](http://iflista.github.com/php-the-right-way) ### Translations From edd362fb87b4351c888161e5e8454b1b6a7a504c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rados=C5=82aw=20Benkel?= Date: Sun, 23 Sep 2012 23:00:20 +0200 Subject: [PATCH 041/843] Added short info about writing identifiers in English --- _posts/02-01-01-Code-Style-Guide.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/_posts/02-01-01-Code-Style-Guide.md b/_posts/02-01-01-Code-Style-Guide.md index 5196c9d07..284829775 100644 --- a/_posts/02-01-01-Code-Style-Guide.md +++ b/_posts/02-01-01-Code-Style-Guide.md @@ -22,6 +22,8 @@ You can use the [phpcs-psr][phpcs-psr] sniff for [PHP_CodeSniffer][phpcs] to che Use Fabien Potencier's [PHP Coding Standards Fixer][phpcsfixer] to automatically modify your code syntax so that it conforms with these standards, saving you from fixing each problem by hand. +English is preferred for all symbol names and code infrastructure. Comments may be written in any language easily readable by all current and future parties who may be working on the codebase. + [fig]: http://www.php-fig.org/ [psr0]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md [psr1]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-1-basic-coding-standard.md @@ -29,3 +31,4 @@ conforms with these standards, saving you from fixing each problem by hand. [phpcs]: http://pear.php.net/package/PHP_CodeSniffer/ [phpcs-psr]: https://github.com/klaussilveira/phpcs-psr [phpcsfixer]: http://cs.sensiolabs.org/ + From 526ecf8f74720e80383659e70ae4e4b8309f5b8f Mon Sep 17 00:00:00 2001 From: iflista Date: Fri, 28 Sep 2012 21:32:33 +0300 Subject: [PATCH 042/843] Update Ukrainian Translation --- _includes/welcome.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_includes/welcome.md b/_includes/welcome.md index 738505ccc..a1acf98fc 100644 --- a/_includes/welcome.md +++ b/_includes/welcome.md @@ -15,7 +15,7 @@ _PHP: The Right Way_ is (or soon will be) translated into many different languag * Portuguese (Coming Soon) * Russian (Coming Soon) * [Spanish](http://es.phptherightway.com) -* Ukrainian (Coming Soon) +* [Ukrainian](http://iflista.github.com/php-the-right-way/) ## Disclaimer From 27fff934292a1ff1bd36d8035242ca5a2e885fdd Mon Sep 17 00:00:00 2001 From: iflista Date: Tue, 9 Oct 2012 17:36:31 +0300 Subject: [PATCH 043/843] Updated page with link to Ukrainian Translation --- _includes/welcome.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_includes/welcome.md b/_includes/welcome.md index 738505ccc..a1acf98fc 100644 --- a/_includes/welcome.md +++ b/_includes/welcome.md @@ -15,7 +15,7 @@ _PHP: The Right Way_ is (or soon will be) translated into many different languag * Portuguese (Coming Soon) * Russian (Coming Soon) * [Spanish](http://es.phptherightway.com) -* Ukrainian (Coming Soon) +* [Ukrainian](http://iflista.github.com/php-the-right-way/) ## Disclaimer From 2be210a68755a5318c3c542dd56e1ba5b4c81b78 Mon Sep 17 00:00:00 2001 From: Tom de Bruin Date: Thu, 11 Oct 2012 05:17:06 +0100 Subject: [PATCH 044/843] Corrected ternary operator syntax --- pages/The-Basics.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pages/The-Basics.md b/pages/The-Basics.md index 7b2e8937a..601945856 100644 --- a/pages/The-Basics.md +++ b/pages/The-Basics.md @@ -293,12 +293,17 @@ $b = 10; echo ($a) ? ($a == 5) ? 'yay' : 'nay' : ($b == 10) ? 'excessive' : ':('; // excess nesting, sacrificing readability {% endhighlight %} -Ternary operators also have their limitations and cannot be used to 'return' a value. +To 'return' a value with ternary operators use the correct syntax. {% highlight php %} Date: Fri, 12 Oct 2012 09:09:21 +0100 Subject: [PATCH 045/843] Changed example return values At request of Phil Sturgeon. --- pages/The-Basics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/The-Basics.md b/pages/The-Basics.md index 601945856..68d425c01 100644 --- a/pages/The-Basics.md +++ b/pages/The-Basics.md @@ -303,7 +303,7 @@ echo ($a == 5) ? return true : return false; // this example will output an e vs. $a = 5; -return ($a == 5) ? true : false; // this example will return true +return ($a == 5) ? 'yay' : 'nope'; // this example will return true {% endhighlight %} * [Ternary operators](http://php.net/manual/en/language.operators.comparison.php) From c95fc4250ec035cf1b4c063c85114a430b56e202 Mon Sep 17 00:00:00 2001 From: Tom de Bruin Date: Fri, 12 Oct 2012 09:13:43 +0100 Subject: [PATCH 046/843] It's true, it will return 'yay'. --- pages/The-Basics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/The-Basics.md b/pages/The-Basics.md index 68d425c01..092ce5820 100644 --- a/pages/The-Basics.md +++ b/pages/The-Basics.md @@ -303,7 +303,7 @@ echo ($a == 5) ? return true : return false; // this example will output an e vs. $a = 5; -return ($a == 5) ? 'yay' : 'nope'; // this example will return true +return ($a == 5) ? 'yay' : 'nope'; // this example will return 'yay' {% endhighlight %} * [Ternary operators](http://php.net/manual/en/language.operators.comparison.php) From d6a150eb218e2ce48465032a4ed735362736c8ef Mon Sep 17 00:00:00 2001 From: Vincent Tunru Date: Sun, 14 Oct 2012 15:33:39 +0200 Subject: [PATCH 047/843] Removed "too" from "also ... too". --- _posts/03-05-01-Command-Line-Interface.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_posts/03-05-01-Command-Line-Interface.md b/_posts/03-05-01-Command-Line-Interface.md index 8790591c8..020b121cc 100644 --- a/_posts/03-05-01-Command-Line-Interface.md +++ b/_posts/03-05-01-Command-Line-Interface.md @@ -4,7 +4,7 @@ isChild: true ## 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. +PHP was created primarily to write web applications, but it's also useful for scripting command line interface (CLI) programs. 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! @@ -53,4 +53,4 @@ Hello, world [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 -[exit-codes]: http://www.gsp.com/cgi-bin/man.cgi?section=3&topic=sysexits \ No newline at end of file +[exit-codes]: http://www.gsp.com/cgi-bin/man.cgi?section=3&topic=sysexits From f1e806c941480020236b8484e9f0ec14b5b5adb0 Mon Sep 17 00:00:00 2001 From: Pontus Alexander Date: Mon, 15 Oct 2012 09:27:03 +0200 Subject: [PATCH 048/843] Improves wording on the Cross-Site Scripting segment --- _posts/07-04-01-Data-Filtering.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/_posts/07-04-01-Data-Filtering.md b/_posts/07-04-01-Data-Filtering.md index 7dcdcdd77..e262aaa68 100644 --- a/_posts/07-04-01-Data-Filtering.md +++ b/_posts/07-04-01-Data-Filtering.md @@ -19,8 +19,10 @@ the data is filtered properly and can it be trusted. Data may be _filtered_ differently based on its purpose. For example, when unfiltered foreign input is passed into HTML page output, it can execute HTML and JavaScript on your site! This is known as Cross-Site -Scripting (XSS) and can be a very dangerous attack. One way to avoid XSS is to sanitize all HTML tags -in the input by removing tags or escaping them into HTML entities. +Scripting (XSS) and can be a very dangerous attack. One way to avoid XSS is to sanitize all user-generated +data before outputting it to your page by removing HTML tags with the `strip_tags` function or escaping +characters with special meaning into their respective HTML entities with the `htmlentities` +or `htmlspecialchars` functions. Another example is passing options to be executed on the command line. This can be extremely dangerous (and is usually a bad idea), but you can use the built-in `escapeshellarg` function to sanitize the executed From ced10a36c3424683463800852bb2ad3d2f1cb853 Mon Sep 17 00:00:00 2001 From: Phil Sturgeon Date: Mon, 15 Oct 2012 09:39:18 +0200 Subject: [PATCH 049/843] Never say "all" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I wrote previously about the PSR's that "They all add on to the recommendation before" which is of course entirely correct at the time of writing, but will not be the case going forwards as HTTP and Caching recommendations (or whatever happens next) become PSR-3, 4, 5, 345, etc. --- _posts/02-01-01-Code-Style-Guide.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_posts/02-01-01-Code-Style-Guide.md b/_posts/02-01-01-Code-Style-Guide.md index 2e438d842..c41013402 100644 --- a/_posts/02-01-01-Code-Style-Guide.md +++ b/_posts/02-01-01-Code-Style-Guide.md @@ -11,8 +11,8 @@ these recommendations are merely a set of rules that some projects like Drupal, 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. +read and work with your code, and applications that implement the components can have consistency even when working with +lots of third-party code. The first few recommendations are designed to be a super-set of the previews recomendation. * [Read about PSR-0][psr0] * [Read about PSR-1][psr1] From ff1427063059ae4bf5f265392779887a16619b16 Mon Sep 17 00:00:00 2001 From: Phil Sturgeon Date: Tue, 16 Oct 2012 22:17:53 -0300 Subject: [PATCH 050/843] Autocorrect fail --- _posts/02-01-01-Code-Style-Guide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/02-01-01-Code-Style-Guide.md b/_posts/02-01-01-Code-Style-Guide.md index c41013402..f5a501dcb 100644 --- a/_posts/02-01-01-Code-Style-Guide.md +++ b/_posts/02-01-01-Code-Style-Guide.md @@ -12,7 +12,7 @@ Lithium, etc are starting to adopt. You can use them for your own projects, or c 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, and applications that implement the components can have consistency even when working with -lots of third-party code. The first few recommendations are designed to be a super-set of the previews recomendation. +lots of third-party code. The first few recommendations are designed to be a super-set of the previous recomendation. * [Read about PSR-0][psr0] * [Read about PSR-1][psr1] From 8feb9338ac47dc5a4c30fa5987b66d3834c2af5d Mon Sep 17 00:00:00 2001 From: Phil Sturgeon Date: Tue, 23 Oct 2012 16:01:27 -0300 Subject: [PATCH 051/843] Formatting issue --- _posts/07-07-01-Error-Reporting.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/07-07-01-Error-Reporting.md b/_posts/07-07-01-Error-Reporting.md index f13c947e5..6d4fd40e8 100644 --- a/_posts/07-07-01-Error-Reporting.md +++ b/_posts/07-07-01-Error-Reporting.md @@ -29,7 +29,7 @@ use either `-1` or `E_ALL | E_STRICT`. **Reporting Every Possibly Error by PHP Version** * < 5.3 `-1` or `E_ALL` -* 5.3 `-1` or `E_ALL | E_STRICT` +* 5.3 `-1` or `E_ALL | E_STRICT` * > 5.3 `-1` or `E_ALL` ### Production From 6e97c680e0a6436972f353a866c16b8736841e7b Mon Sep 17 00:00:00 2001 From: Phil Sturgeon Date: Tue, 23 Oct 2012 16:03:38 -0300 Subject: [PATCH 052/843] Another shot at formatting Sorry guys no local copy and going for the speed-fix. --- _posts/07-07-01-Error-Reporting.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/_posts/07-07-01-Error-Reporting.md b/_posts/07-07-01-Error-Reporting.md index 6d4fd40e8..1eee78dd3 100644 --- a/_posts/07-07-01-Error-Reporting.md +++ b/_posts/07-07-01-Error-Reporting.md @@ -28,9 +28,9 @@ use either `-1` or `E_ALL | E_STRICT`. **Reporting Every Possibly Error by PHP Version** -* < 5.3 `-1` or `E_ALL` -* 5.3 `-1` or `E_ALL | E_STRICT` -* > 5.3 `-1` or `E_ALL` +* < 5.3 `-1` or `E_ALL` +*   5.3 `-1` or `E_ALL | E_STRICT` +* > 5.3 `-1` or `E_ALL` ### Production From afceb6ae5881ceb8610b3236fd94a9378b0291ed Mon Sep 17 00:00:00 2001 From: Kevin Boyd Date: Wed, 24 Oct 2012 13:50:47 -0700 Subject: [PATCH 053/843] Initial attempt at XDebug The Right Way --- _posts/03-06-01-XDebug.md | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 _posts/03-06-01-XDebug.md diff --git a/_posts/03-06-01-XDebug.md b/_posts/03-06-01-XDebug.md new file mode 100644 index 000000000..ce7852010 --- /dev/null +++ b/_posts/03-06-01-XDebug.md @@ -0,0 +1,35 @@ +--- +isChild: true +--- + +## XDebug {#xdebug_title} + +One of the most useful tools in software development is a proper debugger. It allows you to trace the execution of your +code and monitor the contents of the stack. XDebug, PHP's debugger, can be utilized by various IDEs to provide +Breakpoints and stack inspection. It can also allow tools like PHPUnit and KCacheGrind to perform code coverage analysis +and code profiling. + +If you find yourself in a bind, willing to resort to var_dump/print_r, and you still can't find the solution - maybe you +need to use the debugger. + +[Installing XDebug][xdebug-install] can be tricky, but one of its most important features is "Remote Debugging" - if you +develop code locally and then test it inside a VM or on another server, Remote Debugging is the feature that you will +want to enable right away. + +Traditionally, you will modify your Apache VHost or .htaccess file with these values: + + php_value xdebug.remote_host=192.168.?.? + php_value xdebug.remote_port=9000 + +The "remote host" and "remote port" will correspond to your local computer and the port that you configure your IDE to +listen on. Then it's just a matter of putting your IDE into "listen for connections" mode, and loading the URL: + + http://your-website.example.com/index.php?XDEBUG_SESSION_START=1 + +Your IDE will now intercept the current state as the script executes, allowing you to set breakpoints and probe the +values in memory. + + * [Learn more about XDebug][xdebug-docs] + +[xdebug-docs]: http://xdebug.org/docs/ +[xdebug-install]: http://xdebug.org/docs/install \ No newline at end of file From 854d87a110eab861daeb64907e03ed6cefc940a8 Mon Sep 17 00:00:00 2001 From: coderabbi Date: Mon, 29 Oct 2012 17:33:15 -0300 Subject: [PATCH 054/843] Edited for Grammar & Style --- pages/Functional-Programming.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/pages/Functional-Programming.md b/pages/Functional-Programming.md index 4ff3ae07a..6d129c3de 100644 --- a/pages/Functional-Programming.md +++ b/pages/Functional-Programming.md @@ -5,19 +5,19 @@ title: Functional Programming in PHP # Functional Programming in PHP -PHP supports first-class function, meaning that a function can be assigned to a variable. Both user defined and built-in +PHP supports first-class functions, meaning that a function can be assigned to a variable. Both user-defined and built-in functions can be referenced by a variable and invoked dynamically. Functions can be passed as arguments to other -functions (feature called Higher-order functions) and function can return other functions. +functions (a feature called higher-order functions) and a function can return other functions. -Recursion, a feature that allows a function to call itself is supported by the language, but most of the PHP code focus -on iteration. +Recursion, a feature that allows a function to call itself, is supported by the language, but most of the PHP code focus +is on iteration. -New anonymous functions (with support for closures) are present since PHP 5.3 (2009). +Anonymous functions (with support for closures) have been present since PHP 5.3 (2009). PHP 5.4 added the ability to bind closures to an object's scope and also improved support for callables such that they can be used interchangeably with anonymous functions in almost all cases. -The most common usage of higher-order functions is when implementing a strategy pattern. Built-in `array_filter` +The most common usage of higher-order functions is when implementing a strategy pattern. The built-in `array_filter` function asks both for the input array (data) and a function (a strategy or a callback) used as a filter function on each array item. @@ -41,7 +41,7 @@ $output = array_filter($input, function($item) { print_r($output); {% endhighlight %} -Closure is an anonymous function that can access variables imported from the outside scope without using any global +A closure is an anonymous function that can access variables imported from the outside scope without using any global variables. Theoretically, a closure is a function with some arguments closed (e.g. fixed) by the environment when it is defined. Closures can work around variable scope restrictions in a clean way. @@ -75,7 +75,7 @@ Each filter function in the family accepts only elements greater than some minim `criteria_greater_than` is called). Early binding is used by default for importing `$min` variable into the created function. For true closures with late -binding one should use a reference when importing. Imagine a templating or input validation libraries, where closure is +binding one should use a reference when importing. Imagine a templating or input validation library, where closure is defined to capture variables in scope and access them later when the anonymous function is evaluated. * [Read about Anonymous functions][anonymous-functions] From d39c1922b142bb5b77981fcef8fc6885cc08fdbe Mon Sep 17 00:00:00 2001 From: Andrew Berry Date: Mon, 5 Nov 2012 15:34:17 -0500 Subject: [PATCH 055/843] Use HTTPS when downloading composer to prevent MITM attacks. --- _posts/04-02-01-Composer-and-Packagist.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_posts/04-02-01-Composer-and-Packagist.md b/_posts/04-02-01-Composer-and-Packagist.md index d80a72fa5..0fbae9fc4 100644 --- a/_posts/04-02-01-Composer-and-Packagist.md +++ b/_posts/04-02-01-Composer-and-Packagist.md @@ -12,7 +12,7 @@ There are already a lot of PHP libraries that are compatible with Composer, read 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 + curl -s https://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. @@ -28,7 +28,7 @@ Manually installing composer is an advanced technique; however, there are variou 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 + curl -s https://getcomposer.org/composer.phar -o $HOME/local/bin/composer chmod +x $HOME/local/bin/composer The path `$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. From 9ac9d23a5a381aa41ae2c0783f30a952c25d7fa7 Mon Sep 17 00:00:00 2001 From: Rogerio Prado de Jesus Date: Tue, 6 Nov 2012 00:47:20 -0200 Subject: [PATCH 056/843] Include link to portuguese translation in README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index e003a0662..d4bbe964e 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,7 @@ developers know where to find good information! * [English](http://www.phptherightway.com) * [Chinese](http://wulijun.github.com/php-the-right-way) * [Ukrainian](http://iflista.github.com/php-the-right-way) +* [Portuguese](http://br.phptherightway.com/) ### Translations From 5e13a57660d0cfad317af4aa3b8b4bd25ef23309 Mon Sep 17 00:00:00 2001 From: Rogerio Prado de Jesus Date: Tue, 6 Nov 2012 00:50:16 -0200 Subject: [PATCH 057/843] Update link to portuguese translation in welcome.md --- _includes/welcome.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_includes/welcome.md b/_includes/welcome.md index a1acf98fc..eaa0a6474 100644 --- a/_includes/welcome.md +++ b/_includes/welcome.md @@ -12,7 +12,7 @@ _PHP: The Right Way_ is (or soon will be) translated into many different languag * [Chinese](http://wulijun.github.com/php-the-right-way) * [Japanese](http://ja.phptherightway.com) * Polish (Coming Soon) -* Portuguese (Coming Soon) +* [Portuguese](http://br.phptherightway.com/) * Russian (Coming Soon) * [Spanish](http://es.phptherightway.com) * [Ukrainian](http://iflista.github.com/php-the-right-way/) From 1a44f505203d1d85aacf0fd9123f1d1abffe20ec Mon Sep 17 00:00:00 2001 From: Markus Hausammann Date: Wed, 14 Nov 2012 18:57:31 +0200 Subject: [PATCH 058/843] new chapter about building, deployment and CI --- _posts/09-05-01-Building your Application.md | 95 ++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 _posts/09-05-01-Building your Application.md diff --git a/_posts/09-05-01-Building your Application.md b/_posts/09-05-01-Building your Application.md new file mode 100644 index 000000000..da039b355 --- /dev/null +++ b/_posts/09-05-01-Building your Application.md @@ -0,0 +1,95 @@ +--- +isChild: true +--- + +## Building and Deploying your Application {#build_title} + +If you find yourself doing manual database schema changes or running your tests manually before updating your files (manually), think twice! With every additional manual task needed to deploy a new version of your app, the chances for potentially fatal mistakes increase. Whether you're dealing with a simple update, a comprehensive build process or even a continuous integration strategy, build tools are your friend. + +### Control your deployment with Phing + +With [Phing](http://www.phing.info/) you can control your packaging, deployment or testing process from within a simple XML build file. Phing provides a rich set of tasks usually needed to install or update a web app and can be extended with additional custom tasks (written in PHP). + +Example of a Phing script (build.xml): + +{% highlight xml %} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +{% endhighlight %} + +### Continuous Integration + +> Continuous Integration is a software development practice where members of a team integrate their work frequently, usually each person integrates at least daily — leading to multiple integrations per day. Many teams find that this approach leads to significantly reduced integration problems and allows a team to develop cohesive software more rapidly. + +*Martin Fowler* + +There are different ways to implement continuous integration for PHP. Recently [Travis CI](https://travis-ci.org/) has become by far the easiest way to do CI. Travis CI is a hosted continuous integration service for the open source community. It is integrated with GitHub and offers first class support for many languages including PHP. + +Example of a Travis CI build script: + +{% highlight yml %} + + language: php + + # list any PHP version you want to test against + php: + # aliased to a recent 5.3.x version + - 5.3 + # aliased to a recent 5.4.x version + - 5.4 + + # optionally specify a list of environments, for example to test different RDBMS + env: + - DB=mysql + - DB=pgsql + + # execute any number of scripts before the test run, custom env's are available as variables + before_script: + - if [[ "$DB" == "pgsql" ]]; then psql -c "DROP DATABASE IF EXISTS hello_world_test;" -U postgres; fi + - if [[ "$DB" == "pgsql" ]]; then psql -c "create database hello_world_test;" -U postgres; fi + - if [[ "$DB" == "mysql" ]]; then mysql -e "create database IF NOT EXISTS hello_world_test;" -uroot; fi + + script: phpunit --configuration phpunit_$DB.xml --coverage-text + +{% endhighlight %} + +Further reading: + +* [Continuous Integration with Jenkins](http://jenkins-ci.org/) +* [Continuous Integration with Teamcity](http://www.jetbrains.com/teamcity/) \ No newline at end of file From 6c6d4c5ae4c89fe4f0ddb7739689256ffc2a74a6 Mon Sep 17 00:00:00 2001 From: Markus Date: Thu, 15 Nov 2012 03:10:34 +0200 Subject: [PATCH 059/843] Added two more people to follow --- _posts/11-01-01-Resources.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/_posts/11-01-01-Resources.md b/_posts/11-01-01-Resources.md index e06c56fae..bab9bd714 100644 --- a/_posts/11-01-01-Resources.md +++ b/_posts/11-01-01-Resources.md @@ -13,6 +13,8 @@ * [Chris Shiflett](http://twitter.com/shiflett) * [Sebastian Bergmann](http://twitter.com/s_bergmann) * [Matthew Weier O'Phinney](http://twitter.com/weierophinney) +* [Pádraic Brady](http://twitter.com/padraicb) +* [Anthony Ferrara](http://twitter.com/ircmaxell) * [Nikita Popov](http://twitter.com/nikita_ppv) ## Mentoring From a3b455f1832718ac7418a5ac14e4e7e35f47ea32 Mon Sep 17 00:00:00 2001 From: mkaatman Date: Wed, 14 Nov 2012 23:20:29 -0600 Subject: [PATCH 060/843] Update scripts/setup.js MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix for https://github.com/codeguy/php-the-right-way/issues/194 which was caused by https://github.com/codeguy/php-the-right-way/commit/d5d5d0725bb7658460b09489065ad29d13663af1 --- scripts/setup.js | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/setup.js b/scripts/setup.js index 49695dc8d..bab825153 100644 --- a/scripts/setup.js +++ b/scripts/setup.js @@ -55,6 +55,7 @@ var eTop = $(e).offset().top; var eBottom = eTop + $(e).height(); var id=e.id; + id = id.replace("_title", ""); if (eTop >= viewTop) { //if we are passed the view and no heading was highlighted yet, store previous one as fallback From 0487a30e4d08011ab2d97ab9712749145ed946a7 Mon Sep 17 00:00:00 2001 From: Marin Ivanov Date: Thu, 22 Nov 2012 04:20:25 +0200 Subject: [PATCH 061/843] Added links to bg.phptherightway.com for Bulgarian translation --- README.md | 1 + _includes/welcome.md | 1 + 2 files changed, 2 insertions(+) diff --git a/README.md b/README.md index d4bbe964e..afcab6154 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,7 @@ developers know where to find good information! * [Chinese](http://wulijun.github.com/php-the-right-way) * [Ukrainian](http://iflista.github.com/php-the-right-way) * [Portuguese](http://br.phptherightway.com/) +* [Bulgarian](http://bg.phptherightway.com/) ### Translations diff --git a/_includes/welcome.md b/_includes/welcome.md index eaa0a6474..a37f707fb 100644 --- a/_includes/welcome.md +++ b/_includes/welcome.md @@ -16,6 +16,7 @@ _PHP: The Right Way_ is (or soon will be) translated into many different languag * Russian (Coming Soon) * [Spanish](http://es.phptherightway.com) * [Ukrainian](http://iflista.github.com/php-the-right-way/) +* [Bulgarian](http://bg.phptherightway.com/) ## Disclaimer From 1baa0436df5fd6058cc9f3321b5ef716c465d5ef Mon Sep 17 00:00:00 2001 From: Markus Hausammann Date: Fri, 23 Nov 2012 23:03:24 +0200 Subject: [PATCH 062/843] added chef and capistrano to deployment chapter --- _posts/09-05-01-Building your Application.md | 36 ++++++++++++++++---- 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/_posts/09-05-01-Building your Application.md b/_posts/09-05-01-Building your Application.md index da039b355..4701a7544 100644 --- a/_posts/09-05-01-Building your Application.md +++ b/_posts/09-05-01-Building your Application.md @@ -4,11 +4,16 @@ isChild: true ## Building and Deploying your Application {#build_title} -If you find yourself doing manual database schema changes or running your tests manually before updating your files (manually), think twice! With every additional manual task needed to deploy a new version of your app, the chances for potentially fatal mistakes increase. Whether you're dealing with a simple update, a comprehensive build process or even a continuous integration strategy, build tools are your friend. +If you find yourself doing manual database schema changes or running your tests manually before updating your files (manually), +think twice! With every additional manual task needed to deploy a new version of your app, the chances for potentially +fatal mistakes increase. Whether you're dealing with a simple update, a comprehensive build process or even a continuous +integration strategy, build tools are your friend. -### Control your deployment with Phing +### Phing - Deployment with XML and PHP -With [Phing](http://www.phing.info/) you can control your packaging, deployment or testing process from within a simple XML build file. Phing provides a rich set of tasks usually needed to install or update a web app and can be extended with additional custom tasks (written in PHP). +[Phing](http://www.phing.info/) is the easiest way to get started with automated deployment in the PHP world. With Phing you can control your packaging, deployment or testing process from within a simple +XML build file. Phing provides a rich set of tasks usually needed to install or update a web app and can be extended +with additional custom tasks, written in PHP. Example of a Phing script (build.xml): @@ -18,7 +23,7 @@ Example of a Phing script (build.xml): + promptText="What's the target environment (development, production)?" useExistingValue="true" /> @@ -53,13 +58,32 @@ Example of a Phing script (build.xml): {% endhighlight %} +### Capistrano - The powerful Ruby alternative + +[Capistrano](https://github.com/capistrano/capistrano/wiki) is a system for *intermediate-to-advanced programmers* to execute commands in a structured, repeatable way on one or more remote machines. + +It is pre-configured for deploying Ruby on Rails applications, however people are **successfully deploying PHP systems** with it. Successful use of Capistrano depends on a working knowledge of Ruby and Rake. + +Dave Gardner's blog post [PHP Deployment with Capistrano](http://www.davegardner.me.uk/blog/2012/02/13/php-deployment-with-capistrano/) is a good starting point for PHP developers interested in Capistrano. + +###Chef - Ruby based system integration framework + +[Chef](http://www.opscode.com/chef/) is more than a deployment framework, it is a very powerful Ruby based system integration framework that doesn't just deploy your app but can build your whole server environment or virtual boxes. + +Chef resources for PHP developers: + +* [Three part blog series about deploying a LAMP application with Chef, Vagrant, and EC2](http://www.jasongrimes.org/2012/06/managing-lamp-environments-with-chef-vagrant-and-ec2-1-of-3/) +* [Chef Cookbook which installs and configures PHP 5.3 and the PEAR package management system](https://github.com/opscode-cookbooks/php) + ### Continuous Integration -> Continuous Integration is a software development practice where members of a team integrate their work frequently, usually each person integrates at least daily — leading to multiple integrations per day. Many teams find that this approach leads to significantly reduced integration problems and allows a team to develop cohesive software more rapidly. +> Continuous Integration is a software development practice where members of a team integrate their work frequently, +usually each person integrates at least daily — leading to multiple integrations per day. Many teams find that this +approach leads to significantly reduced integration problems and allows a team to develop cohesive software more rapidly. *Martin Fowler* -There are different ways to implement continuous integration for PHP. Recently [Travis CI](https://travis-ci.org/) has become by far the easiest way to do CI. Travis CI is a hosted continuous integration service for the open source community. It is integrated with GitHub and offers first class support for many languages including PHP. +There are different ways to implement continuous integration for PHP. Recently [Travis CI](https://travis-ci.org/) has done a great job of making continuous integration a reality even for small projects. Travis CI is a hosted continuous integration service for the open source community. It is integrated with GitHub and offers first class support for many languages including PHP. Example of a Travis CI build script: From e354d95842f65587956e0a006bcc2d833a776282 Mon Sep 17 00:00:00 2001 From: Markus Hausammann Date: Fri, 23 Nov 2012 23:10:15 +0200 Subject: [PATCH 063/843] line wraps for easier read --- _posts/09-05-01-Building your Application.md | 30 +++++++++++++------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/_posts/09-05-01-Building your Application.md b/_posts/09-05-01-Building your Application.md index 4701a7544..9dfab93a6 100644 --- a/_posts/09-05-01-Building your Application.md +++ b/_posts/09-05-01-Building your Application.md @@ -4,15 +4,16 @@ isChild: true ## Building and Deploying your Application {#build_title} -If you find yourself doing manual database schema changes or running your tests manually before updating your files (manually), -think twice! With every additional manual task needed to deploy a new version of your app, the chances for potentially -fatal mistakes increase. Whether you're dealing with a simple update, a comprehensive build process or even a continuous -integration strategy, build tools are your friend. +If you find yourself doing manual database schema changes or running your tests manually before updating your files +(manually), think twice! With every additional manual task needed to deploy a new version of your app, the chances for +potentially fatal mistakes increase. Whether you're dealing with a simple update, a comprehensive build process or even +a continuous integration strategy, build tools are your friend. ### Phing - Deployment with XML and PHP -[Phing](http://www.phing.info/) is the easiest way to get started with automated deployment in the PHP world. With Phing you can control your packaging, deployment or testing process from within a simple -XML build file. Phing provides a rich set of tasks usually needed to install or update a web app and can be extended +[Phing](http://www.phing.info/) is the easiest way to get started with automated deployment in the PHP world. +With Phing you can control your packaging, deployment or testing process from within a simple XML build file. +Phing provides a rich set of tasks usually needed to install or update a web app and can be extended with additional custom tasks, written in PHP. Example of a Phing script (build.xml): @@ -60,15 +61,19 @@ Example of a Phing script (build.xml): ### Capistrano - The powerful Ruby alternative -[Capistrano](https://github.com/capistrano/capistrano/wiki) is a system for *intermediate-to-advanced programmers* to execute commands in a structured, repeatable way on one or more remote machines. +[Capistrano](https://github.com/capistrano/capistrano/wiki) is a system for *intermediate-to-advanced programmers* +to execute commands in a structured, repeatable way on one or more remote machines. -It is pre-configured for deploying Ruby on Rails applications, however people are **successfully deploying PHP systems** with it. Successful use of Capistrano depends on a working knowledge of Ruby and Rake. +It is pre-configured for deploying Ruby on Rails applications, however people are **successfully deploying PHP systems** +with it. Successful use of Capistrano depends on a working knowledge of Ruby and Rake. -Dave Gardner's blog post [PHP Deployment with Capistrano](http://www.davegardner.me.uk/blog/2012/02/13/php-deployment-with-capistrano/) is a good starting point for PHP developers interested in Capistrano. +Dave Gardner's blog post [PHP Deployment with Capistrano](http://www.davegardner.me.uk/blog/2012/02/13/php-deployment-with-capistrano/) +is a good starting point for PHP developers interested in Capistrano. ###Chef - Ruby based system integration framework -[Chef](http://www.opscode.com/chef/) is more than a deployment framework, it is a very powerful Ruby based system integration framework that doesn't just deploy your app but can build your whole server environment or virtual boxes. +[Chef](http://www.opscode.com/chef/) is more than a deployment framework, it is a very powerful Ruby based system +integration framework that doesn't just deploy your app but can build your whole server environment or virtual boxes. Chef resources for PHP developers: @@ -83,7 +88,10 @@ approach leads to significantly reduced integration problems and allows a team t *Martin Fowler* -There are different ways to implement continuous integration for PHP. Recently [Travis CI](https://travis-ci.org/) has done a great job of making continuous integration a reality even for small projects. Travis CI is a hosted continuous integration service for the open source community. It is integrated with GitHub and offers first class support for many languages including PHP. +There are different ways to implement continuous integration for PHP. Recently [Travis CI](https://travis-ci.org/) has +done a great job of making continuous integration a reality even for small projects. Travis CI is a hosted continuous +integration service for the open source community. It is integrated with GitHub and offers first class support for many +languages including PHP. Example of a Travis CI build script: From f247cb7441104a5eff342542d7abbd15ea604bf4 Mon Sep 17 00:00:00 2001 From: Phil Sturgeon Date: Sun, 25 Nov 2012 15:11:48 -0500 Subject: [PATCH 064/843] Added link to Polish Translation --- _includes/welcome.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_includes/welcome.md b/_includes/welcome.md index eaa0a6474..301179c69 100644 --- a/_includes/welcome.md +++ b/_includes/welcome.md @@ -11,7 +11,7 @@ _PHP: The Right Way_ is (or soon will be) translated into many different languag * [English](http://www.phptherightway.com) * [Chinese](http://wulijun.github.com/php-the-right-way) * [Japanese](http://ja.phptherightway.com) -* Polish (Coming Soon) +* [Polish](http://pl.phptherightway.com/) * [Portuguese](http://br.phptherightway.com/) * Russian (Coming Soon) * [Spanish](http://es.phptherightway.com) From 5dfc244734652d6e09b62922a204b74a40e5cff9 Mon Sep 17 00:00:00 2001 From: Phil Sturgeon Date: Sun, 25 Nov 2012 17:10:28 -0500 Subject: [PATCH 065/843] Fixed link to php binaries for Windows --- _posts/01-05-01-Windows-Setup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/01-05-01-Windows-Setup.md b/_posts/01-05-01-Windows-Setup.md index 351977368..1cd34ab14 100644 --- a/_posts/01-05-01-Windows-Setup.md +++ b/_posts/01-05-01-Windows-Setup.md @@ -4,7 +4,7 @@ isChild: true ## Windows Setup {#windows_setup_title} -PHP is available in several ways for Windows. You can [download the binaries](php-downloads) and until recently you could use a '.msi' +PHP is available in several ways for Windows. You can [download the binaries][php-downloads] and until recently you could use a '.msi' installer. The installer is no longer supported and stops at PHP 5.3.0. For learning and local development you can use the built in webserver with PHP 5.4 so you don't need to worry about configuring it. If you From 8f15552dece7382f40c52d6ef894100c6be2223e Mon Sep 17 00:00:00 2001 From: Markus Hausammann Date: Thu, 29 Nov 2012 14:55:28 +0200 Subject: [PATCH 066/843] make chapter topic based instead of product based --- _posts/09-05-01-Building your Application.md | 93 ++++---------------- 1 file changed, 15 insertions(+), 78 deletions(-) diff --git a/_posts/09-05-01-Building your Application.md b/_posts/09-05-01-Building your Application.md index 9dfab93a6..00273ee1d 100644 --- a/_posts/09-05-01-Building your Application.md +++ b/_posts/09-05-01-Building your Application.md @@ -7,71 +7,36 @@ isChild: true If you find yourself doing manual database schema changes or running your tests manually before updating your files (manually), think twice! With every additional manual task needed to deploy a new version of your app, the chances for potentially fatal mistakes increase. Whether you're dealing with a simple update, a comprehensive build process or even -a continuous integration strategy, build tools are your friend. +a continuous integration strategy, [build automation](http://en.wikipedia.org/wiki/Build_automation) is your friend. -### Phing - Deployment with XML and PHP +Among the tasks you might want to automate are: + +* dependency management +* compilation, minification of your assets +* running tests +* creation of documentation +* packaging +* deployment + + +### Build Automation Tools + +Build tools can be described as a collection of scripts that handle common tasks of software deployment. The build tool +is not a part of your software, it acts on your software from 'outside'. [Phing](http://www.phing.info/) is the easiest way to get started with automated deployment in the PHP world. With Phing you can control your packaging, deployment or testing process from within a simple XML build file. Phing provides a rich set of tasks usually needed to install or update a web app and can be extended with additional custom tasks, written in PHP. -Example of a Phing script (build.xml): - -{% highlight xml %} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -{% endhighlight %} - -### Capistrano - The powerful Ruby alternative - [Capistrano](https://github.com/capistrano/capistrano/wiki) is a system for *intermediate-to-advanced programmers* to execute commands in a structured, repeatable way on one or more remote machines. - It is pre-configured for deploying Ruby on Rails applications, however people are **successfully deploying PHP systems** with it. Successful use of Capistrano depends on a working knowledge of Ruby and Rake. Dave Gardner's blog post [PHP Deployment with Capistrano](http://www.davegardner.me.uk/blog/2012/02/13/php-deployment-with-capistrano/) is a good starting point for PHP developers interested in Capistrano. -###Chef - Ruby based system integration framework - [Chef](http://www.opscode.com/chef/) is more than a deployment framework, it is a very powerful Ruby based system integration framework that doesn't just deploy your app but can build your whole server environment or virtual boxes. @@ -93,34 +58,6 @@ done a great job of making continuous integration a reality even for small proje integration service for the open source community. It is integrated with GitHub and offers first class support for many languages including PHP. -Example of a Travis CI build script: - -{% highlight yml %} - - language: php - - # list any PHP version you want to test against - php: - # aliased to a recent 5.3.x version - - 5.3 - # aliased to a recent 5.4.x version - - 5.4 - - # optionally specify a list of environments, for example to test different RDBMS - env: - - DB=mysql - - DB=pgsql - - # execute any number of scripts before the test run, custom env's are available as variables - before_script: - - if [[ "$DB" == "pgsql" ]]; then psql -c "DROP DATABASE IF EXISTS hello_world_test;" -U postgres; fi - - if [[ "$DB" == "pgsql" ]]; then psql -c "create database hello_world_test;" -U postgres; fi - - if [[ "$DB" == "mysql" ]]; then mysql -e "create database IF NOT EXISTS hello_world_test;" -uroot; fi - - script: phpunit --configuration phpunit_$DB.xml --coverage-text - -{% endhighlight %} - Further reading: * [Continuous Integration with Jenkins](http://jenkins-ci.org/) From 45dc8214aa1213e6f34537e4c9303ee60f52462d Mon Sep 17 00:00:00 2001 From: Markus Hausammann Date: Thu, 29 Nov 2012 15:24:23 +0200 Subject: [PATCH 067/843] add information about ant and maven --- _posts/09-05-01-Building your Application.md | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/_posts/09-05-01-Building your Application.md b/_posts/09-05-01-Building your Application.md index 00273ee1d..8b08603d6 100644 --- a/_posts/09-05-01-Building your Application.md +++ b/_posts/09-05-01-Building your Application.md @@ -22,12 +22,15 @@ Among the tasks you might want to automate are: ### Build Automation Tools Build tools can be described as a collection of scripts that handle common tasks of software deployment. The build tool -is not a part of your software, it acts on your software from 'outside'. +is not a part of your software, it acts on your software from 'outside'. + +There are many open source tools available to help you with build automation, some are written in PHP others aren't. +This shouldn't hold you back from using them, if they're better suited for the specific job. Here are a few examples: [Phing](http://www.phing.info/) is the easiest way to get started with automated deployment in the PHP world. With Phing you can control your packaging, deployment or testing process from within a simple XML build file. -Phing provides a rich set of tasks usually needed to install or update a web app and can be extended -with additional custom tasks, written in PHP. +Phing (which is based on [Apache Ant](http://ant.apache.org/)) provides a rich set of tasks usually needed to install or +update a web app and can be extended with additional custom tasks, written in PHP. [Capistrano](https://github.com/capistrano/capistrano/wiki) is a system for *intermediate-to-advanced programmers* to execute commands in a structured, repeatable way on one or more remote machines. @@ -45,6 +48,11 @@ Chef resources for PHP developers: * [Three part blog series about deploying a LAMP application with Chef, Vagrant, and EC2](http://www.jasongrimes.org/2012/06/managing-lamp-environments-with-chef-vagrant-and-ec2-1-of-3/) * [Chef Cookbook which installs and configures PHP 5.3 and the PEAR package management system](https://github.com/opscode-cookbooks/php) +Further reading: + +* [Automate your project with Apache Ant](http://net.tutsplus.com/tutorials/other/automate-your-projects-with-apache-ant/) +* [Maven](http://maven.apache.org/), a build framework based on Ant and [how to use it with PHP](http://www.php-maven.org/) + ### Continuous Integration > Continuous Integration is a software development practice where members of a team integrate their work frequently, From 0e06acf705d6300a52fed40aa0dc33fa45fae429 Mon Sep 17 00:00:00 2001 From: paaswatch Date: Thu, 29 Nov 2012 14:41:44 +0100 Subject: [PATCH 068/843] Update _posts/11-01-01-Resources.md phpfog.com will discontinue the service at the end of the year. Added: AppFog and fortrabbit --- _posts/11-01-01-Resources.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/_posts/11-01-01-Resources.md b/_posts/11-01-01-Resources.md index bab9bd714..f91e62084 100644 --- a/_posts/11-01-01-Resources.md +++ b/_posts/11-01-01-Resources.md @@ -24,7 +24,8 @@ ## PHP PaaS Providers * [PagodaBox](https://pagodabox.com/) -* [PHP Fog](https://phpfog.com/) +* [AppFog](https://appfog.com/) +* [fortrabbit](https://fortrabbit.com/) * [Engine Yard Orchestra PHP Platform](http://www.engineyard.com/products/orchestra/) * [Red Hat OpenShift Platform](http://www.redhat.com/products/cloud-computing/openshift/) * [dotCloud](http://docs.dotcloud.com/services/php/) From f061f6714a306badd5101ef8af8e32ad2763ae3f Mon Sep 17 00:00:00 2001 From: paaswatch Date: Thu, 29 Nov 2012 14:42:33 +0100 Subject: [PATCH 069/843] Update _posts/11-01-01-Resources.md --- _posts/11-01-01-Resources.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/11-01-01-Resources.md b/_posts/11-01-01-Resources.md index f91e62084..2fede3d52 100644 --- a/_posts/11-01-01-Resources.md +++ b/_posts/11-01-01-Resources.md @@ -25,7 +25,7 @@ * [PagodaBox](https://pagodabox.com/) * [AppFog](https://appfog.com/) -* [fortrabbit](https://fortrabbit.com/) +* [fortrabbit](http://fortrabbit.com/) * [Engine Yard Orchestra PHP Platform](http://www.engineyard.com/products/orchestra/) * [Red Hat OpenShift Platform](http://www.redhat.com/products/cloud-computing/openshift/) * [dotCloud](http://docs.dotcloud.com/services/php/) From 891d08d1905f47c35b60a32697b4c2cd8d100da0 Mon Sep 17 00:00:00 2001 From: "Paul M. Jones" Date: Thu, 29 Nov 2012 19:07:16 -0200 Subject: [PATCH 070/843] add Aura.SQL as a PSR-0 compliant DB abstraction layer --- _posts/06-01-01-Databases.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/_posts/06-01-01-Databases.md b/_posts/06-01-01-Databases.md index 930297c9e..2df162496 100644 --- a/_posts/06-01-01-Databases.md +++ b/_posts/06-01-01-Databases.md @@ -71,6 +71,7 @@ SQLite then a little overhead will be worth it the sake of code cleanliness. Some abstraction layers have been built using the PSR-0 namespace standard so can be installed in any application you like: +* [Aura SQL][6] * [Doctrine2 DBAL][2] * [ZF2 Db][4] * [ZF1 Db][3] @@ -80,6 +81,7 @@ Some abstraction layers have been built using the PSR-0 namespace standard so ca [3]: http://framework.zend.com/manual/en/zend.db.html [4]: http://packages.zendframework.com/docs/latest/manual/en/index.html#zend-db [5]: http://php.net/manual/en/pdo.connections.php +[6]: https://github.com/auraphp/Aura.Sql [mysql]: http://php.net/mysql [mysqli]: http://php.net/mysqli From 313760f12d8a44ed4be77ac034a0619c436a7f17 Mon Sep 17 00:00:00 2001 From: Hari K T Date: Fri, 30 Nov 2012 21:57:12 +0530 Subject: [PATCH 071/843] Fix the link of atoum which seems moved to https://github.com/atoum/atoum --- _posts/08-02-01-Test-Driven-Development.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/08-02-01-Test-Driven-Development.md b/_posts/08-02-01-Test-Driven-Development.md index fdbd95367..91a7e59e9 100644 --- a/_posts/08-02-01-Test-Driven-Development.md +++ b/_posts/08-02-01-Test-Driven-Development.md @@ -33,7 +33,7 @@ applications, but there are several alternatives * [SimpleTest](http://simpletest.org) * [Enhance PHP](http://www.enhance-php.com/) * [PUnit](http://punit.smf.me.uk/) -* [atoum](https://github.com/mageekguy/atoum) +* [atoum](https://github.com/atoum/atoum) ### Integration Testing From c5fa313b0e34d4cf7e73f1f88a006d14bd48eab0 Mon Sep 17 00:00:00 2001 From: Gerard Roche Date: Sat, 1 Dec 2012 11:10:46 +0000 Subject: [PATCH 072/843] Update _posts/07-07-01-Error-Reporting.md --- _posts/07-07-01-Error-Reporting.md | 31 +++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/_posts/07-07-01-Error-Reporting.md b/_posts/07-07-01-Error-Reporting.md index 1eee78dd3..1562a38e6 100644 --- a/_posts/07-07-01-Error-Reporting.md +++ b/_posts/07-07-01-Error-Reporting.md @@ -11,22 +11,21 @@ production (live). ### Development -To show errors in your development environment, configure the following settings in your `php.ini`: +To show every possible error during development, configure the following settings in your `php.ini`: -- display_errors: On -- error_reporting: -1 -- log_errors: On + display_errors = On + display_startup_errors = On + error_reporting = -1 + log_errors = On -From [php.net](http://php.net/manual/function.error-reporting.php): - -> Passing in the value -1 will show every possible error, even when new levels and constants are added in future PHP versions. The E_ALL constant also behaves this way as of PHP 5.4. +> Passing in the value `-1` will show every possible error, even when new levels and constants are added in future PHP versions. The `E_ALL` constant also behaves this way as of PHP 5.4. - [php.net](http://php.net/manual/function.error-reporting.php) The `E_STRICT` error level constant was introduced in 5.3.0 and is not part of `E_ALL`, however it became part of `E_ALL` in 5.4.0. What does this mean? In terms of reporting every possible error in version 5.3 it means you must use either `-1` or `E_ALL | E_STRICT`. -**Reporting Every Possibly Error by PHP Version** +**Reporting every possible error by PHP version** * < 5.3 `-1` or `E_ALL` *   5.3 `-1` or `E_ALL | E_STRICT` @@ -34,15 +33,17 @@ use either `-1` or `E_ALL | E_STRICT`. ### Production -To hide the errors on your production environment, configure your `php.ini` as: +To hide errors on your production environment, configure your `php.ini` as: -- display_errors: Off -- error_reporting: E_ALL -- log_errors: On + display_errors = Off + display_startup_errors = Off + error_reporting = E_ALL + log_errors = On With these settings in production, errors will still be logged to the error logs for the web server, but will not be shown to the user. For more information on these settings, see the PHP manual: -* [Error_reporting](http://www.php.net/manual/en/errorfunc.configuration.php#ini.error-reporting) -* [Display_errors](http://www.php.net/manual/en/errorfunc.configuration.php#ini.display-errors) -* [Log_errors](http://www.php.net/manual/en/errorfunc.configuration.php#ini.log-errors) \ No newline at end of file +* [error_reporting](http://www.php.net/manual/en/errorfunc.configuration.php#ini.error-reporting) +* [display_errors](http://www.php.net/manual/en/errorfunc.configuration.php#ini.display-errors) +* [display_startup_errors](http://php.net/manual/errorfunc.configuration.php#ini.display-startup-errors) +* [log_errors](http://www.php.net/manual/en/errorfunc.configuration.php#ini.log-errors) \ No newline at end of file From 937460126aa6477018eafdd2017a9bc3da825c78 Mon Sep 17 00:00:00 2001 From: Gerard Roche Date: Sat, 1 Dec 2012 11:13:37 +0000 Subject: [PATCH 073/843] Update _posts/07-07-01-Error-Reporting.md --- _posts/07-07-01-Error-Reporting.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/_posts/07-07-01-Error-Reporting.md b/_posts/07-07-01-Error-Reporting.md index 1eee78dd3..9fd409409 100644 --- a/_posts/07-07-01-Error-Reporting.md +++ b/_posts/07-07-01-Error-Reporting.md @@ -43,6 +43,6 @@ To hide the errors on your production environment, configure yo With these settings in production, errors will still be logged to the error logs for the web server, but will not be shown to the user. For more information on these settings, see the PHP manual: -* [Error_reporting](http://www.php.net/manual/en/errorfunc.configuration.php#ini.error-reporting) -* [Display_errors](http://www.php.net/manual/en/errorfunc.configuration.php#ini.display-errors) -* [Log_errors](http://www.php.net/manual/en/errorfunc.configuration.php#ini.log-errors) \ No newline at end of file +* [error_reporting](http://php.net/manual/errorfunc.configuration.php#ini.error-reporting) +* [display_errors](http://php.net/manual/errorfunc.configuration.php#ini.display-errors) +* [log_errors](http://php.net/manual/errorfunc.configuration.php#ini.log-errors) \ No newline at end of file From bcff8df579e78c33f16c990edacc3866b245d4f4 Mon Sep 17 00:00:00 2001 From: Markus Hausammann Date: Sun, 2 Dec 2012 03:23:36 +0200 Subject: [PATCH 074/843] capitalise bullet points --- _posts/09-05-01-Building your Application.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/_posts/09-05-01-Building your Application.md b/_posts/09-05-01-Building your Application.md index 8b08603d6..66e99dcf6 100644 --- a/_posts/09-05-01-Building your Application.md +++ b/_posts/09-05-01-Building your Application.md @@ -11,12 +11,12 @@ a continuous integration strategy, [build automation](http://en.wikipedia.org/wi Among the tasks you might want to automate are: -* dependency management -* compilation, minification of your assets -* running tests -* creation of documentation -* packaging -* deployment +* Dependency management +* Compilation, minification of your assets +* Running tests +* Creation of documentation +* Packaging +* Deployment ### Build Automation Tools From 1ac7c580ade0b755bbe3c9924e2d60cb130e46a1 Mon Sep 17 00:00:00 2001 From: Sebastian Goettschkes Date: Tue, 4 Dec 2012 16:17:24 +0100 Subject: [PATCH 075/843] Updating pear description --- _posts/04-03-01-PEAR.md | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/_posts/04-03-01-PEAR.md b/_posts/04-03-01-PEAR.md index e0f019461..61d0ce406 100644 --- a/_posts/04-03-01-PEAR.md +++ b/_posts/04-03-01-PEAR.md @@ -4,6 +4,36 @@ isChild: true ## PEAR {#pear_title} -Another veteran package manager that many PHP developers enjoy is [PEAR][1]. It behaves much the same way, and is also worth researching for your projects. [Learn about PEAR][1]. +Another veteran package manager that many PHP developers enjoy is [PEAR][1]. It behaves much the same way as Composer, +but has some noteable differences. + +PEAR requires each package to have a specific structure, which means that the author of the package must prepare it +for usage with PEAR. Using a project which was not prepared to work with PEAR is not possible. + +PEAR installs packages globally, which means after installing them once they are available to all projects on that +server. This can be good if many projects rely on the same package with the same version but might lead to problems +if version conflicts between two projects arise. + +### How to install PEAR + +You can install PEAR by downloading the phar installer and executing it. The PEAR documentation has detailed +[install instructions][2] for every operating system. + +If you are using Linux, you can also have a look at your distribution package manager. Debian and Ubuntu for example +have a apt ``php-pear`` package. + +### How to install a package + +If the package is listed on the [PEAR packages list][3], you can install it by specifying the official name: + + pear install foo + +If the package is hosted on another channel, you need to `discover` the channel first and also specify it when +installing. See the [Using channel docs][4] for more information on this topic. + +* [Learn about PEAR][1] [1]: http://pear.php.net/ +[2]: http://pear.php.net/manual/en/installation.getting.php +[3]: http://pear.php.net/packages.php +[4]: http://pear.php.net/manual/en/guide.users.commandline.channels.php From 50ef1b10bd2d737dd0344750387cf8f449c71460 Mon Sep 17 00:00:00 2001 From: Ryan McAllen Date: Tue, 4 Dec 2012 13:20:18 -0500 Subject: [PATCH 076/843] Fixed misspelling --- pages/Functional-Programming.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/Functional-Programming.md b/pages/Functional-Programming.md index 6d129c3de..f9dc9a006 100644 --- a/pages/Functional-Programming.md +++ b/pages/Functional-Programming.md @@ -71,7 +71,7 @@ print_r($output); // items > 3 {% endhighlight %} Each filter function in the family accepts only elements greater than some minimum value. Single filter returned by -`criteria_greater_than` is a closure whith `$min` argument closed by the value in the scope (given as an argument when +`criteria_greater_than` is a closure with `$min` argument closed by the value in the scope (given as an argument when `criteria_greater_than` is called). Early binding is used by default for importing `$min` variable into the created function. For true closures with late From 5c412a4c877dadfba739d08dba2e44b133a869ea Mon Sep 17 00:00:00 2001 From: Jeremy Cloutier Date: Tue, 4 Dec 2012 15:35:28 -0500 Subject: [PATCH 077/843] fixed blockquote and removed linebreaks "Building your Application" --- _posts/09-05-01-Building your Application.md | 36 +++++--------------- 1 file changed, 9 insertions(+), 27 deletions(-) diff --git a/_posts/09-05-01-Building your Application.md b/_posts/09-05-01-Building your Application.md index 66e99dcf6..bccdc1650 100644 --- a/_posts/09-05-01-Building your Application.md +++ b/_posts/09-05-01-Building your Application.md @@ -4,10 +4,7 @@ isChild: true ## Building and Deploying your Application {#build_title} -If you find yourself doing manual database schema changes or running your tests manually before updating your files -(manually), think twice! With every additional manual task needed to deploy a new version of your app, the chances for -potentially fatal mistakes increase. Whether you're dealing with a simple update, a comprehensive build process or even -a continuous integration strategy, [build automation](http://en.wikipedia.org/wiki/Build_automation) is your friend. +If you find yourself doing manual database schema changes or running your tests manually before updating your files (manually), think twice! With every additional manual task needed to deploy a new version of your app, the chances for potentially fatal mistakes increase. Whether you're dealing with a simple update, a comprehensive build process or even a continuous integration strategy, [build automation](http://en.wikipedia.org/wiki/Build_automation) is your friend. Among the tasks you might want to automate are: @@ -21,27 +18,17 @@ Among the tasks you might want to automate are: ### Build Automation Tools -Build tools can be described as a collection of scripts that handle common tasks of software deployment. The build tool -is not a part of your software, it acts on your software from 'outside'. +Build tools can be described as a collection of scripts that handle common tasks of software deployment. The build tool is not a part of your software, it acts on your software from 'outside'. -There are many open source tools available to help you with build automation, some are written in PHP others aren't. -This shouldn't hold you back from using them, if they're better suited for the specific job. Here are a few examples: +There are many open source tools available to help you with build automation, some are written in PHP others aren't. This shouldn't hold you back from using them, if they're better suited for the specific job. Here are a few examples: -[Phing](http://www.phing.info/) is the easiest way to get started with automated deployment in the PHP world. -With Phing you can control your packaging, deployment or testing process from within a simple XML build file. -Phing (which is based on [Apache Ant](http://ant.apache.org/)) provides a rich set of tasks usually needed to install or -update a web app and can be extended with additional custom tasks, written in PHP. +[Phing](http://www.phing.info/) is the easiest way to get started with automated deployment in the PHP world. With Phing you can control your packaging, deployment or testing process from within a simple XML build file. Phing (which is based on [Apache Ant](http://ant.apache.org/)) provides a rich set of tasks usually needed to install or update a web app and can be extended with additional custom tasks, written in PHP. -[Capistrano](https://github.com/capistrano/capistrano/wiki) is a system for *intermediate-to-advanced programmers* -to execute commands in a structured, repeatable way on one or more remote machines. -It is pre-configured for deploying Ruby on Rails applications, however people are **successfully deploying PHP systems** -with it. Successful use of Capistrano depends on a working knowledge of Ruby and Rake. +[Capistrano](https://github.com/capistrano/capistrano/wiki) is a system for *intermediate-to-advanced programmers* to execute commands in a structured, repeatable way on one or more remote machines.It is pre-configured for deploying Ruby on Rails applications, however people are **successfully deploying PHP systems** with it. Successful use of Capistrano depends on a working knowledge of Ruby and Rake. -Dave Gardner's blog post [PHP Deployment with Capistrano](http://www.davegardner.me.uk/blog/2012/02/13/php-deployment-with-capistrano/) -is a good starting point for PHP developers interested in Capistrano. +Dave Gardner's blog post [PHP Deployment with Capistrano](http://www.davegardner.me.uk/blog/2012/02/13/php-deployment-with-capistrano/) is a good starting point for PHP developers interested in Capistrano. -[Chef](http://www.opscode.com/chef/) is more than a deployment framework, it is a very powerful Ruby based system -integration framework that doesn't just deploy your app but can build your whole server environment or virtual boxes. +[Chef](http://www.opscode.com/chef/) is more than a deployment framework, it is a very powerful Ruby based system integration framework that doesn't just deploy your app but can build your whole server environment or virtual boxes. Chef resources for PHP developers: @@ -55,16 +42,11 @@ Further reading: ### Continuous Integration -> Continuous Integration is a software development practice where members of a team integrate their work frequently, -usually each person integrates at least daily — leading to multiple integrations per day. Many teams find that this -approach leads to significantly reduced integration problems and allows a team to develop cohesive software more rapidly. +> Continuous Integration is a software development practice where members of a team integrate their work frequently, usually each person integrates at least daily — leading to multiple integrations per day. Many teams find that this approach leads to significantly reduced integration problems and allows a team to develop cohesive software more rapidly. *Martin Fowler* -There are different ways to implement continuous integration for PHP. Recently [Travis CI](https://travis-ci.org/) has -done a great job of making continuous integration a reality even for small projects. Travis CI is a hosted continuous -integration service for the open source community. It is integrated with GitHub and offers first class support for many -languages including PHP. +There are different ways to implement continuous integration for PHP. Recently [Travis CI](https://travis-ci.org/) has done a great job of making continuous integration a reality even for small projects. Travis CI is a hosted continuous integration service for the open source community. It is integrated with GitHub and offers first class support for many languages including PHP. Further reading: From 8b7b2ae5562d4cc77b516ed6b628d084fd2688ae Mon Sep 17 00:00:00 2001 From: Sean DuBois Date: Wed, 5 Dec 2012 22:58:44 -0500 Subject: [PATCH 078/843] Update password hashing section --- .../07-03-01-Password-Hashing-with-Bcrypt.md | 19 -------- _posts/07-03-01-Password-Hashing.md | 44 +++++++++++++++++++ 2 files changed, 44 insertions(+), 19 deletions(-) delete mode 100644 _posts/07-03-01-Password-Hashing-with-Bcrypt.md create mode 100644 _posts/07-03-01-Password-Hashing.md diff --git a/_posts/07-03-01-Password-Hashing-with-Bcrypt.md b/_posts/07-03-01-Password-Hashing-with-Bcrypt.md deleted file mode 100644 index bb8471c29..000000000 --- a/_posts/07-03-01-Password-Hashing-with-Bcrypt.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -isChild: true ---- - -## Password Hashing with Bcrypt {#password_hashing_with_bcrypt_title} - -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] - -[3]: http://codahale.com/how-to-safely-store-a-password/ -[4]: http://www.openwall.com/phpass/ diff --git a/_posts/07-03-01-Password-Hashing.md b/_posts/07-03-01-Password-Hashing.md new file mode 100644 index 000000000..8d3d03aba --- /dev/null +++ b/_posts/07-03-01-Password-Hashing.md @@ -0,0 +1,44 @@ +--- +isChild: true +--- + +## Password Hashing {#password_hashing_title} + +Eventually everyone builds a PHP application that relies on user login. Usernames and passwords are stored in a database and later used to authenticate users upon login. + +It is important that you properly [_hash_][3] passwords before storing them. Password hashing is an irreversible, one way function performed against the users password. This produces a fix length string that can not be feasibly reversed. This means you can compare a hash against another to determine if they both came from the same source string, but you can not determine the original string. If passwords are not hashed and your database is accessed by an unauthorized third-party, all user accounts are now compromised. Some users may (unfortunately) use the same password for other services. Therefore, it is important to take security seriously. + +**Hashing passwords with `password_hash`** + +In PHP 5.5 `password_hash` will be introduced. At this time it is using BCrypt, the strongest algorithm currently supported by PHP. It will updated in the future to support more algorithms as needed though. The `password_compat` library was created to provide forward compatibility for PHP >= 5.3.7. + +Below we hash two strings, but because the two hashes do not match the user will be denied login. + +{% highlight php %} += 5.3.7 && < 5.5] [2] +* [Learn about hashing in regards to cryptography] [3] +* [PHP `password_hash` RFC] [4] + +[1]: http://us2.php.net/manual/en/function.password-hash.php +[2]: https://github.com/ircmaxell/password_compat +[3]: http://en.wikipedia.org/wiki/Cryptographic_hash_function +[4]: https://wiki.php.net/rfc/password_hash From 6d62e643f7a75dff69c4cf42edaaf04bf1961cdb Mon Sep 17 00:00:00 2001 From: Sean DuBois Date: Thu, 6 Dec 2012 04:44:29 -0500 Subject: [PATCH 079/843] The example I had before is not actually helpful for users, this one is much more relevant --- _posts/07-03-01-Password-Hashing.md | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/_posts/07-03-01-Password-Hashing.md b/_posts/07-03-01-Password-Hashing.md index 8d3d03aba..cb611bfaf 100644 --- a/_posts/07-03-01-Password-Hashing.md +++ b/_posts/07-03-01-Password-Hashing.md @@ -12,20 +12,16 @@ It is important that you properly [_hash_][3] passwords before storing them. Pas In PHP 5.5 `password_hash` will be introduced. At this time it is using BCrypt, the strongest algorithm currently supported by PHP. It will updated in the future to support more algorithms as needed though. The `password_compat` library was created to provide forward compatibility for PHP >= 5.3.7. -Below we hash two strings, but because the two hashes do not match the user will be denied login. +Below we hash a string, we then check the hash against a new string. Because our two source strings are different ('secret-password' vs. 'bad-password') this login will fail. {% highlight php %} Date: Sun, 9 Dec 2012 20:52:59 +0100 Subject: [PATCH 080/843] Adding more information about vagrant, extracting it into it's own section --- _posts/01-05-01-Windows-Setup.md | 7 ------- _posts/01-06-01-Vagrant.md | 22 ++++++++++++++++++++++ 2 files changed, 22 insertions(+), 7 deletions(-) create mode 100644 _posts/01-06-01-Vagrant.md diff --git a/_posts/01-05-01-Windows-Setup.md b/_posts/01-05-01-Windows-Setup.md index 1cd34ab14..c6430bf6c 100644 --- a/_posts/01-05-01-Windows-Setup.md +++ b/_posts/01-05-01-Windows-Setup.md @@ -17,10 +17,6 @@ If you need to run your production system on Windows then IIS7 will give you the to go, you just need to configure PHP as a handler. For support and additional resources there is a [dedicated area on iis.net][php-iis] for PHP. -Generally running your application on different environment in development and production can lead to strange bugs popping up when you go -live. If you are developing on Windows and deploying to Linux (or anything non-Windows) then you should consider using a Virtual Machine. This -sounds tricky, but using [Vagrant][vagrant] you can set up simple wrappers, then using [Puppet][puppet] or [Chef][chef] you can provision these boxes and share them with your colleagues to ensure you're all working on the same stack. More on this soon. - [php-downloads]: http://windows.php.net [phpmanager]: http://phpmanager.codeplex.com/ [wpi]: http://www.microsoft.com/web/downloads/platform.aspx @@ -28,6 +24,3 @@ sounds tricky, but using [Vagrant][vagrant] you can set up simple wrappers, then [xampp]: http://www.apachefriends.org/en/xampp.html [wamp]: http://www.wampserver.com/ [php-iis]: http://php.iis.net/ -[vagrant]: http://vagrantup.com/ -[puppet]: http://www.puppetlabs.com/ -[chef]: http://www.opscode.com/ diff --git a/_posts/01-06-01-Vagrant.md b/_posts/01-06-01-Vagrant.md new file mode 100644 index 000000000..9f824f84f --- /dev/null +++ b/_posts/01-06-01-Vagrant.md @@ -0,0 +1,22 @@ +--- +isChild: true +--- + +## Vagrant {#vagrant_title} + +Running your application on different environments in development and production can lead to strange bugs +popping up when you go live. It's also tricky to keep different development environments up to date with the same +version for all libraries used when working with a team of developers. + +If you are developing on Windows and deploying to Linux (or anything non-Windows) or are developing in a team, you +should consider using a virtual machine. This sounds tricky, but using [Vagrant][vagrant] you can set up a simple +virtual machine with only a few steps. This so called "base boxes" can then be set up with different software +using either [Puppet][puppet] or [Chef][chef] (This is called provisioning). If you share those setup files with your +colleagues you can ensure you're all working on the same stack. + +Vagrant creates shared folders used to share your code between your host and your virtual machine, meaning you can +create and edit your files on your host machine and then run the code inside your virtual machine. + +[vagrant]: http://vagrantup.com/ +[puppet]: http://www.puppetlabs.com/ +[chef]: http://www.opscode.com/ From bdbace15413b2b64337a5838a846fa1f8b5e2ce8 Mon Sep 17 00:00:00 2001 From: Jeremy Cloutier Date: Sun, 9 Dec 2012 16:13:22 -0500 Subject: [PATCH 081/843] replaced line breaks and added block quote markup for multiple lines of the fowler quote --- _posts/09-05-01-Building your Application.md | 33 +++++++++++++++----- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/_posts/09-05-01-Building your Application.md b/_posts/09-05-01-Building your Application.md index bccdc1650..ceb50f83c 100644 --- a/_posts/09-05-01-Building your Application.md +++ b/_posts/09-05-01-Building your Application.md @@ -4,7 +4,11 @@ isChild: true ## Building and Deploying your Application {#build_title} -If you find yourself doing manual database schema changes or running your tests manually before updating your files (manually), think twice! With every additional manual task needed to deploy a new version of your app, the chances for potentially fatal mistakes increase. Whether you're dealing with a simple update, a comprehensive build process or even a continuous integration strategy, [build automation](http://en.wikipedia.org/wiki/Build_automation) is your friend. +If you find yourself doing manual database schema changes or running your tests manually before updating your files +(manually), think twice! With every additional manual task needed to deploy a new version of your app, the chances for +potentially fatal mistakes increase. Whether you're dealing with a simple update, a comprehensive build process or +even a continuous integration strategy, [build automation](http://en.wikipedia.org/wiki/Build_automation) is your +friend. Among the tasks you might want to automate are: @@ -18,17 +22,27 @@ Among the tasks you might want to automate are: ### Build Automation Tools -Build tools can be described as a collection of scripts that handle common tasks of software deployment. The build tool is not a part of your software, it acts on your software from 'outside'. +Build tools can be described as a collection of scripts that handle common tasks of software deployment. The build +tool is not a part of your software, it acts on your software from 'outside'. -There are many open source tools available to help you with build automation, some are written in PHP others aren't. This shouldn't hold you back from using them, if they're better suited for the specific job. Here are a few examples: +There are many open source tools available to help you with build automation, some are written in PHP others aren't. +This shouldn't hold you back from using them, if they're better suited for the specific job. Here are a few examples: -[Phing](http://www.phing.info/) is the easiest way to get started with automated deployment in the PHP world. With Phing you can control your packaging, deployment or testing process from within a simple XML build file. Phing (which is based on [Apache Ant](http://ant.apache.org/)) provides a rich set of tasks usually needed to install or update a web app and can be extended with additional custom tasks, written in PHP. +[Phing](http://www.phing.info/) is the easiest way to get started with automated deployment in the PHP world. With +Phing you can control your packaging, deployment or testing process from within a simple XML build file. Phing (which +is based on [Apache Ant](http://ant.apache.org/)) provides a rich set of tasks usually needed to install or update a +web app and can be extended with additional custom tasks, written in PHP. -[Capistrano](https://github.com/capistrano/capistrano/wiki) is a system for *intermediate-to-advanced programmers* to execute commands in a structured, repeatable way on one or more remote machines.It is pre-configured for deploying Ruby on Rails applications, however people are **successfully deploying PHP systems** with it. Successful use of Capistrano depends on a working knowledge of Ruby and Rake. +[Capistrano](https://github.com/capistrano/capistrano/wiki) is a system for *intermediate-to-advanced programmers* to +execute commands in a structured, repeatable way on one or more remote machines.It is pre-configured for deploying +Ruby on Rails applications, however people are **successfully deploying PHP systems** with it. Successful use of +Capistrano depends on a working knowledge of Ruby and Rake. -Dave Gardner's blog post [PHP Deployment with Capistrano](http://www.davegardner.me.uk/blog/2012/02/13/php-deployment-with-capistrano/) is a good starting point for PHP developers interested in Capistrano. +Dave Gardner's blog post [PHP Deployment with Capistrano](http://www.davegardner.me.uk/blog/2012/02/13/php-deployment-with-capistrano/) +is a good starting point for PHP developers interested in Capistrano. -[Chef](http://www.opscode.com/chef/) is more than a deployment framework, it is a very powerful Ruby based system integration framework that doesn't just deploy your app but can build your whole server environment or virtual boxes. +[Chef](http://www.opscode.com/chef/) is more than a deployment framework, it is a very powerful Ruby based system +integration framework that doesn't just deploy your app but can build your whole server environment or virtual boxes. Chef resources for PHP developers: @@ -42,7 +56,10 @@ Further reading: ### Continuous Integration -> Continuous Integration is a software development practice where members of a team integrate their work frequently, usually each person integrates at least daily — leading to multiple integrations per day. Many teams find that this approach leads to significantly reduced integration problems and allows a team to develop cohesive software more rapidly. +> Continuous Integration is a software development practice where members of a team integrate their work frequently, +> usually each person integrates at least daily — leading to multiple integrations per day. Many teams find that this +> approach leads to significantly reduced integration problems and allows a team to develop cohesive software more +> rapidly. *Martin Fowler* From 85c8cb1212539165db4d7e8c02d4edd14d20154d Mon Sep 17 00:00:00 2001 From: Phil Sturgeon Date: Sun, 9 Dec 2012 16:21:48 -0500 Subject: [PATCH 082/843] Fixed formatting for last PR --- _posts/09-05-01-Building your Application.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/_posts/09-05-01-Building your Application.md b/_posts/09-05-01-Building your Application.md index ceb50f83c..d0708b1c3 100644 --- a/_posts/09-05-01-Building your Application.md +++ b/_posts/09-05-01-Building your Application.md @@ -34,7 +34,7 @@ is based on [Apache Ant](http://ant.apache.org/)) provides a rich set of tasks u web app and can be extended with additional custom tasks, written in PHP. [Capistrano](https://github.com/capistrano/capistrano/wiki) is a system for *intermediate-to-advanced programmers* to -execute commands in a structured, repeatable way on one or more remote machines.It is pre-configured for deploying +execute commands in a structured, repeatable way on one or more remote machines. It is pre-configured for deploying Ruby on Rails applications, however people are **successfully deploying PHP systems** with it. Successful use of Capistrano depends on a working knowledge of Ruby and Rake. @@ -61,9 +61,12 @@ Further reading: > approach leads to significantly reduced integration problems and allows a team to develop cohesive software more > rapidly. -*Martin Fowler* +*-- Martin Fowler* -There are different ways to implement continuous integration for PHP. Recently [Travis CI](https://travis-ci.org/) has done a great job of making continuous integration a reality even for small projects. Travis CI is a hosted continuous integration service for the open source community. It is integrated with GitHub and offers first class support for many languages including PHP. +There are different ways to implement continuous integration for PHP. Recently [Travis CI](https://travis-ci.org/) has +done a great job of making continuous integration a reality even for small projects. Travis CI is a hosted continuous +integration service for the open source community. It is integrated with GitHub and offers first class support for many +languages including PHP. Further reading: From 871b53f2c72473a8b751f7ac1f7e4ad3eee416c5 Mon Sep 17 00:00:00 2001 From: Sebastian Goettschkes Date: Mon, 10 Dec 2012 10:22:56 +0100 Subject: [PATCH 083/843] Doing some improvements to the vagrant section as suggested by @philsturgeon --- _posts/01-06-01-Vagrant.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/_posts/01-06-01-Vagrant.md b/_posts/01-06-01-Vagrant.md index 9f824f84f..9503f95fe 100644 --- a/_posts/01-06-01-Vagrant.md +++ b/_posts/01-06-01-Vagrant.md @@ -10,9 +10,11 @@ version for all libraries used when working with a team of developers. If you are developing on Windows and deploying to Linux (or anything non-Windows) or are developing in a team, you should consider using a virtual machine. This sounds tricky, but using [Vagrant][vagrant] you can set up a simple -virtual machine with only a few steps. This so called "base boxes" can then be set up with different software -using either [Puppet][puppet] or [Chef][chef] (This is called provisioning). If you share those setup files with your -colleagues you can ensure you're all working on the same stack. +virtual machine with only a few steps. These base boxes can then be set up manually, or you can use "provisioning" +software such as [Puppet][puppet] or [Chef][chef] to do this for you. Provisioning the base box is a great way to +ensure that multiple boxes are set up in an identical fashion and removes the need for you to maintain complicated +"set up" command lists. You can also "destroy" your base box and recreate it without many manual steps, making it +easy to create a "fresh" installation. Vagrant creates shared folders used to share your code between your host and your virtual machine, meaning you can create and edit your files on your host machine and then run the code inside your virtual machine. From 3cbb0ba99651f081ce1401604701997f8a0ad453 Mon Sep 17 00:00:00 2001 From: Leif Arne Storset Date: Tue, 11 Dec 2012 21:43:07 +0100 Subject: [PATCH 084/843] Clarify global-namespace explanation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I had trouble understanding this passage, but a peek in the documentation explained it. It's not about "execution" – the execution of the function is unaffected – it's about name resolution. And it's also not really about "definition". While I was at it, I renamed "method" to function, as these are not methods and methods aren't really affected by namespaces (they're already namespaced by a class). Also copyedited a bit. --- pages/The-Basics.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pages/The-Basics.md b/pages/The-Basics.md index 092ce5820..b905277f0 100644 --- a/pages/The-Basics.md +++ b/pages/The-Basics.md @@ -104,8 +104,8 @@ function test($a) ## Global namespace -While using namespaces, you may find your code being executed in the wrong scope for internal methods. To fix this, -define the method globally by using a backslash before the method. +When using namespaces, you may find that internal functions are hidden by functions you wrote. To fix this, +refer to the global function by using a backslash before the function name. {% highlight php %} Date: Fri, 14 Dec 2012 22:50:43 +0000 Subject: [PATCH 085/843] Fixed typos --- _posts/02-01-01-Code-Style-Guide.md | 2 +- _posts/03-02-01-Programming-Paradigms.md | 2 +- _posts/06-01-01-Databases.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/_posts/02-01-01-Code-Style-Guide.md b/_posts/02-01-01-Code-Style-Guide.md index f5a501dcb..b83e831d3 100644 --- a/_posts/02-01-01-Code-Style-Guide.md +++ b/_posts/02-01-01-Code-Style-Guide.md @@ -12,7 +12,7 @@ Lithium, etc are starting to adopt. You can use them for your own projects, or c 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, and applications that implement the components can have consistency even when working with -lots of third-party code. The first few recommendations are designed to be a super-set of the previous recomendation. +lots of third-party code. The first few recommendations are designed to be a super-set of the previous recommendation. * [Read about PSR-0][psr0] * [Read about PSR-1][psr1] diff --git a/_posts/03-02-01-Programming-Paradigms.md b/_posts/03-02-01-Programming-Paradigms.md index 57958d121..eb0d5676d 100644 --- a/_posts/03-02-01-Programming-Paradigms.md +++ b/_posts/03-02-01-Programming-Paradigms.md @@ -11,7 +11,7 @@ the years, notably adding a solid object-oriented model in PHP 5.0 (2004), anony ### Object-oriented Programming PHP has a very complete set of object-oriented programming features including support for classes, abstract classes, -interfaces, inheritence, constructors, cloning, exceptions, and more. +interfaces, inheritance, constructors, cloning, exceptions, and more. * [Read about Object-oriented PHP][oop] * [Read about Traits][traits] diff --git a/_posts/06-01-01-Databases.md b/_posts/06-01-01-Databases.md index 2df162496..bf20ecbc3 100644 --- a/_posts/06-01-01-Databases.md +++ b/_posts/06-01-01-Databases.md @@ -13,7 +13,7 @@ database — and that can get silly. As an extra note on native drivers, the mysql extension for PHP is no longer in active development, and the official status since PHP 5.4.0 is "Long term deprecation". This means it will be removed within the next few releases, so by PHP 5.6 (or whatever comes after 5.5) it may well be gone. If you are using `mysql_connect()` and `mysql_query()` in your applications then you will be faced with a rewrite at some point down the -line, so the best option is to replace mysql usage with mysqli or PDO in your applications within your own development shedules so you won't +line, so the best option is to replace mysql usage with mysqli or PDO in your applications within your own development schedules so you won't be rushed later on. _If you are starting from scratch then absolutely do not use the mysql extension: use the [MySQLi extension][mysqli], or use PDO._ * [PHP: Choosing an API for MySQL](http://php.net/manual/en/mysqlinfo.api.choosing.php) From f03a14bcb50ec934c91d955087715a3a78d90e5d Mon Sep 17 00:00:00 2001 From: maliayas Date: Sun, 16 Dec 2012 06:32:52 +0200 Subject: [PATCH 086/843] Fixed typo with variable name. --- _posts/07-03-01-Password-Hashing.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_posts/07-03-01-Password-Hashing.md b/_posts/07-03-01-Password-Hashing.md index cb611bfaf..104736850 100644 --- a/_posts/07-03-01-Password-Hashing.md +++ b/_posts/07-03-01-Password-Hashing.md @@ -18,9 +18,9 @@ Below we hash a string, we then check the hash against a new string. Because our Date: Thu, 3 Jan 2013 12:16:46 +0000 Subject: [PATCH 087/843] Fixed a minor typo. --- _posts/06-01-01-Databases.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/06-01-01-Databases.md b/_posts/06-01-01-Databases.md index bf20ecbc3..cfaa556f8 100644 --- a/_posts/06-01-01-Databases.md +++ b/_posts/06-01-01-Databases.md @@ -38,7 +38,7 @@ $pdo->query("SELECT name 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. Just imagine if a hacker passes in an inventive `id` parameter by calling a URL like -`http://domain.com/?id=1%3BDELETE+FROM+users`. This will set the `$_GET['id']` variable to `id=1;DELETE FROM users` +`http://domain.com/?id=1%3BDELETE+FROM+users`. This will set the `$_GET['id']` variable to `1;DELETE FROM users` which will delete all of your users! Instead, you should sanitize the ID input using PDO bound parameters. {% highlight php %} From 3a79e14a368e75e9158f5c451b2b33bbc39b17b5 Mon Sep 17 00:00:00 2001 From: Phil Sturgeon Date: Thu, 3 Jan 2013 11:23:35 -0500 Subject: [PATCH 088/843] Typo --- pages/The-Basics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/The-Basics.md b/pages/The-Basics.md index b905277f0..147df30f6 100644 --- a/pages/The-Basics.md +++ b/pages/The-Basics.md @@ -325,4 +325,4 @@ vs. echo 'A very long string of text'; // uses 1MB memory {% endhighlight %} -* [Performace tips](https://developers.google.com/speed/articles/optimizing-php) \ No newline at end of file +* [Performance tips](https://developers.google.com/speed/articles/optimizing-php) From c7774d7f23efa9cef55409281958a1f87854e9b0 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Sun, 6 Jan 2013 16:06:26 +0100 Subject: [PATCH 089/843] Update _posts/10-03-01-Object-Caching.md Adjusted caching example-pattern, so it will not trigger 2 cache-lookups --- _posts/10-03-01-Object-Caching.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/_posts/10-03-01-Object-Caching.md b/_posts/10-03-01-Object-Caching.md index b812eb04d..f00e8b45b 100644 --- a/_posts/10-03-01-Object-Caching.md +++ b/_posts/10-03-01-Object-Caching.md @@ -32,12 +32,13 @@ Example logic using APC: {% highlight php %} Date: Tue, 8 Jan 2013 02:57:02 -0600 Subject: [PATCH 090/843] Update _posts/06-01-01-Databases.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Found a typo on line 68:   missing form another -> missing from another  --- _posts/06-01-01-Databases.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/06-01-01-Databases.md b/_posts/06-01-01-Databases.md index cfaa556f8..ce47ec4fa 100644 --- a/_posts/06-01-01-Databases.md +++ b/_posts/06-01-01-Databases.md @@ -65,7 +65,7 @@ unless of course you are using persistent connections. ## Abstraction Layers Many frameworks provide their own abstraction layer which may or may not sit on top of PDO. These will often emulate features for -one database system that another is missing form another by wrapping your queries in PHP methods, giving you actual database abstraction. +one database system that another is missing from another by wrapping your queries in PHP methods, giving you actual database abstraction. This will of course add a little overhead, but if you are building a portable application that needs to work with MySQL, PostgreSQL and SQLite then a little overhead will be worth it the sake of code cleanliness. From 0e4171332c698ee588666f79d15f25a097051caa Mon Sep 17 00:00:00 2001 From: Dennis Bartlett Date: Tue, 8 Jan 2013 03:15:19 -0600 Subject: [PATCH 091/843] Update _posts/07-03-01-Password-Hashing.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Typo Found on line 13:  It will updated -> It will be updated  --- _posts/07-03-01-Password-Hashing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/07-03-01-Password-Hashing.md b/_posts/07-03-01-Password-Hashing.md index 104736850..3640e482c 100644 --- a/_posts/07-03-01-Password-Hashing.md +++ b/_posts/07-03-01-Password-Hashing.md @@ -10,7 +10,7 @@ It is important that you properly [_hash_][3] passwords before storing them. Pas **Hashing passwords with `password_hash`** -In PHP 5.5 `password_hash` will be introduced. At this time it is using BCrypt, the strongest algorithm currently supported by PHP. It will updated in the future to support more algorithms as needed though. The `password_compat` library was created to provide forward compatibility for PHP >= 5.3.7. +In PHP 5.5 `password_hash` will be introduced. At this time it is using BCrypt, the strongest algorithm currently supported by PHP. It will be updated in the future to support more algorithms as needed though. The `password_compat` library was created to provide forward compatibility for PHP >= 5.3.7. Below we hash a string, we then check the hash against a new string. Because our two source strings are different ('secret-password' vs. 'bad-password') this login will fail. From 7850ebd5e43c89b504c8960248f7ed47a426b53d Mon Sep 17 00:00:00 2001 From: Corey McMahon Date: Wed, 9 Jan 2013 17:59:24 +1100 Subject: [PATCH 092/843] Added singleton pattern to the Design-Patterns page --- pages/Design-Patterns.md | 44 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/pages/Design-Patterns.md b/pages/Design-Patterns.md index 53b0f923b..cb3a9a802 100644 --- a/pages/Design-Patterns.md +++ b/pages/Design-Patterns.md @@ -62,6 +62,50 @@ yourself a lot of trouble down the road by using factories. * [Factory pattern on Wikipedia](https://en.wikipedia.org/wiki/Factory_pattern) +## Singleton + +When designing web applications, it often makes sense conceptually and architecturally to allow access to one and +only one instance of a particular class. The singleton pattern enables us to do this. + +{% highlight php %} + Date: Sat, 12 Jan 2013 06:28:05 +0600 Subject: [PATCH 093/843] Update _posts/12-01-01-Community.md There is a large PHP Programmers community on G+ community. There are around 9000+ PHP programmers from around the globe are still active. I have added that link to this doc. Hopefully it will help the people who trust phptherightway. It would be great if you can merge this. Thanks, Shaharia Moderator PHP Programmers, G+ Community --- _posts/12-01-01-Community.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/_posts/12-01-01-Community.md b/_posts/12-01-01-Community.md index 3986e7f1d..bd36d7ca7 100644 --- a/_posts/12-01-01-Community.md +++ b/_posts/12-01-01-Community.md @@ -1,6 +1,6 @@ # Community {#community_title} -The PHP community is as diverse as it is large, and it's members are ready and willing to support new PHP programmers. You should consider joining your local PHP user group (PUG) or attending larger PHP conferences to learn more about the best practices shown here. You can also hang out on IRC in the #phpc channel on irc.freenode.com and follow the [@phpc][phpc-twitter] twitter account. Get out there, meet new developers, learn new topics and, above all, make new friends. +The PHP community is as diverse as it is large, and it's members are ready and willing to support new PHP programmers. You should consider joining your local PHP user group (PUG) or attending larger PHP conferences to learn more about the best practices shown here. You can also hang out on IRC in the #phpc channel on irc.freenode.com and follow the [@phpc][phpc-twitter] twitter account. Get out there, meet new developers, learn new topics and, above all, make new friends. Also there is a large Google+ Community for PHP Prorammers where 9,000+ PHP Programmers are available to discuss about your problem and solving other problem. You can also join there on Google+ community for [PHP Programmer][php-programmers-gplus] [Read the Official PHP Events Calendar][php-calendar] @@ -22,3 +22,4 @@ The PHP community also hosts larger regional and national conferences in many co [php-wiki]: https://wiki.php.net/usergroups [php-conf]: http://php.net/conferences/index.php [phpc-twitter]: https://twitter.com/phpc +[php-programmers-gplus]: https://plus.google.com/u/0/communities/104245651975268426012 From 210377b84231458a0a2471c0221b49f1d2f9b40c Mon Sep 17 00:00:00 2001 From: Shaharia Azam Date: Sat, 12 Jan 2013 06:58:58 +0600 Subject: [PATCH 094/843] Update _posts/12-01-01-Community.md Few spelling mistake correction --- _posts/12-01-01-Community.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/12-01-01-Community.md b/_posts/12-01-01-Community.md index bd36d7ca7..98feda243 100644 --- a/_posts/12-01-01-Community.md +++ b/_posts/12-01-01-Community.md @@ -1,6 +1,6 @@ # Community {#community_title} -The PHP community is as diverse as it is large, and it's members are ready and willing to support new PHP programmers. You should consider joining your local PHP user group (PUG) or attending larger PHP conferences to learn more about the best practices shown here. You can also hang out on IRC in the #phpc channel on irc.freenode.com and follow the [@phpc][phpc-twitter] twitter account. Get out there, meet new developers, learn new topics and, above all, make new friends. Also there is a large Google+ Community for PHP Prorammers where 9,000+ PHP Programmers are available to discuss about your problem and solving other problem. You can also join there on Google+ community for [PHP Programmer][php-programmers-gplus] +The PHP community is as diverse as it is large, and it's members are ready and willing to support new PHP programmers. You should consider joining your local PHP user group (PUG) or attending larger PHP conferences to learn more about the best practices shown here. You can also hang out on IRC in the #phpc channel on irc.freenode.com and follow the [@phpc][phpc-twitter] twitter account. Get out there, meet new developers, learn new topics and, above all, make new friends. Also there is a large Google+ Community for PHP Programmers where 9,000+ PHP Programmers are available to discuss about problem and solving others problem by each other. You can also join there on Google+ community for [PHP Programmer][php-programmers-gplus] [Read the Official PHP Events Calendar][php-calendar] From 8d5ab66099a78496eb7eb7f0add7f50979a0203f Mon Sep 17 00:00:00 2001 From: Corey McMahon Date: Mon, 14 Jan 2013 15:28:25 +1100 Subject: [PATCH 095/843] Added a sentence defining the benefit or using DI over the singleton pattern --- pages/Design-Patterns.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pages/Design-Patterns.md b/pages/Design-Patterns.md index cb3a9a802..d57b79b0b 100644 --- a/pages/Design-Patterns.md +++ b/pages/Design-Patterns.md @@ -101,8 +101,9 @@ request lifecycle in a web application. This typically occurs when we have globa class) or a shared resource (such as an event queue). You should be wary when using the singleton pattern, as by its very nature it introduces global state into your -application, reducing testability. In most cases, dependency injection can (and should) be used in place of -singleton objects. +application, reducing testability. In most cases, dependency injection can (and should) be used in place of a +singleton class. Using dependency injection means that we do not introduce unnecessary coupling into the design of our +application, as the object using the shared or global resource requires no knowledge of a concretely defined class. * [Singleton pattern on Wikipedia](https://en.wikipedia.org/wiki/Singleton_pattern) From 7bf6835bb755049ebea74a7d1f9c127620ff39d4 Mon Sep 17 00:00:00 2001 From: Phil Sturgeon Date: Tue, 15 Jan 2013 13:46:56 -0500 Subject: [PATCH 096/843] Added Laravel 4's "Illuminate Components" --- _posts/11-03-01-Components.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/_posts/11-03-01-Components.md b/_posts/11-03-01-Components.md index ffc058d1a..e29a3ca1c 100644 --- a/_posts/11-03-01-Components.md +++ b/_posts/11-03-01-Components.md @@ -22,4 +22,5 @@ just another repository for reusable components: * [Aura](http://auraphp.github.com/) * [FuelPHP (2.0 only)](https://github.com/fuelphp) -* [Symfony Components](http://symfony.com/doc/current/components/index.html) \ No newline at end of file +* [Laravel's "Illuminate Components"](https://github.com/illuminate) +* [Symfony Components](http://symfony.com/doc/current/components/index.html) From 3b9211bf3db128f8b44f626824b684e2729429d0 Mon Sep 17 00:00:00 2001 From: Akshay Agarwal Date: Sun, 20 Jan 2013 19:47:53 +0530 Subject: [PATCH 097/843] Fixing minor typo --- _posts/10-03-01-Object-Caching.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/10-03-01-Object-Caching.md b/_posts/10-03-01-Object-Caching.md index f00e8b45b..f6096251c 100644 --- a/_posts/10-03-01-Object-Caching.md +++ b/_posts/10-03-01-Object-Caching.md @@ -19,7 +19,7 @@ one real limitation of APC is that it is tied to the server it's installed on. M as a separate service and can be accessed across the network, meaning that you can store objects in a hyper-fast data store in a central location and many different systems can pull from it. -Note that when running PHP as a (Fast-)CGI application inside your webserver, every PHP processes will have its own +Note that when running PHP as a (Fast-)CGI application inside your webserver, every PHP process will have its own cache, i.e. APC data is not shared between your worker processes. In these cases, you might want to consider using memcached instead, as it's not tied to the PHP processes. From 80e80579b6ca228f2e0c1710b7929c86cb0b0946 Mon Sep 17 00:00:00 2001 From: Akshay Agarwal Date: Mon, 21 Jan 2013 03:26:27 +0530 Subject: [PATCH 098/843] Adding PSR-3 standards to the list --- _posts/02-01-01-Code-Style-Guide.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/_posts/02-01-01-Code-Style-Guide.md b/_posts/02-01-01-Code-Style-Guide.md index b83e831d3..380154bd3 100644 --- a/_posts/02-01-01-Code-Style-Guide.md +++ b/_posts/02-01-01-Code-Style-Guide.md @@ -6,7 +6,7 @@ PHP developers to choose several of these and combine them into a single project their projects. 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, +style recommendations, known as [PSR-0][psr0], [PSR-1][psr1], [PSR-2][psr2] and [PSR-3][psr3]. 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. @@ -17,6 +17,7 @@ lots of third-party code. The first few recommendations are designed to be a sup * [Read about PSR-0][psr0] * [Read about PSR-1][psr1] * [Read about PSR-2][psr2] +* [Read about PSR-3][psr3] You can use [PHP_CodeSniffer][phpcs] to check code against these recommendations. Use Fabien Potencier's [PHP Coding Standards Fixer][phpcsfixer] to automatically modify your code syntax so that it @@ -28,6 +29,7 @@ English is preferred for all symbol names and code infrastructure. Comments may [psr0]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md [psr1]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-1-basic-coding-standard.md [psr2]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md +[psr3]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md [phpcs]: http://pear.php.net/package/PHP_CodeSniffer/ [phpcs-psr]: https://github.com/klaussilveira/phpcs-psr [phpcsfixer]: http://cs.sensiolabs.org/ From 10d5be6802c5120e6ec9acf56c797d099b1e75e6 Mon Sep 17 00:00:00 2001 From: David Joos Date: Mon, 11 Feb 2013 09:30:13 +0000 Subject: [PATCH 099/843] Addition of Symfony to the shortlist of projects --- _posts/02-01-01-Code-Style-Guide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/02-01-01-Code-Style-Guide.md b/_posts/02-01-01-Code-Style-Guide.md index 380154bd3..304dc88df 100644 --- a/_posts/02-01-01-Code-Style-Guide.md +++ b/_posts/02-01-01-Code-Style-Guide.md @@ -7,7 +7,7 @@ their projects. 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], [PSR-2][psr2] and [PSR-3][psr3]. 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, +these recommendations are merely a set of rules that some projects like Drupal, Zend, Symfony, 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 From ba77b5918f580475f4148ddab16837073da10ccc Mon Sep 17 00:00:00 2001 From: David Joos Date: Mon, 11 Feb 2013 09:55:29 +0000 Subject: [PATCH 100/843] Fixed typo: it > is --- pages/Design-Patterns.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/Design-Patterns.md b/pages/Design-Patterns.md index d57b79b0b..3f510ac2d 100644 --- a/pages/Design-Patterns.md +++ b/pages/Design-Patterns.md @@ -119,7 +119,7 @@ and gives you a central place to hook in code that should be run for every reque ## Model-View-Controller The model-view-controller (MVC) pattern and its relatives HMVC and MVVM let you break up code into logical objects that -serve very specific purposes. Models serve as a data access layer where data it fetched and returned in formats usable +serve very specific purposes. Models serve as a data access layer where data is fetched and returned in formats usable throughout your application. Controllers handle the request, process the data returned from models and load views to send in the response. And views are display templates (markup, xml, etc) that are sent in the response to the web browser. From bc1823ce8626e6a19c2676c7a0c11cf93c222a44 Mon Sep 17 00:00:00 2001 From: Patrick Connolly Date: Wed, 13 Feb 2013 13:00:09 -0500 Subject: [PATCH 101/843] Adds Heroku to PaaS provider list. --- _posts/11-01-01-Resources.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/_posts/11-01-01-Resources.md b/_posts/11-01-01-Resources.md index 2fede3d52..c6eed0c32 100644 --- a/_posts/11-01-01-Resources.md +++ b/_posts/11-01-01-Resources.md @@ -25,6 +25,8 @@ * [PagodaBox](https://pagodabox.com/) * [AppFog](https://appfog.com/) +* [Heroku](https://heroku.com) + (PHP support is undocumented but based on stable Facebook partnership [[link]](http://net.tutsplus.com/tutorials/php/quick-tip-deploy-php-to-heroku-in-seconds/)) * [fortrabbit](http://fortrabbit.com/) * [Engine Yard Orchestra PHP Platform](http://www.engineyard.com/products/orchestra/) * [Red Hat OpenShift Platform](http://www.redhat.com/products/cloud-computing/openshift/) From 5b6928a08b7e5e4500783f5fd6985459eee368d8 Mon Sep 17 00:00:00 2001 From: Wil Moore III Date: Mon, 18 Feb 2013 03:31:57 -0700 Subject: [PATCH 102/843] Update _posts/05-05-01-Exceptions.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The original purpose of this edit was to correct a gramatical error; however, this turned into a more detailed explanation of `Exception` sub-classing. --- _posts/05-05-01-Exceptions.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/_posts/05-05-01-Exceptions.md b/_posts/05-05-01-Exceptions.md index 67262a797..685caa1a9 100644 --- a/_posts/05-05-01-Exceptions.md +++ b/_posts/05-05-01-Exceptions.md @@ -42,7 +42,8 @@ catch(Fuel\Email\SendingFailedException $e) ### SPL Exceptions -An Exception by default has no meaning and the most common to give it meaning is by setting its name: +The generic `Exception` class provides very little debugging context for the developer; however, to remedy this, +it is possible to create a specialized `Exception` type by sub-classing the generic `Exception` class: {% highlight php %} Date: Fri, 1 Mar 2013 15:20:47 -0500 Subject: [PATCH 103/843] Updated Code Style Guide People were getting the idea that PSR's were being forced down their throats. Now we're recommending the PEAR style guide (only ever intended for PEAR packages) and the Zend style guide (only ever meant for Zend projects) as well as the PSRs (only ever intended for FIG projects). --- _posts/02-01-01-Code-Style-Guide.md | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/_posts/02-01-01-Code-Style-Guide.md b/_posts/02-01-01-Code-Style-Guide.md index 304dc88df..1cd16f920 100644 --- a/_posts/02-01-01-Code-Style-Guide.md +++ b/_posts/02-01-01-Code-Style-Guide.md @@ -5,32 +5,37 @@ PHP developers to choose several of these and combine them into a single project (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 recommendations, known as [PSR-0][psr0], [PSR-1][psr1], [PSR-2][psr2] and [PSR-3][psr3]. Don't let the funny names confuse you, -these recommendations are merely a set of rules that some projects like Drupal, Zend, Symfony, 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] 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, Symfony, 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, and applications that implement the components can have consistency even when working with -lots of third-party code. The first few recommendations are designed to be a super-set of the previous recommendation. +Ideally you should write PHP code that adheres to a known standard. This could be any combination of PSR's, or one +of the coding standards made by PEAR or Zend. This means other developers can easily read and work with your code, +and applications that implement the components can have consistency even when working with lots of third-party code. * [Read about PSR-0][psr0] * [Read about PSR-1][psr1] * [Read about PSR-2][psr2] -* [Read about PSR-3][psr3] +* [Read about PEAR Coding Standards][pear-cs] +* [Read about Zend Coding Standards][zend-cs] + +You can use [PHP_CodeSniffer][phpcs] to check code against any one of these recommendations, and plugins for text editors +like [Sublime Text 2][st-cs] to be given real time feedback. -You can use [PHP_CodeSniffer][phpcs] to check code against these recommendations. Use Fabien Potencier's [PHP Coding Standards Fixer][phpcsfixer] to automatically modify your code syntax so that it conforms with these standards, saving you from fixing each problem by hand. -English is preferred for all symbol names and code infrastructure. Comments may be written in any language easily readable by all current and future parties who may be working on the codebase. +English is preferred for all symbol names and code infrastructure. Comments may be written in any language easily readable +by all current and future parties who may be working on the codebase. [fig]: http://www.php-fig.org/ [psr0]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md [psr1]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-1-basic-coding-standard.md [psr2]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md [psr3]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md +[pear-cs]: http://pear.php.net/manual/en/standards.php +[zend-cs]: http://framework.zend.com/wiki/display/ZFDEV2/Coding+Standards [phpcs]: http://pear.php.net/package/PHP_CodeSniffer/ -[phpcs-psr]: https://github.com/klaussilveira/phpcs-psr +[st-cs]: https://github.com/benmatselby/sublime-phpcs [phpcsfixer]: http://cs.sensiolabs.org/ - From 31d89020d6e4623b033a6f2aff29519e85d1abad Mon Sep 17 00:00:00 2001 From: mkaatman Date: Wed, 6 Mar 2013 16:21:06 -0600 Subject: [PATCH 104/843] Update 12-01-01-Community.md A little bit of grammar cleanup. Added a link to the web irc freenode client and stackoverflow. --- _posts/12-01-01-Community.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/_posts/12-01-01-Community.md b/_posts/12-01-01-Community.md index 98feda243..4af118509 100644 --- a/_posts/12-01-01-Community.md +++ b/_posts/12-01-01-Community.md @@ -1,6 +1,6 @@ # Community {#community_title} -The PHP community is as diverse as it is large, and it's members are ready and willing to support new PHP programmers. You should consider joining your local PHP user group (PUG) or attending larger PHP conferences to learn more about the best practices shown here. You can also hang out on IRC in the #phpc channel on irc.freenode.com and follow the [@phpc][phpc-twitter] twitter account. Get out there, meet new developers, learn new topics and, above all, make new friends. Also there is a large Google+ Community for PHP Programmers where 9,000+ PHP Programmers are available to discuss about problem and solving others problem by each other. You can also join there on Google+ community for [PHP Programmer][php-programmers-gplus] +The PHP community is as diverse as it is large, and its members are ready and willing to support new PHP programmers. Consider joining your local PHP user group (PUG) or attending larger PHP conferences to learn more about the best practices shown here. You can hang out on IRC in the #phpc channel on [irc.freenode.com][php-irc] and follow the [@phpc][phpc-twitter] twitter account. Get out there, meet new developers, learn new topics, and above all, make new friends! Other community resources include the Google+ PHP [Programmer community][php-programmers-gplus] and [StackOverflow][php-so]. [Read the Official PHP Events Calendar][php-calendar] @@ -23,3 +23,5 @@ The PHP community also hosts larger regional and national conferences in many co [php-conf]: http://php.net/conferences/index.php [phpc-twitter]: https://twitter.com/phpc [php-programmers-gplus]: https://plus.google.com/u/0/communities/104245651975268426012 +[php-irc]: http://webchat.freenode.net/ +[php-so]: http://stackoverflow.com/questions/tagged/php From 5f467ed7e327c98082af611b2ca252e773bee415 Mon Sep 17 00:00:00 2001 From: Matt Robinson Date: Sun, 10 Mar 2013 21:07:05 +0000 Subject: [PATCH 105/843] Update Composer advice Notable changes: * Use composer itself to create `composer.json` file. * Brief mention of flexible versioning * Brief mention of the security advisory checker * Brief mention of how to update --- _posts/04-02-01-Composer-and-Packagist.md | 27 ++++++++++++++--------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/_posts/04-02-01-Composer-and-Packagist.md b/_posts/04-02-01-Composer-and-Packagist.md index 0fbae9fc4..316e1a7d5 100644 --- a/_posts/04-02-01-Composer-and-Packagist.md +++ b/_posts/04-02-01-Composer-and-Packagist.md @@ -18,7 +18,7 @@ This will download `composer.phar` (a PHP binary archive). You can run this with ### 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: +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 @@ -39,19 +39,15 @@ When you come across documentation that states to run Composer as `php composer. ### 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. +Composer keeps track of your project's dependencies in a file called `composer.json`. You can manage it by hand if you like, or use Composer itself. The `php composer.phar require` command adds a project dependency and if you don't have a `composer.json` file, one will be created. Here's an example that adds [Twig][2] as a dependency of your project. Run it in your project's root directory where you've downloaded `composer.phar`: - { - "require": { - "twig/twig": "1.8.*" - } - } + php composer.phar require twig/twig:~1.8 -Next, run this command from your project root directory. +Alternatively the `php composer.phar init` command will guide you through creating a full `composer.json` file for your project. Either way, once you've created your `composer.json` file you can tell Composer to download and install your dependencies into the `vendors/` directory. This also applies to projects you've downloaded that already provide a `composer.json` file: 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. +Next, add this line to your application's primary PHP file; this will tell PHP to use Composer's autoloader for your project dependencies. {% highlight php %} Date: Wed, 13 Mar 2013 15:52:19 +0100 Subject: [PATCH 106/843] Removed trailing whitespaces. --- pages/Design-Patterns.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/pages/Design-Patterns.md b/pages/Design-Patterns.md index 3f510ac2d..041928a36 100644 --- a/pages/Design-Patterns.md +++ b/pages/Design-Patterns.md @@ -64,11 +64,11 @@ yourself a lot of trouble down the road by using factories. ## Singleton -When designing web applications, it often makes sense conceptually and architecturally to allow access to one and +When designing web applications, it often makes sense conceptually and architecturally to allow access to one and only one instance of a particular class. The singleton pattern enables us to do this. {% highlight php %} - Date: Wed, 13 Mar 2013 16:21:22 +0100 Subject: [PATCH 107/843] Enhanced the example for the Singleton design pattern. - Moved static variable into the static creation method getInstance. - Replaced "new self();" with "new static" (late static binding to allow subclassing). - Changed visibility of __construct to protected. - Added the two private methods __clone and __wakeup. - Added DocBlock comments. - Updated description and enhanced with links to the PHP manual. --- pages/Design-Patterns.md | 66 ++++++++++++++++++++++++++++++++-------- 1 file changed, 54 insertions(+), 12 deletions(-) diff --git a/pages/Design-Patterns.md b/pages/Design-Patterns.md index 041928a36..75c14d3b3 100644 --- a/pages/Design-Patterns.md +++ b/pages/Design-Patterns.md @@ -71,30 +71,72 @@ only one instance of a particular class. The singleton pattern enables us to do Date: Fri, 5 Apr 2013 19:16:26 -0400 Subject: [PATCH 108/843] Add links to Italian and Catalan translations --- _includes/welcome.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/_includes/welcome.md b/_includes/welcome.md index f97525e03..bf395adfc 100644 --- a/_includes/welcome.md +++ b/_includes/welcome.md @@ -9,8 +9,10 @@ standards, and links to authoritative tutorials around the Web. _PHP: The Right Way_ is (or soon will be) translated into many different languages: * [English](http://www.phptherightway.com) +* [Catalan](http://ca.phptherightway.com) * [Chinese](http://wulijun.github.com/php-the-right-way) * [Japanese](http://ja.phptherightway.com) +* [Italian](http://it.phptherightway.com) * [Polish](http://pl.phptherightway.com/) * [Portuguese](http://br.phptherightway.com/) * Russian (Coming Soon) From 38822d6bc06f6f5a08f1ff79bc8c15aa34a4ade2 Mon Sep 17 00:00:00 2001 From: Robert Wetzlmayr Date: Thu, 11 Apr 2013 08:16:54 +0200 Subject: [PATCH 109/843] Introducing the German translation. --- _includes/welcome.md | 1 + 1 file changed, 1 insertion(+) diff --git a/_includes/welcome.md b/_includes/welcome.md index bf395adfc..06852dc03 100644 --- a/_includes/welcome.md +++ b/_includes/welcome.md @@ -19,6 +19,7 @@ _PHP: The Right Way_ is (or soon will be) translated into many different languag * [Spanish](http://es.phptherightway.com) * [Ukrainian](http://iflista.github.com/php-the-right-way/) * [Bulgarian](http://bg.phptherightway.com/) +* [German](http://rwetzlmayr.github.io/php-the-right-way/) ## Disclaimer From 04ae71568bd7ae25b698b2d8e0ecf02d2662c0d9 Mon Sep 17 00:00:00 2001 From: Phil Sturgeon Date: Fri, 12 Apr 2013 12:12:36 -0400 Subject: [PATCH 110/843] Closes #240: Explain how to manage PEAR dependencies with Composer --- _posts/04-03-01-PEAR.md | 44 ++++++++++++++++++++++++++++++++++++ _posts/11-01-01-Resources.md | 2 +- 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/_posts/04-03-01-PEAR.md b/_posts/04-03-01-PEAR.md index 61d0ce406..72e30b1e9 100644 --- a/_posts/04-03-01-PEAR.md +++ b/_posts/04-03-01-PEAR.md @@ -33,7 +33,51 @@ installing. See the [Using channel docs][4] for more information on this topic. * [Learn about PEAR][1] +### Handling PEAR dependencies with Composer + +If you are already using [Composer][5] and you would like to install some PEAR code too, you can use +Composer to handle your PEAR dependencies. This example will install code from `pear2.php.net`: + +{% highlight json %} +{ + "repositories": [ + { + "type": "pear", + "url": "http://pear2.php.net" + } + ], + "require": { + "pear-pear2/PEAR2_Text_Markdown": "*", + "pear-pear2/PEAR2_HTTP_Request": "*" + } +} +{% endhighlight %} + +The first section `"repositories"` will be used to let Composer know it should "initialise" +(or "discover" in PEAR terminology) the pear repo. Then the require section will prefix the package +name like this: + +> pear-channel/Package + +The "pear" prefix is hardcoded to avoid any conflicts, as a pear channel could be the same as another packages vendor name for example, then the channel short name (or full URL) can be used +to reference which channel the package is in. + +When this code is installed it will be available in your vendor directory and automatically +available through the Comoser autoloader: + +> vendor/pear-pear2.php.net/PEAR2_HTTP_Request/pear2/HTTP/Request.php + +To use this PEAR package simply reference it like so: + +{% highlight php %} +$request = new pear2\HTTP\Request(); +{% endhighlight %} + +* [Learn more about using PEAR with Composer][6] + [1]: http://pear.php.net/ [2]: http://pear.php.net/manual/en/installation.getting.php [3]: http://pear.php.net/packages.php [4]: http://pear.php.net/manual/en/guide.users.commandline.channels.php +[5]: /#composer_and_packagist +[6]: http://getcomposer.org/doc/05-repositories.md#pear diff --git a/_posts/11-01-01-Resources.md b/_posts/11-01-01-Resources.md index c6eed0c32..cd3f258e2 100644 --- a/_posts/11-01-01-Resources.md +++ b/_posts/11-01-01-Resources.md @@ -26,7 +26,7 @@ * [PagodaBox](https://pagodabox.com/) * [AppFog](https://appfog.com/) * [Heroku](https://heroku.com) - (PHP support is undocumented but based on stable Facebook partnership [[link]](http://net.tutsplus.com/tutorials/php/quick-tip-deploy-php-to-heroku-in-seconds/)) + (PHP support is undocumented but based on stable Facebook partnership [link](http://net.tutsplus.com/tutorials/php/quick-tip-deploy-php-to-heroku-in-seconds/)) * [fortrabbit](http://fortrabbit.com/) * [Engine Yard Orchestra PHP Platform](http://www.engineyard.com/products/orchestra/) * [Red Hat OpenShift Platform](http://www.redhat.com/products/cloud-computing/openshift/) From 4be17cec521c84e3df8af2de5f2d111d4dfeb932 Mon Sep 17 00:00:00 2001 From: Phil Sturgeon Date: Fri, 12 Apr 2013 12:17:27 -0400 Subject: [PATCH 111/843] Closes #251: Conditional arguments or Conditional statements --- pages/The-Basics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/The-Basics.md b/pages/The-Basics.md index 147df30f6..f6f3484cf 100644 --- a/pages/The-Basics.md +++ b/pages/The-Basics.md @@ -36,7 +36,7 @@ if (strpos('testing', 'test') !== false) { // true, as strict comparison was * [Comparison operators](http://php.net/manual/en/language.operators.comparison.php) * [Comparison table](http://php.net/manual/en/types.comparisons.php) -## Conditional arguments +## Conditional statements ### If statements From a22c77cb8da208584d0935ab18e1f508f8e776e0 Mon Sep 17 00:00:00 2001 From: Matt Robinson Date: Sun, 21 Apr 2013 13:47:18 +0200 Subject: [PATCH 112/843] Fix incorrect links --- _posts/04-02-01-Composer-and-Packagist.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/_posts/04-02-01-Composer-and-Packagist.md b/_posts/04-02-01-Composer-and-Packagist.md index 316e1a7d5..fc67e0ba2 100644 --- a/_posts/04-02-01-Composer-and-Packagist.md +++ b/_posts/04-02-01-Composer-and-Packagist.md @@ -70,5 +70,6 @@ The [Security Advisories Checker][3] is a web service and a command-line tool, b [1]: http://packagist.org/ [2]: http://twig.sensiolabs.org -[3]: http://getcomposer.org/doc/00-intro.md -[4]: https://security.sensiolabs.org/ +[3]: https://security.sensiolabs.org/ +[4]: http://getcomposer.org/doc/00-intro.md + From 3f719140cb0bad0ae12db725ed8375ad504f5721 Mon Sep 17 00:00:00 2001 From: = Date: Wed, 8 May 2013 20:56:13 -0400 Subject: [PATCH 113/843] Add links to Russian and Korean translations --- _includes/welcome.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/_includes/welcome.md b/_includes/welcome.md index 06852dc03..b33ac376f 100644 --- a/_includes/welcome.md +++ b/_includes/welcome.md @@ -12,10 +12,11 @@ _PHP: The Right Way_ is (or soon will be) translated into many different languag * [Catalan](http://ca.phptherightway.com) * [Chinese](http://wulijun.github.com/php-the-right-way) * [Japanese](http://ja.phptherightway.com) +* [Korean](http://wafe.github.io/php-the-right-way/) * [Italian](http://it.phptherightway.com) * [Polish](http://pl.phptherightway.com/) * [Portuguese](http://br.phptherightway.com/) -* Russian (Coming Soon) +* [Russian](http://getjump.github.io/ru-php-the-right-way) * [Spanish](http://es.phptherightway.com) * [Ukrainian](http://iflista.github.com/php-the-right-way/) * [Bulgarian](http://bg.phptherightway.com/) From 2c8c2368a2f7cd891cfa4355419b723ecac24692 Mon Sep 17 00:00:00 2001 From: Bartosz Maciaszek Date: Fri, 10 May 2013 12:14:47 +0300 Subject: [PATCH 114/843] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index afcab6154..33b4446fc 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,7 @@ developers know where to find good information! * [Ukrainian](http://iflista.github.com/php-the-right-way) * [Portuguese](http://br.phptherightway.com/) * [Bulgarian](http://bg.phptherightway.com/) +* [Polish](http://pl.phptherightway.com/) ### Translations From 1753639937b167d86e81496c32e46a1af649ca63 Mon Sep 17 00:00:00 2001 From: Dan Cryer Date: Tue, 14 May 2013 13:04:25 +0200 Subject: [PATCH 115/843] Adding PHPCI to the continuous integration section. --- _posts/09-05-01-Building your Application.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/_posts/09-05-01-Building your Application.md b/_posts/09-05-01-Building your Application.md index d0708b1c3..59f6f9a09 100644 --- a/_posts/09-05-01-Building your Application.md +++ b/_posts/09-05-01-Building your Application.md @@ -71,4 +71,5 @@ languages including PHP. Further reading: * [Continuous Integration with Jenkins](http://jenkins-ci.org/) -* [Continuous Integration with Teamcity](http://www.jetbrains.com/teamcity/) \ No newline at end of file +* [Continuous Integration with PHPCI](http://www.phptesting.org/) +* [Continuous Integration with Teamcity](http://www.jetbrains.com/teamcity/) From 407ba97085421349bbda7de7f9b5566eb9517d2f Mon Sep 17 00:00:00 2001 From: = Date: Wed, 15 May 2013 16:34:56 -0400 Subject: [PATCH 116/843] Add Google Cloud Engine to supported PaaS providers --- _posts/11-01-01-Resources.md | 1 + 1 file changed, 1 insertion(+) diff --git a/_posts/11-01-01-Resources.md b/_posts/11-01-01-Resources.md index cd3f258e2..281bdc0b9 100644 --- a/_posts/11-01-01-Resources.md +++ b/_posts/11-01-01-Resources.md @@ -35,3 +35,4 @@ * [cloudControl](https://www.cloudcontrol.com/) * [Windows Azure](http://www.windowsazure.com/) * [Zend Developer Cloud](http://www.phpcloud.com/develop) +* [Google Cloud Engine](https://developers.google.com/appengine/docs/php/gettingstarted/) From cb085fee2c402146fbafb5358537c7282505bacb Mon Sep 17 00:00:00 2001 From: = Date: Wed, 15 May 2013 16:36:10 -0400 Subject: [PATCH 117/843] Fix Google Compute Engine name typo --- _posts/11-01-01-Resources.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/11-01-01-Resources.md b/_posts/11-01-01-Resources.md index 281bdc0b9..60fea6eb5 100644 --- a/_posts/11-01-01-Resources.md +++ b/_posts/11-01-01-Resources.md @@ -35,4 +35,4 @@ * [cloudControl](https://www.cloudcontrol.com/) * [Windows Azure](http://www.windowsazure.com/) * [Zend Developer Cloud](http://www.phpcloud.com/develop) -* [Google Cloud Engine](https://developers.google.com/appengine/docs/php/gettingstarted/) +* [Google Compute Engine](https://developers.google.com/appengine/docs/php/gettingstarted/) From eee34579761636b84db059e0d33504db9fcd3de9 Mon Sep 17 00:00:00 2001 From: = Date: Wed, 15 May 2013 16:51:28 -0400 Subject: [PATCH 118/843] Change Google PaaS to AppEngine --- _posts/11-01-01-Resources.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/11-01-01-Resources.md b/_posts/11-01-01-Resources.md index 60fea6eb5..af35107fb 100644 --- a/_posts/11-01-01-Resources.md +++ b/_posts/11-01-01-Resources.md @@ -35,4 +35,4 @@ * [cloudControl](https://www.cloudcontrol.com/) * [Windows Azure](http://www.windowsazure.com/) * [Zend Developer Cloud](http://www.phpcloud.com/develop) -* [Google Compute Engine](https://developers.google.com/appengine/docs/php/gettingstarted/) +* [Google AppEngine](https://developers.google.com/appengine/docs/php/gettingstarted/) From a6e052fee8c5201bed345fa1ad6a195d4bfcd621 Mon Sep 17 00:00:00 2001 From: = Date: Wed, 15 May 2013 16:52:41 -0400 Subject: [PATCH 119/843] Add space to Google App Engine name --- _posts/11-01-01-Resources.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/11-01-01-Resources.md b/_posts/11-01-01-Resources.md index af35107fb..4b4fe0733 100644 --- a/_posts/11-01-01-Resources.md +++ b/_posts/11-01-01-Resources.md @@ -35,4 +35,4 @@ * [cloudControl](https://www.cloudcontrol.com/) * [Windows Azure](http://www.windowsazure.com/) * [Zend Developer Cloud](http://www.phpcloud.com/develop) -* [Google AppEngine](https://developers.google.com/appengine/docs/php/gettingstarted/) +* [Google App Engine](https://developers.google.com/appengine/docs/php/gettingstarted/) From a042a78c1371f87b917258425c4bd147d00f01c6 Mon Sep 17 00:00:00 2001 From: rtretyakov Date: Sat, 18 May 2013 13:32:48 +0700 Subject: [PATCH 120/843] Add links to translations --- README.md | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 33b4446fc..15f33add1 100644 --- a/README.md +++ b/README.md @@ -34,11 +34,18 @@ developers know where to find good information! * [English](http://www.phptherightway.com) +* [Catalan] (http://ca.phptherightway.com) * [Chinese](http://wulijun.github.com/php-the-right-way) +* [Japanese] (http://ja.phptherightway.com) +* [Korean] (http://wafe.github.io/php-the-right-way) +* [Italian] (http://it.phptherightway.com) +* [Polish](http://pl.phptherightway.com) +* [Portuguese](http://br.phptherightway.com) +* [Russian] (http://getjump.github.io/ru-php-the-right-way) +* [Spanish] (http://es.phptherightway.com) * [Ukrainian](http://iflista.github.com/php-the-right-way) -* [Portuguese](http://br.phptherightway.com/) -* [Bulgarian](http://bg.phptherightway.com/) -* [Polish](http://pl.phptherightway.com/) +* [Bulgarian](http://bg.phptherightway.com) +* [German] (http://rwetzlmayr.github.io/php-the-right-way) ### Translations From a94d95f84d48df9ed452a50eaf79cf23a96fde87 Mon Sep 17 00:00:00 2001 From: Haydar Kulekci Date: Mon, 20 May 2013 14:52:44 +0300 Subject: [PATCH 121/843] added turkish translation --- README.md | 1 + _includes/welcome.md | 1 + 2 files changed, 2 insertions(+) diff --git a/README.md b/README.md index 15f33add1..c1717e3e3 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,7 @@ developers know where to find good information! * [Ukrainian](http://iflista.github.com/php-the-right-way) * [Bulgarian](http://bg.phptherightway.com) * [German] (http://rwetzlmayr.github.io/php-the-right-way) +* [Turkish](http://hkulekci.github.io/php-the-right-way/) ### Translations diff --git a/_includes/welcome.md b/_includes/welcome.md index b33ac376f..ecf87a3ac 100644 --- a/_includes/welcome.md +++ b/_includes/welcome.md @@ -21,6 +21,7 @@ _PHP: The Right Way_ is (or soon will be) translated into many different languag * [Ukrainian](http://iflista.github.com/php-the-right-way/) * [Bulgarian](http://bg.phptherightway.com/) * [German](http://rwetzlmayr.github.io/php-the-right-way/) +* [Turkish](http://hkulekci.github.io/php-the-right-way/) ## Disclaimer From 595fc95b4af84fb586d9eab55f929482d80c9806 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karol=20S=C3=B3jko?= Date: Wed, 22 May 2013 13:22:25 +0300 Subject: [PATCH 122/843] Added Prophecy to complementary testing tools --- _posts/08-04-01-Complementary-Testing-Tools.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/_posts/08-04-01-Complementary-Testing-Tools.md b/_posts/08-04-01-Complementary-Testing-Tools.md index 709d10acb..034937ad3 100644 --- a/_posts/08-04-01-Complementary-Testing-Tools.md +++ b/_posts/08-04-01-Complementary-Testing-Tools.md @@ -9,4 +9,5 @@ Besides individual testing and behavior driven frameworks, there are also a numb ### Tool Links * [Selenium](http://seleniumhq.org/) is a browser automation tool which can be [integrated with PHPUnit](http://www.phpunit.de/manual/3.1/en/selenium.html) -* [Mockery](https://github.com/padraic/mockery) is a Mock Object Framework which can be integrated with [PHPUnit](http://phpunit.de/) or [PHPSpec](http://www.phpspec.net/) \ No newline at end of file +* [Mockery](https://github.com/padraic/mockery) is a Mock Object Framework which can be integrated with [PHPUnit](http://phpunit.de/) or [PHPSpec](http://www.phpspec.net/) +* [Prophecy](https://github.com/phpspec/prophecy) is a highly opinionated yet very powerful and flexible PHP object mocking framework. It's integrated with [PHPSpec](http://www.phpspec.net/) and can be used with [PHPUnit](http://phpunit.de/). From 67ae0f80aa5306ff5d17e94494d1e2c79d48d72b Mon Sep 17 00:00:00 2001 From: Phil Sturgeon Date: Fri, 24 May 2013 12:07:00 -0300 Subject: [PATCH 123/843] Closes #271: I can't haz spelling --- _posts/04-03-01-PEAR.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/04-03-01-PEAR.md b/_posts/04-03-01-PEAR.md index 72e30b1e9..b48fa44ac 100644 --- a/_posts/04-03-01-PEAR.md +++ b/_posts/04-03-01-PEAR.md @@ -63,7 +63,7 @@ The "pear" prefix is hardcoded to avoid any conflicts, as a pear channel could b to reference which channel the package is in. When this code is installed it will be available in your vendor directory and automatically -available through the Comoser autoloader: +available through the Composer autoloader: > vendor/pear-pear2.php.net/PEAR2_HTTP_Request/pear2/HTTP/Request.php From dc059e98582d840273820444729aee5e41ba50c1 Mon Sep 17 00:00:00 2001 From: Simon R Jones Date: Fri, 31 May 2013 15:42:16 +0100 Subject: [PATCH 124/843] Removing back-slash from global functions for consistency with print_r() in factory example and since it's unecessary --- pages/Design-Patterns.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pages/Design-Patterns.md b/pages/Design-Patterns.md index 75c14d3b3..e284d6acf 100644 --- a/pages/Design-Patterns.md +++ b/pages/Design-Patterns.md @@ -122,12 +122,12 @@ class SingletonChild extends Singleton } $obj = Singleton::getInstance(); -\var_dump($obj === Singleton::getInstance()); // bool(true) +var_dump($obj === Singleton::getInstance()); // bool(true) $anotherObj = SingletonChild::getInstance(); -\var_dump($anotherObj === Singleton::getInstance()); // bool(false) +var_dump($anotherObj === Singleton::getInstance()); // bool(false) -\var_dump($anotherObj === SingletonChild::getInstance()); // bool(true) +var_dump($anotherObj === SingletonChild::getInstance()); // bool(true) {% endhighlight %} The code above implements the singleton pattern using a [*static* variable](http://php.net/language.variables.scope#language.variables.scope.static) and the static creation method `getInstance()`. @@ -135,7 +135,7 @@ Note the following: * The constructor [`__construct`](http://php.net/language.oop5.decon#object.construct) is declared as protected to prevent creating a new instance outside of the class via the `new` operator. * The magic method [`__clone`](http://php.net/language.oop5.cloning#object.clone) is declared as private to prevent cloning of an instance of the class via the [`clone`](http://php.net/language.oop5.cloning) operator. -* The magic method [`__wakeup`](http://php.net/language.oop5.magic#object.wakeup) is declared as private to prevent unserializing of an instance of the class via the global function [`\unserialize()`](http://php.net/function.unserialize). +* The magic method [`__wakeup`](http://php.net/language.oop5.magic#object.wakeup) is declared as private to prevent unserializing of an instance of the class via the global function [`unserialize()`](http://php.net/function.unserialize). * A new instance is created via [late static binding](http://php.net/language.oop5.late-static-bindings) in the static creation method `getInstance()` with the keyword `static`. This allows the subclassing of the class `Singleton` in the example. The singleton pattern is useful when we need to make sure we only have a single instance of a class for the entire From 4d2fcc80e7111b727358aa254b96de511810d553 Mon Sep 17 00:00:00 2001 From: Simon R Jones Date: Fri, 31 May 2013 15:43:46 +0100 Subject: [PATCH 125/843] Adding () after static keyword to make it clearer this is instantiating a new object --- pages/Design-Patterns.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/Design-Patterns.md b/pages/Design-Patterns.md index e284d6acf..e82a61d0a 100644 --- a/pages/Design-Patterns.md +++ b/pages/Design-Patterns.md @@ -82,7 +82,7 @@ class Singleton { static $instance = null; if (null === $instance) { - $instance = new static; + $instance = new static(); } return $instance; From 9e03a911cbd524d09fec470ba39b87ddf3d0ae03 Mon Sep 17 00:00:00 2001 From: Sean DuBois Date: Wed, 12 Jun 2013 22:02:40 -0500 Subject: [PATCH 126/843] fix length string -> fixed-length string --- _posts/07-03-01-Password-Hashing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/07-03-01-Password-Hashing.md b/_posts/07-03-01-Password-Hashing.md index 3640e482c..88f6f5579 100644 --- a/_posts/07-03-01-Password-Hashing.md +++ b/_posts/07-03-01-Password-Hashing.md @@ -6,7 +6,7 @@ isChild: true Eventually everyone builds a PHP application that relies on user login. Usernames and passwords are stored in a database and later used to authenticate users upon login. -It is important that you properly [_hash_][3] passwords before storing them. Password hashing is an irreversible, one way function performed against the users password. This produces a fix length string that can not be feasibly reversed. This means you can compare a hash against another to determine if they both came from the same source string, but you can not determine the original string. If passwords are not hashed and your database is accessed by an unauthorized third-party, all user accounts are now compromised. Some users may (unfortunately) use the same password for other services. Therefore, it is important to take security seriously. +It is important that you properly [_hash_][3] passwords before storing them. Password hashing is an irreversible, one way function performed against the users password. This produces a fixed-length string that can not be feasibly reversed. This means you can compare a hash against another to determine if they both came from the same source string, but you can not determine the original string. If passwords are not hashed and your database is accessed by an unauthorized third-party, all user accounts are now compromised. Some users may (unfortunately) use the same password for other services. Therefore, it is important to take security seriously. **Hashing passwords with `password_hash`** From 8d8fa72cca27b1246232b236a436e2a98fe502b2 Mon Sep 17 00:00:00 2001 From: Rogerio Prado de Jesus Date: Fri, 21 Jun 2013 18:21:42 -0300 Subject: [PATCH 127/843] Bump PHP current version to 5.5 in Use-the-Current-Stable-Version.md Signed-off-by: Rogerio Prado de Jesus --- _posts/01-02-01-Use-the-Current-Stable-Version.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/_posts/01-02-01-Use-the-Current-Stable-Version.md b/_posts/01-02-01-Use-the-Current-Stable-Version.md index ccb0b3599..d8d5881d5 100644 --- a/_posts/01-02-01-Use-the-Current-Stable-Version.md +++ b/_posts/01-02-01-Use-the-Current-Stable-Version.md @@ -1,11 +1,11 @@ --- -title: Use the Current Stable Version (5.4) +title: Use the Current Stable Version (5.5) isChild: true --- -## Use the Current Stable Version (5.4) {#use_the_current_stable_version_54_title} +## Use the Current Stable Version (5.5) {#use_the_current_stable_version_55_title} -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. If you are looking for a function or it's usage, the documentation on the [php.net][php-docs] website will have the answer. +If you are just getting started with PHP make sure to start with the current stable release of [PHP 5.5][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.5 fool you, it represents _major_ improvements. If you are looking for a function or it's usage, the documentation on the [php.net][php-docs] website will have the answer. [php-release]: http://www.php.net/downloads.php [php-docs]: http://www.php.net/manual/en/ From c0152e6b5307b21e9e848f7d5242429ac37ebee5 Mon Sep 17 00:00:00 2001 From: Rogerio Prado de Jesus Date: Fri, 21 Jun 2013 18:24:20 -0300 Subject: [PATCH 128/843] Inform that built-in web server is a 5.4+ feature Signed-off-by: Rogerio Prado de Jesus --- _posts/01-03-01-Built-in-Web-Server.md | 2 +- _posts/01-05-01-Windows-Setup.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/_posts/01-03-01-Built-in-Web-Server.md b/_posts/01-03-01-Built-in-Web-Server.md index 076a04ea2..2e9228d2a 100644 --- a/_posts/01-03-01-Built-in-Web-Server.md +++ b/_posts/01-03-01-Built-in-Web-Server.md @@ -5,7 +5,7 @@ isChild: true ## Built-in web server {#builtin_web_server_title} -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: +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 diff --git a/_posts/01-05-01-Windows-Setup.md b/_posts/01-05-01-Windows-Setup.md index c6430bf6c..87021e35f 100644 --- a/_posts/01-05-01-Windows-Setup.md +++ b/_posts/01-05-01-Windows-Setup.md @@ -7,7 +7,7 @@ isChild: true PHP is available in several ways for Windows. You can [download the binaries][php-downloads] and until recently you could use a '.msi' installer. The installer is no longer supported and stops at PHP 5.3.0. -For learning and local development you can use the built in webserver with PHP 5.4 so you don't need to worry about configuring it. If you +For learning and local development you can use the built in webserver with PHP 5.4+ so you don't need to worry about configuring it. If you would like an "all-in-one" which includes a full-blown webserver and MySQL too then tools such as the [Web Platform Installer][wpi], [Zend Server CE][zsce], [XAMPP][xampp] and [WAMP][wamp] will help get a Windows development environment up and running fast. That said, these tools will be a little different from production so be careful of environment differences if you are working on Windows and deploying to Linux. From e5618e81e4eae96b87da19373bddfc6e03a9ac34 Mon Sep 17 00:00:00 2001 From: Chris Christoff Date: Sat, 22 Jun 2013 10:14:19 -0300 Subject: [PATCH 129/843] Update 07-03-01-Password-Hashing.md --- _posts/07-03-01-Password-Hashing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/07-03-01-Password-Hashing.md b/_posts/07-03-01-Password-Hashing.md index 88f6f5579..9ae41fc78 100644 --- a/_posts/07-03-01-Password-Hashing.md +++ b/_posts/07-03-01-Password-Hashing.md @@ -10,7 +10,7 @@ It is important that you properly [_hash_][3] passwords before storing them. Pas **Hashing passwords with `password_hash`** -In PHP 5.5 `password_hash` will be introduced. At this time it is using BCrypt, the strongest algorithm currently supported by PHP. It will be updated in the future to support more algorithms as needed though. The `password_compat` library was created to provide forward compatibility for PHP >= 5.3.7. +In PHP 5.5 `password_hash` was be introduced. At this time it is using BCrypt, the strongest algorithm currently supported by PHP. It will be updated in the future to support more algorithms as needed though. The `password_compat` library was created to provide forward compatibility for PHP >= 5.3.7. Below we hash a string, we then check the hash against a new string. Because our two source strings are different ('secret-password' vs. 'bad-password') this login will fail. From 97caf3e9ef627cd3f09699154fca4d9b8e1ee6b4 Mon Sep 17 00:00:00 2001 From: Chris Christoff Date: Sat, 22 Jun 2013 10:16:01 -0300 Subject: [PATCH 130/843] Update 05-05-01-Exceptions.md --- _posts/05-05-01-Exceptions.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/_posts/05-05-01-Exceptions.md b/_posts/05-05-01-Exceptions.md index 685caa1a9..56311b65f 100644 --- a/_posts/05-05-01-Exceptions.md +++ b/_posts/05-05-01-Exceptions.md @@ -38,6 +38,10 @@ catch(Fuel\Email\SendingFailedException $e) { // The driver could not send the email } +finally +{ + // Use this to let user know email was sent +} {% endhighlight %} ### SPL Exceptions From 3fe10f963d16675e8d97303976e66ec96265cd19 Mon Sep 17 00:00:00 2001 From: Kevin Holler Date: Tue, 2 Jul 2013 12:54:45 +0100 Subject: [PATCH 131/843] Updated Engine Yard entry Engine Yard Orchestra has been replaced by our main Cloud platform, which now supports PHP and Composer <3 --- _posts/11-01-01-Resources.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/11-01-01-Resources.md b/_posts/11-01-01-Resources.md index 4b4fe0733..f4bbfa2c1 100644 --- a/_posts/11-01-01-Resources.md +++ b/_posts/11-01-01-Resources.md @@ -28,7 +28,7 @@ * [Heroku](https://heroku.com) (PHP support is undocumented but based on stable Facebook partnership [link](http://net.tutsplus.com/tutorials/php/quick-tip-deploy-php-to-heroku-in-seconds/)) * [fortrabbit](http://fortrabbit.com/) -* [Engine Yard Orchestra PHP Platform](http://www.engineyard.com/products/orchestra/) +* [Engine Yard Cloud](https://www.engineyard.com/products/cloud) * [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/) From 49215075a5b86d44db0bb7445f7dcf8357f37f9d Mon Sep 17 00:00:00 2001 From: = Date: Thu, 4 Jul 2013 14:32:05 -0400 Subject: [PATCH 132/843] Update translation links --- _includes/welcome.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/_includes/welcome.md b/_includes/welcome.md index ecf87a3ac..98dc576f7 100644 --- a/_includes/welcome.md +++ b/_includes/welcome.md @@ -9,15 +9,15 @@ standards, and links to authoritative tutorials around the Web. _PHP: The Right Way_ is (or soon will be) translated into many different languages: * [English](http://www.phptherightway.com) -* [Catalan](http://ca.phptherightway.com) +* Catalan (Needs translation) * [Chinese](http://wulijun.github.com/php-the-right-way) * [Japanese](http://ja.phptherightway.com) * [Korean](http://wafe.github.io/php-the-right-way/) -* [Italian](http://it.phptherightway.com) +* Italian (Needs translation) * [Polish](http://pl.phptherightway.com/) * [Portuguese](http://br.phptherightway.com/) * [Russian](http://getjump.github.io/ru-php-the-right-way) -* [Spanish](http://es.phptherightway.com) +* Spanish (Needs translation) * [Ukrainian](http://iflista.github.com/php-the-right-way/) * [Bulgarian](http://bg.phptherightway.com/) * [German](http://rwetzlmayr.github.io/php-the-right-way/) From c618db21e9ab111a4b5e64ecb547d1add871be90 Mon Sep 17 00:00:00 2001 From: Chris Christoff Date: Thu, 4 Jul 2013 14:35:50 -0400 Subject: [PATCH 133/843] Update 07-03-01-Password-Hashing.md --- _posts/07-03-01-Password-Hashing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/07-03-01-Password-Hashing.md b/_posts/07-03-01-Password-Hashing.md index 9ae41fc78..b44d2300e 100644 --- a/_posts/07-03-01-Password-Hashing.md +++ b/_posts/07-03-01-Password-Hashing.md @@ -10,7 +10,7 @@ It is important that you properly [_hash_][3] passwords before storing them. Pas **Hashing passwords with `password_hash`** -In PHP 5.5 `password_hash` was be introduced. At this time it is using BCrypt, the strongest algorithm currently supported by PHP. It will be updated in the future to support more algorithms as needed though. The `password_compat` library was created to provide forward compatibility for PHP >= 5.3.7. +In PHP 5.5 `password_hash` was introduced. At this time it is using BCrypt, the strongest algorithm currently supported by PHP. It will be updated in the future to support more algorithms as needed though. The `password_compat` library was created to provide forward compatibility for PHP >= 5.3.7. Below we hash a string, we then check the hash against a new string. Because our two source strings are different ('secret-password' vs. 'bad-password') this login will fail. From 7d31508cc78f9c2e18df6b3fde237712e3281bd9 Mon Sep 17 00:00:00 2001 From: = Date: Thu, 4 Jul 2013 14:53:39 -0400 Subject: [PATCH 134/843] Update message for broken translation links --- _includes/welcome.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/_includes/welcome.md b/_includes/welcome.md index 98dc576f7..f6f08520e 100644 --- a/_includes/welcome.md +++ b/_includes/welcome.md @@ -9,15 +9,15 @@ standards, and links to authoritative tutorials around the Web. _PHP: The Right Way_ is (or soon will be) translated into many different languages: * [English](http://www.phptherightway.com) -* Catalan (Needs translation) +* Catalan (Link broken... we're looking into it) * [Chinese](http://wulijun.github.com/php-the-right-way) * [Japanese](http://ja.phptherightway.com) * [Korean](http://wafe.github.io/php-the-right-way/) -* Italian (Needs translation) +* Italian (Link broken... we're looking into it) * [Polish](http://pl.phptherightway.com/) * [Portuguese](http://br.phptherightway.com/) * [Russian](http://getjump.github.io/ru-php-the-right-way) -* Spanish (Needs translation) +* Spanish (Link broken... we're looking into it) * [Ukrainian](http://iflista.github.com/php-the-right-way/) * [Bulgarian](http://bg.phptherightway.com/) * [German](http://rwetzlmayr.github.io/php-the-right-way/) From 10f26cdbe2d0b8067d750e0752145e73acdc29be Mon Sep 17 00:00:00 2001 From: Aran Wilkinson Date: Sun, 7 Jul 2013 17:27:57 +0100 Subject: [PATCH 135/843] Updated jekyll config and removed unneeded options Signed-off-by: Aran Wilkinson --- _config.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/_config.yml b/_config.yml index 6b9b0db79..e13f69ef3 100644 --- a/_config.yml +++ b/_config.yml @@ -1,7 +1,4 @@ -auto: true safe: true -server: true -server_port: 4000 baseurl: / url: http://localhost:4000 From 03dbf0b355da7e55795fbbfea191d919bc655ce9 Mon Sep 17 00:00:00 2001 From: Aran Wilkinson Date: Sun, 7 Jul 2013 17:33:00 +0100 Subject: [PATCH 136/843] Started work on errors and exceptions section Signed-off-by: Aran Wilkinson --- _posts/07-01-01-Errors-and-Exceptions.md | 6 ++++++ _posts/07-02-01-Errors.md | 11 +++++++++++ ...{05-05-01-Exceptions.md => 07-03-01-Exceptions.md} | 0 _posts/{07-01-01-Security.md => 08-01-01-Security.md} | 0 ...curity.md => 08-02-01-Web-Application-Security.md} | 0 ...ssword-Hashing.md => 08-03-01-Password-Hashing.md} | 0 ...1-Data-Filtering.md => 08-04-01-Data-Filtering.md} | 0 ...ation-Files.md => 08-05-01-Configuration-Files.md} | 0 ...gister-Globals.md => 08-06-01-Register-Globals.md} | 0 ...Error-Reporting.md => 08-07-01-Error-Reporting.md} | 0 _posts/{08-01-01-Testing.md => 09-01-01-Testing.md} | 0 ...lopment.md => 09-02-01-Test-Driven-Development.md} | 0 ...ent.md => 09-03-01-Behavior-Driven-Development.md} | 0 ...ols.md => 09-04-01-Complementary-Testing-Tools.md} | 0 ...ployment.md => 10-01-01-Servers-and-Deployment.md} | 0 ...a-Service.md => 10-02-01-Platform-as-a-Service.md} | 0 ...rs.md => 10-03-01-Virtual-or-Dedicated-Servers.md} | 0 ...1-Shared-Servers.md => 10-04-01-Shared-Servers.md} | 0 ...ation.md => 10-05-01-Building your Application.md} | 0 _posts/{10-01-01-Caching.md => 11-01-01-Caching.md} | 0 ...1-Bytecode-Cache.md => 11-02-01-Bytecode-Cache.md} | 0 ...1-Object-Caching.md => 11-03-01-Object-Caching.md} | 0 .../{11-01-01-Resources.md => 12-01-01-Resources.md} | 0 ...{11-02-01-Frameworks.md => 12-02-01-Frameworks.md} | 0 ...{11-03-01-Components.md => 12-03-01-Components.md} | 0 .../{12-01-01-Community.md => 13-01-01-Community.md} | 0 26 files changed, 17 insertions(+) create mode 100644 _posts/07-01-01-Errors-and-Exceptions.md create mode 100644 _posts/07-02-01-Errors.md rename _posts/{05-05-01-Exceptions.md => 07-03-01-Exceptions.md} (100%) rename _posts/{07-01-01-Security.md => 08-01-01-Security.md} (100%) rename _posts/{07-02-01-Web-Application-Security.md => 08-02-01-Web-Application-Security.md} (100%) rename _posts/{07-03-01-Password-Hashing.md => 08-03-01-Password-Hashing.md} (100%) rename _posts/{07-04-01-Data-Filtering.md => 08-04-01-Data-Filtering.md} (100%) rename _posts/{07-05-01-Configuration-Files.md => 08-05-01-Configuration-Files.md} (100%) rename _posts/{07-06-01-Register-Globals.md => 08-06-01-Register-Globals.md} (100%) rename _posts/{07-07-01-Error-Reporting.md => 08-07-01-Error-Reporting.md} (100%) rename _posts/{08-01-01-Testing.md => 09-01-01-Testing.md} (100%) rename _posts/{08-02-01-Test-Driven-Development.md => 09-02-01-Test-Driven-Development.md} (100%) rename _posts/{08-03-01-Behavior-Driven-Development.md => 09-03-01-Behavior-Driven-Development.md} (100%) rename _posts/{08-04-01-Complementary-Testing-Tools.md => 09-04-01-Complementary-Testing-Tools.md} (100%) rename _posts/{09-01-01-Servers-and-Deployment.md => 10-01-01-Servers-and-Deployment.md} (100%) rename _posts/{09-02-01-Platform-as-a-Service.md => 10-02-01-Platform-as-a-Service.md} (100%) rename _posts/{09-03-01-Virtual-or-Dedicated-Servers.md => 10-03-01-Virtual-or-Dedicated-Servers.md} (100%) rename _posts/{09-04-01-Shared-Servers.md => 10-04-01-Shared-Servers.md} (100%) rename _posts/{09-05-01-Building your Application.md => 10-05-01-Building your Application.md} (100%) rename _posts/{10-01-01-Caching.md => 11-01-01-Caching.md} (100%) rename _posts/{10-02-01-Bytecode-Cache.md => 11-02-01-Bytecode-Cache.md} (100%) rename _posts/{10-03-01-Object-Caching.md => 11-03-01-Object-Caching.md} (100%) rename _posts/{11-01-01-Resources.md => 12-01-01-Resources.md} (100%) rename _posts/{11-02-01-Frameworks.md => 12-02-01-Frameworks.md} (100%) rename _posts/{11-03-01-Components.md => 12-03-01-Components.md} (100%) rename _posts/{12-01-01-Community.md => 13-01-01-Community.md} (100%) diff --git a/_posts/07-01-01-Errors-and-Exceptions.md b/_posts/07-01-01-Errors-and-Exceptions.md new file mode 100644 index 000000000..f1b85667a --- /dev/null +++ b/_posts/07-01-01-Errors-and-Exceptions.md @@ -0,0 +1,6 @@ +--- +title: Errors and Exceptions +--- + +# Errors and Exceptions {#errors_and_exceptions_title} + diff --git a/_posts/07-02-01-Errors.md b/_posts/07-02-01-Errors.md new file mode 100644 index 000000000..dd4daeb20 --- /dev/null +++ b/_posts/07-02-01-Errors.md @@ -0,0 +1,11 @@ +--- +isChild: true +--- + +## Errors {#errors_title} + +PHP has several levels of error severity. The three most common types of messages are errors, notices and warnings. These have different levels of severity; `E_ERROR`, `E_NOTICE`, and `E_WARNING`. Errors are fatal run-time errors and are usually caused by faults in your code and need to be fixed as they'll cause PHP to stop executing. Warnings are non-fatal errors, execution of the script will not be halted. Notices are advisory messages caused by code that may or may not cause problems during the execution of the script, execution is not halted. + +Another type of error message reported at compile time is the `E_STRICT` message, these messages are used to suggest changes to your code to help ensure best interoperability and forward compatibility for your code. + +* [Predefined Constants for Error Handling](http://www.php.net/manual/en/errorfunc.constants.php) \ No newline at end of file diff --git a/_posts/05-05-01-Exceptions.md b/_posts/07-03-01-Exceptions.md similarity index 100% rename from _posts/05-05-01-Exceptions.md rename to _posts/07-03-01-Exceptions.md diff --git a/_posts/07-01-01-Security.md b/_posts/08-01-01-Security.md similarity index 100% rename from _posts/07-01-01-Security.md rename to _posts/08-01-01-Security.md diff --git a/_posts/07-02-01-Web-Application-Security.md b/_posts/08-02-01-Web-Application-Security.md similarity index 100% rename from _posts/07-02-01-Web-Application-Security.md rename to _posts/08-02-01-Web-Application-Security.md diff --git a/_posts/07-03-01-Password-Hashing.md b/_posts/08-03-01-Password-Hashing.md similarity index 100% rename from _posts/07-03-01-Password-Hashing.md rename to _posts/08-03-01-Password-Hashing.md diff --git a/_posts/07-04-01-Data-Filtering.md b/_posts/08-04-01-Data-Filtering.md similarity index 100% rename from _posts/07-04-01-Data-Filtering.md rename to _posts/08-04-01-Data-Filtering.md diff --git a/_posts/07-05-01-Configuration-Files.md b/_posts/08-05-01-Configuration-Files.md similarity index 100% rename from _posts/07-05-01-Configuration-Files.md rename to _posts/08-05-01-Configuration-Files.md diff --git a/_posts/07-06-01-Register-Globals.md b/_posts/08-06-01-Register-Globals.md similarity index 100% rename from _posts/07-06-01-Register-Globals.md rename to _posts/08-06-01-Register-Globals.md diff --git a/_posts/07-07-01-Error-Reporting.md b/_posts/08-07-01-Error-Reporting.md similarity index 100% rename from _posts/07-07-01-Error-Reporting.md rename to _posts/08-07-01-Error-Reporting.md diff --git a/_posts/08-01-01-Testing.md b/_posts/09-01-01-Testing.md similarity index 100% rename from _posts/08-01-01-Testing.md rename to _posts/09-01-01-Testing.md diff --git a/_posts/08-02-01-Test-Driven-Development.md b/_posts/09-02-01-Test-Driven-Development.md similarity index 100% rename from _posts/08-02-01-Test-Driven-Development.md rename to _posts/09-02-01-Test-Driven-Development.md diff --git a/_posts/08-03-01-Behavior-Driven-Development.md b/_posts/09-03-01-Behavior-Driven-Development.md similarity index 100% rename from _posts/08-03-01-Behavior-Driven-Development.md rename to _posts/09-03-01-Behavior-Driven-Development.md diff --git a/_posts/08-04-01-Complementary-Testing-Tools.md b/_posts/09-04-01-Complementary-Testing-Tools.md similarity index 100% rename from _posts/08-04-01-Complementary-Testing-Tools.md rename to _posts/09-04-01-Complementary-Testing-Tools.md diff --git a/_posts/09-01-01-Servers-and-Deployment.md b/_posts/10-01-01-Servers-and-Deployment.md similarity index 100% rename from _posts/09-01-01-Servers-and-Deployment.md rename to _posts/10-01-01-Servers-and-Deployment.md diff --git a/_posts/09-02-01-Platform-as-a-Service.md b/_posts/10-02-01-Platform-as-a-Service.md similarity index 100% rename from _posts/09-02-01-Platform-as-a-Service.md rename to _posts/10-02-01-Platform-as-a-Service.md diff --git a/_posts/09-03-01-Virtual-or-Dedicated-Servers.md b/_posts/10-03-01-Virtual-or-Dedicated-Servers.md similarity index 100% rename from _posts/09-03-01-Virtual-or-Dedicated-Servers.md rename to _posts/10-03-01-Virtual-or-Dedicated-Servers.md diff --git a/_posts/09-04-01-Shared-Servers.md b/_posts/10-04-01-Shared-Servers.md similarity index 100% rename from _posts/09-04-01-Shared-Servers.md rename to _posts/10-04-01-Shared-Servers.md diff --git a/_posts/09-05-01-Building your Application.md b/_posts/10-05-01-Building your Application.md similarity index 100% rename from _posts/09-05-01-Building your Application.md rename to _posts/10-05-01-Building your Application.md diff --git a/_posts/10-01-01-Caching.md b/_posts/11-01-01-Caching.md similarity index 100% rename from _posts/10-01-01-Caching.md rename to _posts/11-01-01-Caching.md diff --git a/_posts/10-02-01-Bytecode-Cache.md b/_posts/11-02-01-Bytecode-Cache.md similarity index 100% rename from _posts/10-02-01-Bytecode-Cache.md rename to _posts/11-02-01-Bytecode-Cache.md diff --git a/_posts/10-03-01-Object-Caching.md b/_posts/11-03-01-Object-Caching.md similarity index 100% rename from _posts/10-03-01-Object-Caching.md rename to _posts/11-03-01-Object-Caching.md diff --git a/_posts/11-01-01-Resources.md b/_posts/12-01-01-Resources.md similarity index 100% rename from _posts/11-01-01-Resources.md rename to _posts/12-01-01-Resources.md diff --git a/_posts/11-02-01-Frameworks.md b/_posts/12-02-01-Frameworks.md similarity index 100% rename from _posts/11-02-01-Frameworks.md rename to _posts/12-02-01-Frameworks.md diff --git a/_posts/11-03-01-Components.md b/_posts/12-03-01-Components.md similarity index 100% rename from _posts/11-03-01-Components.md rename to _posts/12-03-01-Components.md diff --git a/_posts/12-01-01-Community.md b/_posts/13-01-01-Community.md similarity index 100% rename from _posts/12-01-01-Community.md rename to _posts/13-01-01-Community.md From e741063667904b391a2a444f441224389ff798ee Mon Sep 17 00:00:00 2001 From: Aran Wilkinson Date: Thu, 11 Jul 2013 22:46:26 +0100 Subject: [PATCH 137/843] Expanded Errors section to cover more --- _posts/07-02-01-Errors.md | 35 ++++++++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/_posts/07-02-01-Errors.md b/_posts/07-02-01-Errors.md index dd4daeb20..9e8995216 100644 --- a/_posts/07-02-01-Errors.md +++ b/_posts/07-02-01-Errors.md @@ -1,11 +1,36 @@ ---- -isChild: true +--- +isChild: true --- ## Errors {#errors_title} -PHP has several levels of error severity. The three most common types of messages are errors, notices and warnings. These have different levels of severity; `E_ERROR`, `E_NOTICE`, and `E_WARNING`. Errors are fatal run-time errors and are usually caused by faults in your code and need to be fixed as they'll cause PHP to stop executing. Warnings are non-fatal errors, execution of the script will not be halted. Notices are advisory messages caused by code that may or may not cause problems during the execution of the script, execution is not halted. +PHP Errors differ to Exceptions in that they, Errors can halt the execution of your script depending on the level of severity. Exceptions on the other hand can be caught using `try catch` statements. + +### Error Severity + +PHP's built in error reporting and logging, allows for different levels of reporting via the use of Predefined Constants. The three main constants are `E_ERROR`, `E_NOTICE`, and `E_WARNING`. + +The different levels of error severity have different meanings. The three most common types of messages are Errors, Notices and Warnings. Errors are fatal run-time Errors and are usually caused by faults in your code and need to be fixed as they'll cause execution to be halted. Warnings are non-fatal errors, execution of the script will continue and dependant on settings the user may or not may see the Warning message. Notices are advisory messages caused by code that may or may not cause problems during script execution, execution is not halted and again depending on settings the user may or not see the Notice message. + +Another type of Error Message reported at compile time are `E_STRICT` messages, these messages are used to suggest +changes to your code to help ensure best interoperability and forward compatibility for your code. + +### Changing PHP's Error Reporting Behaviour + +Error Reporting can both be changed using PHP settings and PHP function calls. Using the built in PHP function `error_reporting()` you can set the level of errors for the duration of the script execution by passing one of the Predefined Constants. For more information on this relating to application environments check out the [Error Reporting][errorreport]. + +As well as setting the level of error reporting during script execution you can also suppress Errors using the Error Control Operator `@` by putting this operator at the beginning an expression. + +* [Error Control Operators](http://php.net/manual/en/language.operators.errorcontrol.php) + +### Error Exceptions + +Optionally you can throw your Errors as Exceptions using the `ErrorException` class, this extends the `Exception` class. More information on this and details on how to use `ErrorException` can be found at [ErrorException Class][errorexception]. This is a common practice but it is not an advised practice. Errors are used to faults and potential issues in your code that should be corrected. -Another type of error message reported at compile time is the `E_STRICT` message, these messages are used to suggest changes to your code to help ensure best interoperability and forward compatibility for your code. +* [Predefined Constants for Error Handling](http://www.php.net/manual/en/errorfunc.constants.php) +* [error_reporting](http://www.php.net/manual/en/function.error-reporting.php) +* [ErrorException Class][errorexception] +* [Reporting][errorreport] -* [Predefined Constants for Error Handling](http://www.php.net/manual/en/errorfunc.constants.php) \ No newline at end of file +[errorexception]: http://php.net/manual/en/class.errorexception.php +[errorreport]: /#error_reporting From 25d81eb23d7dc726df3e771baebbb179d95bd597 Mon Sep 17 00:00:00 2001 From: Aran Wilkinson Date: Fri, 12 Jul 2013 06:34:10 +0100 Subject: [PATCH 138/843] Forced Word Wrap Signed-off-by: Aran Wilkinson --- _posts/07-02-01-Errors.md | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/_posts/07-02-01-Errors.md b/_posts/07-02-01-Errors.md index 9e8995216..dcbca7406 100644 --- a/_posts/07-02-01-Errors.md +++ b/_posts/07-02-01-Errors.md @@ -4,28 +4,43 @@ isChild: true ## Errors {#errors_title} -PHP Errors differ to Exceptions in that they, Errors can halt the execution of your script depending on the level of severity. Exceptions on the other hand can be caught using `try catch` statements. +PHP Errors differ to Exceptions in that they, Errors can halt the execution of your script depending on the level of +severity. Exceptions on the other hand can be caught using `try catch` statements. ### Error Severity -PHP's built in error reporting and logging, allows for different levels of reporting via the use of Predefined Constants. The three main constants are `E_ERROR`, `E_NOTICE`, and `E_WARNING`. +PHP's built in error reporting and logging, allows for different levels of reporting via the use of Predefined +Constants. The three main constants are `E_ERROR`, `E_NOTICE`, and `E_WARNING`. -The different levels of error severity have different meanings. The three most common types of messages are Errors, Notices and Warnings. Errors are fatal run-time Errors and are usually caused by faults in your code and need to be fixed as they'll cause execution to be halted. Warnings are non-fatal errors, execution of the script will continue and dependant on settings the user may or not may see the Warning message. Notices are advisory messages caused by code that may or may not cause problems during script execution, execution is not halted and again depending on settings the user may or not see the Notice message. +The different levels of error severity have different meanings. The three most common types of messages are Errors, +Notices and Warnings. Errors are fatal run-time Errors and are usually caused by faults in your code and need to be +fixed as they'll cause execution to be halted. Warnings are non-fatal errors, execution of the script will continue +and dependant on settings the user may or not may see the Warning message. Notices are advisory messages caused by +code that may or may not cause problems during script execution, execution is not halted and again depending on +settings the user may or not see the Notice message. Another type of Error Message reported at compile time are `E_STRICT` messages, these messages are used to suggest changes to your code to help ensure best interoperability and forward compatibility for your code. ### Changing PHP's Error Reporting Behaviour -Error Reporting can both be changed using PHP settings and PHP function calls. Using the built in PHP function `error_reporting()` you can set the level of errors for the duration of the script execution by passing one of the Predefined Constants. For more information on this relating to application environments check out the [Error Reporting][errorreport]. +Error Reporting can both be changed using PHP settings and PHP function calls. Using the built in PHP function +`error_reporting()` you can set the level of errors for the duration of the script execution by passing one of the +Predefined Constants. For more information on this relating to application environments check +out the [Error Reporting][errorreport]. -As well as setting the level of error reporting during script execution you can also suppress Errors using the Error Control Operator `@` by putting this operator at the beginning an expression. +As well as setting the level of error reporting during script execution you can also suppress Errors using the +Error Control Operator `@` by putting this operator at the beginning an expression. The use of this operator +is not advised * [Error Control Operators](http://php.net/manual/en/language.operators.errorcontrol.php) ### Error Exceptions -Optionally you can throw your Errors as Exceptions using the `ErrorException` class, this extends the `Exception` class. More information on this and details on how to use `ErrorException` can be found at [ErrorException Class][errorexception]. This is a common practice but it is not an advised practice. Errors are used to faults and potential issues in your code that should be corrected. +Optionally you can throw your Errors as Exceptions using the `ErrorException` class, this extends the `Exception` +class. More information on this and details on how to use `ErrorException` can be found at +[ErrorException Class][errorexception]. This is a common practice but it is not an advised practice. +Errors are used to faults and potential issues in your code that should be corrected. * [Predefined Constants for Error Handling](http://www.php.net/manual/en/errorfunc.constants.php) * [error_reporting](http://www.php.net/manual/en/function.error-reporting.php) From 6fcb597b6e8b89ebb135e9b77a0310366d01e55f Mon Sep 17 00:00:00 2001 From: Aran Wilkinson Date: Fri, 12 Jul 2013 07:05:20 +0100 Subject: [PATCH 139/843] Reworded Error Control Operator and ErrorExceptions Signed-off-by: Aran Wilkinson --- _posts/07-02-01-Errors.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/_posts/07-02-01-Errors.md b/_posts/07-02-01-Errors.md index dcbca7406..bbfc67f72 100644 --- a/_posts/07-02-01-Errors.md +++ b/_posts/07-02-01-Errors.md @@ -31,17 +31,21 @@ out the [Error Reporting][errorreport]. As well as setting the level of error reporting during script execution you can also suppress Errors using the Error Control Operator `@` by putting this operator at the beginning an expression. The use of this operator -is not advised +is not advised and should never be used, using this operator is like admitting your code is bad and can fail over * [Error Control Operators](http://php.net/manual/en/language.operators.errorcontrol.php) ### Error Exceptions -Optionally you can throw your Errors as Exceptions using the `ErrorException` class, this extends the `Exception` -class. More information on this and details on how to use `ErrorException` can be found at -[ErrorException Class][errorexception]. This is a common practice but it is not an advised practice. -Errors are used to faults and potential issues in your code that should be corrected. +Optionally you can throw your Errors as Exceptions using the `ErrorException` class, this class extends the `Exception` +class. This is a common practice and by passing errors off as Exceptions in development you can handle them better than +the usual result. By passing these Errors as Exceptions and not trying to catch them in Development the hope is that +you'll catch the Error and hopefully this will allow you to deal with the issue before it becomes a problem in a +Production Environment. +More information on this and details on how to use `ErrorException` with Error Handling can be found at +[ErrorException Class][errorexception]. +* [Error Control Operators](http://php.net/manual/en/language.operators.errorcontrol.php) * [Predefined Constants for Error Handling](http://www.php.net/manual/en/errorfunc.constants.php) * [error_reporting](http://www.php.net/manual/en/function.error-reporting.php) * [ErrorException Class][errorexception] From ca1835615ae7926f449cc3432a79fff09725fdc5 Mon Sep 17 00:00:00 2001 From: dansmith Date: Mon, 15 Jul 2013 15:32:35 +0100 Subject: [PATCH 140/843] Minor (non-quote) grammar/spelling fixes --- _posts/01-02-01-Use-the-Current-Stable-Version.md | 2 +- _posts/02-01-01-Code-Style-Guide.md | 2 +- _posts/03-02-01-Programming-Paradigms.md | 4 ++-- _posts/03-05-01-Command-Line-Interface.md | 2 +- _posts/04-03-01-PEAR.md | 6 +++--- _posts/06-01-01-Databases.md | 2 +- _posts/07-03-01-Exceptions.md | 2 +- _posts/08-03-01-Password-Hashing.md | 4 ++-- _posts/08-05-01-Configuration-Files.md | 2 +- _posts/11-01-01-Caching.md | 2 +- 10 files changed, 14 insertions(+), 14 deletions(-) diff --git a/_posts/01-02-01-Use-the-Current-Stable-Version.md b/_posts/01-02-01-Use-the-Current-Stable-Version.md index d8d5881d5..1edc3ec82 100644 --- a/_posts/01-02-01-Use-the-Current-Stable-Version.md +++ b/_posts/01-02-01-Use-the-Current-Stable-Version.md @@ -5,7 +5,7 @@ isChild: true ## Use the Current Stable Version (5.5) {#use_the_current_stable_version_55_title} -If you are just getting started with PHP make sure to start with the current stable release of [PHP 5.5][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.5 fool you, it represents _major_ improvements. If you are looking for a function or it's usage, the documentation on the [php.net][php-docs] website will have the answer. +If you are just getting started with PHP make sure to start with the current stable release of [PHP 5.5][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.5 fool you, it represents _major_ improvements. If you are looking for a function or its usage, the documentation on the [php.net][php-docs] website will have the answer. [php-release]: http://www.php.net/downloads.php [php-docs]: http://www.php.net/manual/en/ diff --git a/_posts/02-01-01-Code-Style-Guide.md b/_posts/02-01-01-Code-Style-Guide.md index 1cd16f920..3cd3fbb3f 100644 --- a/_posts/02-01-01-Code-Style-Guide.md +++ b/_posts/02-01-01-Code-Style-Guide.md @@ -24,7 +24,7 @@ You can use [PHP_CodeSniffer][phpcs] to check code against any one of these reco like [Sublime Text 2][st-cs] to be given real time feedback. Use Fabien Potencier's [PHP Coding Standards Fixer][phpcsfixer] to automatically modify your code syntax so that it -conforms with these standards, saving you from fixing each problem by hand. +conforms to these standards, saving you from fixing each problem by hand. English is preferred for all symbol names and code infrastructure. Comments may be written in any language easily readable by all current and future parties who may be working on the codebase. diff --git a/_posts/03-02-01-Programming-Paradigms.md b/_posts/03-02-01-Programming-Paradigms.md index eb0d5676d..2da54d91b 100644 --- a/_posts/03-02-01-Programming-Paradigms.md +++ b/_posts/03-02-01-Programming-Paradigms.md @@ -18,7 +18,7 @@ interfaces, inheritance, constructors, cloning, exceptions, and more. ### Functional Programming -PHP supports first-class function, meaning that a function can be assigned to a variable. Both user defined and built-in +PHP supports first-class function, meaning that a function can be assigned to a variable. Both user-defined and built-in functions can be referenced by a variable and invoked dynamically. Functions can be passed as arguments to other functions (feature called Higher-order functions) and function can return other functions. @@ -39,7 +39,7 @@ can be used interchangeably with anonymous functions in almost all cases. ### Meta Programming -PHP supports various forms of meta programming through mechanisms like the Reflection API and Magic Methods. There are +PHP supports various forms of meta-programming through mechanisms like the Reflection API and Magic Methods. There are many Magic Methods available like `__get()`, `__set()`, `__clone()`, `__toString()`, `__invoke()`, etc. that allow developers to hook into class behavior. Ruby developers often say that PHP is lacking `method_missing`, but it is available as `__call()` and `__callStatic()`. diff --git a/_posts/03-05-01-Command-Line-Interface.md b/_posts/03-05-01-Command-Line-Interface.md index c323dc1aa..7b032f22d 100644 --- a/_posts/03-05-01-Command-Line-Interface.md +++ b/_posts/03-05-01-Command-Line-Interface.md @@ -32,7 +32,7 @@ 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`. -The `exit()` expression is used with a non zero number to let the shell know that the command failed. Commonly used exit codes can be found [here][exit-codes] +The `exit()` expression is used with a non-zero number to let the shell know that the command failed. Commonly used exit codes can be found [here][exit-codes] To run our script, above, from the command line: diff --git a/_posts/04-03-01-PEAR.md b/_posts/04-03-01-PEAR.md index b48fa44ac..f5315a8b0 100644 --- a/_posts/04-03-01-PEAR.md +++ b/_posts/04-03-01-PEAR.md @@ -5,7 +5,7 @@ isChild: true ## PEAR {#pear_title} Another veteran package manager that many PHP developers enjoy is [PEAR][1]. It behaves much the same way as Composer, -but has some noteable differences. +but has some notable differences. PEAR requires each package to have a specific structure, which means that the author of the package must prepare it for usage with PEAR. Using a project which was not prepared to work with PEAR is not possible. @@ -19,8 +19,8 @@ if version conflicts between two projects arise. You can install PEAR by downloading the phar installer and executing it. The PEAR documentation has detailed [install instructions][2] for every operating system. -If you are using Linux, you can also have a look at your distribution package manager. Debian and Ubuntu for example -have a apt ``php-pear`` package. +If you are using Linux, you can also have a look at your distribution package manager. Debian and Ubuntu, for example, +have an apt ``php-pear`` package. ### How to install a package diff --git a/_posts/06-01-01-Databases.md b/_posts/06-01-01-Databases.md index ce47ec4fa..5f024fa33 100644 --- a/_posts/06-01-01-Databases.md +++ b/_posts/06-01-01-Databases.md @@ -57,7 +57,7 @@ database preventing potential SQL injection attacks. You should also be aware that database connections use up resources and it was not unheard-of to have resources exhausted if connections were not implicitly closed, however this was more common in other languages. Using PDO you can implicitly close the connection by destroying the object by ensuring all remaining references to it are deleted, -ie. set to NULL. If you don't do this explicitly, PHP will automatically close the connection when your script ends +i.e. set to NULL. If you don't do this explicitly, PHP will automatically close the connection when your script ends - unless of course you are using persistent connections. * [Learn about PDO connections][5] diff --git a/_posts/07-03-01-Exceptions.md b/_posts/07-03-01-Exceptions.md index 56311b65f..f5d68c30f 100644 --- a/_posts/07-03-01-Exceptions.md +++ b/_posts/07-03-01-Exceptions.md @@ -17,7 +17,7 @@ obvious. Another problem is when classes automatically throw an error to the screen and exit the process. When you do this you stop another developer from being able to dynamically handle that error. Exceptions should be thrown to make a developer aware -of an error, then they can choose how to handle this. E.g: +of an error; they then can choose how to handle this. E.g.: {% highlight php %} = 5.3.7. -Below we hash a string, we then check the hash against a new string. Because our two source strings are different ('secret-password' vs. 'bad-password') this login will fail. +Below we hash a string, and then check the hash against a new string. Because our two source strings are different ('secret-password' vs. 'bad-password') this login will fail. {% highlight php %} Date: Thu, 25 Jul 2013 23:04:40 +0100 Subject: [PATCH 141/843] Added the strategy pattern to the Design Patterns page --- pages/Design-Patterns.md | 92 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/pages/Design-Patterns.md b/pages/Design-Patterns.md index e82a61d0a..f89234c9b 100644 --- a/pages/Design-Patterns.md +++ b/pages/Design-Patterns.md @@ -149,6 +149,98 @@ application, as the object using the shared or global resource requires no knowl * [Singleton pattern on Wikipedia](https://en.wikipedia.org/wiki/Singleton_pattern) +## Strategy + +With the strategy pattern you encapsulate specific families of algorithms allowing the client class responsible for +instantiating a particular algorithm to have no knowledge of the actual implementation. +There are several variations on the strategy pattern, the simplest of which is outlined below: + +This first code snippet outlines a family of algorithms; you may want a serialized array, some JSON or maybe +just an array of data: +{% highlight php %} +output = $output_type; + } + + public function loadOutput() + { + return $this->output->load(); + } +} +{% endhighlight %} + +The calling client class above has a private property which must be set at runtime and be of type 'OutputInterface' +once this property is set a call to loadOutput() will call the load() method in the concrete class of the output type +that has been set. +{% highlight php %} +setOutput(new OutputArray()); +$data = $client->loadOutput(); + +// Want some JSON? +$client->setOutput(new OutputJsonString()); +$data = $client->loadOutput(); + +{% endhighlight %} + +* [Strategy pattern on Wikipedia](http://en.wikipedia.org/wiki/Strategy_pattern) + ## Front Controller The front controller pattern is where you have a single entrance point for you web application (e.g. index.php) that From 8991c3f01369a4e1b32a72be9f5ee755c7c227e3 Mon Sep 17 00:00:00 2001 From: Matt Kirwan Date: Mon, 5 Aug 2013 16:23:28 +0100 Subject: [PATCH 142/843] Made the following changes: Removed class, standardised property names to camel case and switched method names. --- pages/Design-Patterns.md | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/pages/Design-Patterns.md b/pages/Design-Patterns.md index f89234c9b..4a3fe45ab 100644 --- a/pages/Design-Patterns.md +++ b/pages/Design-Patterns.md @@ -165,27 +165,27 @@ interface OutputInterface public function load(); } -class OutputSerializedArray implements OutputInterface +class SerializedArrayOutput implements OutputInterface { public function load() { - return serialize($array_of_data); + return serialize($arrayOfData); } } -class OutputJsonString implements OutputInterface +class JsonStringOutput implements OutputInterface { public function load() { - return json_encode($array_of_data); + return json_encode($arrayOfData); } } -class OutputArray implements OutputInterface +class ArrayOutput implements OutputInterface { public function load() { - return $array_of_data; + return $arrayOfData; } } {% endhighlight %} @@ -203,15 +203,13 @@ behaviour required at runtime: {% highlight php %} output = $output_type; + $this->output = $outputType; } public function loadOutput() @@ -227,14 +225,14 @@ that has been set. {% highlight php %} setOutput(new OutputArray()); +$client->setOutput(new ArrayOutput()); $data = $client->loadOutput(); // Want some JSON? -$client->setOutput(new OutputJsonString()); +$client->setOutput(new JsonStringOutput()); $data = $client->loadOutput(); {% endhighlight %} From 25c115c21420df6c0e4fce4a0ea3e6224732abf0 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Wed, 7 Aug 2013 17:57:39 -0400 Subject: [PATCH 143/843] misspelling/typo correction: administrativia -> administrivia --- _posts/03-05-01-Command-Line-Interface.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/03-05-01-Command-Line-Interface.md b/_posts/03-05-01-Command-Line-Interface.md index 7b032f22d..3cbaa16fb 100644 --- a/_posts/03-05-01-Command-Line-Interface.md +++ b/_posts/03-05-01-Command-Line-Interface.md @@ -4,7 +4,7 @@ isChild: true ## Command Line Interface {#command_line_interface_title} -PHP was created primarily to write web applications, but it's also useful for scripting command line interface (CLI) programs. Command line PHP programs can help you automate common tasks like testing, deployment, and application administrativia. +PHP was created primarily to write web applications, but it's also useful for scripting command line interface (CLI) programs. Command line PHP programs can help you automate common tasks like testing, deployment, and application administrivia. 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! From 1e9ba1c7b4b98283fbe86fa080915b08d0e5afbe Mon Sep 17 00:00:00 2001 From: = Date: Mon, 12 Aug 2013 22:00:46 -0400 Subject: [PATCH 144/843] Add Jelastic PaaS --- _posts/11-01-01-Resources.md | 1 + 1 file changed, 1 insertion(+) diff --git a/_posts/11-01-01-Resources.md b/_posts/11-01-01-Resources.md index f4bbfa2c1..3837fbcd0 100644 --- a/_posts/11-01-01-Resources.md +++ b/_posts/11-01-01-Resources.md @@ -36,3 +36,4 @@ * [Windows Azure](http://www.windowsazure.com/) * [Zend Developer Cloud](http://www.phpcloud.com/develop) * [Google App Engine](https://developers.google.com/appengine/docs/php/gettingstarted/) +* [Jelastic](http://jelastic.com/) From ccdaf659cd1cb4916d050a9ce795ec2918a75213 Mon Sep 17 00:00:00 2001 From: Phil Sturgeon Date: Thu, 15 Aug 2013 15:26:41 -0400 Subject: [PATCH 145/843] Updated welcome Some people apparently did not get that the title was jestful hyperbole. To make sure nobody is confused over intentions I've moved the disclaimer up and merged it with the Welcome section. This site is here to help people learn, nothing more. --- _includes/welcome.md | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/_includes/welcome.md b/_includes/welcome.md index f6f08520e..8e73e69b5 100644 --- a/_includes/welcome.md +++ b/_includes/welcome.md @@ -1,8 +1,20 @@ # Welcome -There's a lot of outdated information on the Web 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. +There's a lot of outdated information on the Web that leads new PHP users astray, +propagating bad practices and insecure code. _PHP: The Right Way_ is an easy-to-read, +quick reference for PHP popular coding standards, links to authoritative tutorials +around the Web and what the contributors consider to be best practices at the present +time. + +_There is no canonical way to use PHP_. This website aims to introduce new PHP +developers to some topics which they may not discover until it is too late, and aims +to give seasoned pros some fresh ideas on those topics they've been doing for years +without ever reconsidering. This website will also not tell you which tools to use, but +instead offer suggestions for multiple options, when possible explaining the differences +in approach and use-case. + +This is a living document and will continue to be updated with more helpful information +and examples as they become available. ## Translations @@ -23,15 +35,6 @@ _PHP: The Right Way_ is (or soon will be) translated into many different languag * [German](http://rwetzlmayr.github.io/php-the-right-way/) * [Turkish](http://hkulekci.github.io/php-the-right-way/) -## Disclaimer - -_There is no canonical way to use PHP_. However, this website is a humble display of best practices, -available options, and good information. It aims to introduce new PHP developers and to rethink seasoned pros with fresh -ideas. - -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][1] From 4ad0be78e383059108212f3ca3f1b50f85732745 Mon Sep 17 00:00:00 2001 From: Jaik Dean Date: Fri, 23 Aug 2013 11:05:16 +0100 Subject: [PATCH 146/843] Added notes about OPcache and APCu --- _posts/11-02-01-Bytecode-Cache.md | 7 +++++-- _posts/11-03-01-Object-Caching.md | 18 +++++++++++------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/_posts/11-02-01-Bytecode-Cache.md b/_posts/11-02-01-Bytecode-Cache.md index eaeaffcb8..73a583d11 100644 --- a/_posts/11-02-01-Bytecode-Cache.md +++ b/_posts/11-02-01-Bytecode-Cache.md @@ -10,9 +10,12 @@ If a PHP file is not modified, the bytecode will always be the same. This means This is where Bytecode cache comes in. It prevents redundant compilation by storing bytecode in memory and reusing it on successive calls. Setting up bytecode cache is a matter of minutes, and your application will speed up significantly. There's really no reason not to use it. -Popular bytecodes caches are: +As of PHP 5.5, there is a built-in bytecode cache called [OPcache](http://php.net/manual/en/book.opcache.php). This is +also available for earlier versions. -* [APC](http://php.net/manual/en/book.apc.php) +Other popular bytecodes caches are: + +* [APC](http://php.net/manual/en/book.apc.php) (PHP 5.4 and earlier) * [XCache](http://xcache.lighttpd.net/) * [Zend Optimizer+](http://www.zend.com/products/server/) (part of Zend Server package) * [WinCache](http://www.iis.net/download/wincacheforphp) (extension for MS Windows Server) diff --git a/_posts/11-03-01-Object-Caching.md b/_posts/11-03-01-Object-Caching.md index f6096251c..7a91115c4 100644 --- a/_posts/11-03-01-Object-Caching.md +++ b/_posts/11-03-01-Object-Caching.md @@ -11,23 +11,23 @@ them, then pull them directly from the cache for following requests, you can gai performance as well as reduce the load on your database servers. Many of the popular bytecode caching solutions let you cache custom data as well, so there's even more reason to take -advantage of them. APC, XCache, and WinCache all provide APIs to save data from your PHP code to their memory cache. +advantage of them. APCu, XCache, and WinCache all provide APIs to save data from your PHP code to their memory cache. -The most commonly used memory object caching systems are APC and memcached. APC is an excellent choice for object +The most commonly used memory object caching systems are APCu and memcached. APCu is an excellent choice for object caching, it includes a simple API for adding your own data to its memory cache and is very easy to setup and use. The -one real limitation of APC is that it is tied to the server it's installed on. Memcached on the other hand is installed +one real limitation of APCu is that it is tied to the server it's installed on. Memcached on the other hand is installed as a separate service and can be accessed across the network, meaning that you can store objects in a hyper-fast data store in a central location and many different systems can pull from it. Note that when running PHP as a (Fast-)CGI application inside your webserver, every PHP process will have its own -cache, i.e. APC data is not shared between your worker processes. In these cases, you might want to consider using +cache, i.e. APCu data is not shared between your worker processes. In these cases, you might want to consider using memcached instead, as it's not tied to the PHP processes. -In a networked configuration APC will usually outperform memcached in terms of access speed, but memcached will be able +In a networked configuration APCu will usually outperform memcached in terms of access speed, but memcached will be able to scale up faster and further. If you do not expect to have multiple servers running your application, or do not need -the extra features that memcached offers then APC is probably your best choice for object caching. +the extra features that memcached offers then APCu is probably your best choice for object caching. -Example logic using APC: +Example logic using APCu: {% highlight php %} Date: Sat, 24 Aug 2013 03:56:41 +0200 Subject: [PATCH 147/843] PHP.ug added to PHP User Groups information --- _posts/13-01-01-Community.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/_posts/13-01-01-Community.md b/_posts/13-01-01-Community.md index 4af118509..709d1a8dc 100644 --- a/_posts/13-01-01-Community.md +++ b/_posts/13-01-01-Community.md @@ -6,7 +6,7 @@ The PHP community is as diverse as it is large, and its members are ready and wi ## PHP User Groups -If you live in a larger city, odds are there's a PHP user group nearby. Although there's not yet an official list of PUGs, you can easily find your local PUG by searching on [Google][google] or [Meetup.com][meetup]. If you live in a smaller town, there may not be a local PUG; if that's the case, start one! +If you live in a larger city, odds are there's a PHP user group nearby. Although there's not yet an official list of PUGs, you can easily find your local PUG by searching on [Google][google], [Meetup.com][meetup] or [PHP.ug][php-ug]. If you live in a smaller town, there may not be a local PUG; if that's the case, start one! [Read about User Groups on the PHP Wiki][php-wiki] @@ -19,6 +19,7 @@ The PHP community also hosts larger regional and national conferences in many co [php-calendar]: http://www.php.net/cal.php [google]: https://www.google.com/search?q=php+user+group+near+me [meetup]: http://www.meetup.com/find/ +[php-ug]: http://php.ug [php-wiki]: https://wiki.php.net/usergroups [php-conf]: http://php.net/conferences/index.php [phpc-twitter]: https://twitter.com/phpc From 6556f426a7abd8689ffd24219ce78ca1c4be5633 Mon Sep 17 00:00:00 2001 From: Alan Pinstein Date: Sun, 25 Aug 2013 11:43:15 -0400 Subject: [PATCH 148/843] Add note about MacGDBp stand-alone graphical debugger. --- _posts/03-06-01-XDebug.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/_posts/03-06-01-XDebug.md b/_posts/03-06-01-XDebug.md index ce7852010..be511f309 100644 --- a/_posts/03-06-01-XDebug.md +++ b/_posts/03-06-01-XDebug.md @@ -29,7 +29,13 @@ listen on. Then it's just a matter of putting your IDE into "listen for connecti Your IDE will now intercept the current state as the script executes, allowing you to set breakpoints and probe the values in memory. +Graphical debuggers make it very easy to step through code, inspect variables, and eval code against the live runtime. +Many IDE's have built-in or plugin-based support for graphical debugging with xdebug. MacGBDp is a free, open-source, +stand-alone xdebug GUI for Mac. + * [Learn more about XDebug][xdebug-docs] + * [Learn more about MacGDBp][macgdbp-install] [xdebug-docs]: http://xdebug.org/docs/ -[xdebug-install]: http://xdebug.org/docs/install \ No newline at end of file +[xdebug-install]: http://xdebug.org/docs/install +[macgdbp-install]: http://www.bluestatic.org/software/macgdbp/ From 670d1b903a951511cf462ede5a80f1ab21b0c1d1 Mon Sep 17 00:00:00 2001 From: Stuart Herbert Date: Wed, 28 Aug 2013 09:49:53 +0100 Subject: [PATCH 149/843] Update 09-02-01-Test-Driven-Development.md Added link to Storyplayer, one of the functional test tools available to the community. --- _posts/09-02-01-Test-Driven-Development.md | 1 + 1 file changed, 1 insertion(+) diff --git a/_posts/09-02-01-Test-Driven-Development.md b/_posts/09-02-01-Test-Driven-Development.md index 91a7e59e9..f6571d4cb 100644 --- a/_posts/09-02-01-Test-Driven-Development.md +++ b/_posts/09-02-01-Test-Driven-Development.md @@ -56,3 +56,4 @@ data and simulating actual users of the application. * [Selenium](http://seleniumhq.com) * [Mink](http://mink.behat.org) * [Codeception](http://codeception.com) is a full-stack testing framework that includes acceptance testing tools +* [Storyplayer](http://datasift.github.io/storyplayer) is a full-stack testing framework that includes support for creating and destroying test environments on demand From 5112db612ccbace5b53217a5a7ae56ce9357d4c1 Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Sun, 8 Sep 2013 21:09:25 +0200 Subject: [PATCH 150/843] license year updated --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index e03e9bcef..8e9a4f2b7 100644 --- a/LICENSE +++ b/LICENSE @@ -1,3 +1,3 @@ -Copyright (c) 2012 Josh Lockhart +Copyright (c) 2013 Josh Lockhart http://creativecommons.org/licenses/by-nc-sa/3.0/ From c7a05212751fc03eff17ab2a8c750f5ab2a62f41 Mon Sep 17 00:00:00 2001 From: Ilyes Date: Tue, 10 Sep 2013 19:03:28 +0200 Subject: [PATCH 151/843] Added XAMPP as a option for Mac user's as well. --- _posts/01-04-01-Mac-Setup.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/_posts/01-04-01-Mac-Setup.md b/_posts/01-04-01-Mac-Setup.md index ae9157d55..c394dea76 100644 --- a/_posts/01-04-01-Mac-Setup.md +++ b/_posts/01-04-01-Mac-Setup.md @@ -14,7 +14,7 @@ The other option is to [compile it yourself][mac-compile], in that case be sure Apple's substitute ["Command Line Tools for Xcode"][apple-developer] downloadable from Apple's Mac Developer Center. For a complete "all-in-one" package including PHP, Apache web server and MySQL database, all this with a nice control -GUI, try [MAMP][mamp-downloads]. +GUI, try [MAMP][mamp-downloads] or [XAMPP][xampp]. [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 @@ -22,3 +22,4 @@ GUI, try [MAMP][mamp-downloads]. [apple-developer]: https://developer.apple.com/downloads [mamp-downloads]: http://www.mamp.info/en/downloads/index.html [php-osx-downloads]: http://php-osx.liip.ch/ +[xampp]: http://www.apachefriends.org/en/xampp.html From 1c70bed87000d2876f25a276205243ad36536ab0 Mon Sep 17 00:00:00 2001 From: Rogerio Prado de Jesus Date: Tue, 10 Sep 2013 17:35:05 -0300 Subject: [PATCH 152/843] Include Rove.io and Puphpet in Vagrant section --- _posts/01-06-01-Vagrant.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/_posts/01-06-01-Vagrant.md b/_posts/01-06-01-Vagrant.md index 9503f95fe..c3768a548 100644 --- a/_posts/01-06-01-Vagrant.md +++ b/_posts/01-06-01-Vagrant.md @@ -19,6 +19,17 @@ easy to create a "fresh" installation. Vagrant creates shared folders used to share your code between your host and your virtual machine, meaning you can create and edit your files on your host machine and then run the code inside your virtual machine. +### A little help + +If you need a little help to start using Vagrant there are two services that might be useful: + +- [Rove][rove]: service that allows you to pregenerate typical Vagrant builds, PHP among the options. The + provisioning is made with Chef. +- [Puphpet][puphpet]: simple GUI to set up virtual machines for PHP development. **Heavily focused in PHP**. Besides + local VMs, can be used to deploy to cloud services as well. The provisioning is made with Puppet. + [vagrant]: http://vagrantup.com/ [puppet]: http://www.puppetlabs.com/ [chef]: http://www.opscode.com/ +[rove]: http://rove.io/ +[puphpet]: https://puphpet.com/ From 64b123587ffed47e9bfea995bf6974d1af4a1528 Mon Sep 17 00:00:00 2001 From: Phil Sturgeon Date: Tue, 10 Sep 2013 18:51:49 -0400 Subject: [PATCH 153/843] epub script grumbles about spaces --- ... your Application.md => 10-05-01-Building-your-Application.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename _posts/{10-05-01-Building your Application.md => 10-05-01-Building-your-Application.md} (100%) diff --git a/_posts/10-05-01-Building your Application.md b/_posts/10-05-01-Building-your-Application.md similarity index 100% rename from _posts/10-05-01-Building your Application.md rename to _posts/10-05-01-Building-your-Application.md From e050ed5353987df0f892ed05b8aabd988616a679 Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Thu, 12 Sep 2013 06:44:17 +0200 Subject: [PATCH 154/843] typos in behavior driven development --- _posts/09-03-01-Behavior-Driven-Development.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/_posts/09-03-01-Behavior-Driven-Development.md b/_posts/09-03-01-Behavior-Driven-Development.md index 9fa148c9d..d0cde20b0 100644 --- a/_posts/09-03-01-Behavior-Driven-Development.md +++ b/_posts/09-03-01-Behavior-Driven-Development.md @@ -4,9 +4,9 @@ isChild: true ## Behavior Driven Development {#behavior_driven_development_title} -There are two different types of Behavior-Driven Development (BDD): SpecBDD and StoryBDD. SpecBDD focuses on technical behavior or code, while StoryBDD focuses on business or feature behaviors or interactions. PHP has frameworks for both types of BDD. +There are two different types of Behavior-Driven Development (BDD): SpecBDD and StoryBDD. SpecBDD focuses on technical behavior of code, while StoryBDD focuses on business or feature behaviors or interactions. PHP has frameworks for both types of BDD. -With StoryBDD, you write human-readable stories that describe the behavior of your application. These stories +With StoryBDD, you write human-readable stories that describe the behavior of your application. These stories can then be run as actual tests against your application. The framework used in PHP applications for StoryBDD is Behat, which is inspired by Ruby's [Cucumber](http://cukes.info/) project and implements the Gherkin DSL for describing feature behavior. @@ -15,7 +15,7 @@ With SpecBDD, you write specifications that describe how your actual code should a function or method, you are describing how that function or method should behave. PHP offers the PHPSpec framework for this purpose. This framework is inspired by the [RSpec project](http://rspec.info/) for Ruby. -### BDD Links +### BDD Links * [Behat](http://behat.org/), the StoryBDD framework for PHP, inspired by Ruby's [Cucumber](http://cukes.info/) project; * [PHPSpec](http://www.phpspec.net/), the SpecBDD framework for PHP, inspired by Ruby's [RSpec](http://rspec.info/) project; From 94701e6ddb9a667200d194b28744d72e7ee59d0c Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Thu, 12 Sep 2013 11:15:12 +0200 Subject: [PATCH 155/843] irc channel added to url of webchat.freenode.net --- _posts/13-01-01-Community.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/13-01-01-Community.md b/_posts/13-01-01-Community.md index 4af118509..c0f985e49 100644 --- a/_posts/13-01-01-Community.md +++ b/_posts/13-01-01-Community.md @@ -23,5 +23,5 @@ The PHP community also hosts larger regional and national conferences in many co [php-conf]: http://php.net/conferences/index.php [phpc-twitter]: https://twitter.com/phpc [php-programmers-gplus]: https://plus.google.com/u/0/communities/104245651975268426012 -[php-irc]: http://webchat.freenode.net/ +[php-irc]: http://webchat.freenode.net/?channels=phpc [php-so]: http://stackoverflow.com/questions/tagged/php From 1a935e0872d8ff1fc9b419f2a87aca5eaab21a35 Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Thu, 12 Sep 2013 11:16:51 +0200 Subject: [PATCH 156/843] psr-3 link mark removed from coding style post since it is not used --- _posts/02-01-01-Code-Style-Guide.md | 1 - 1 file changed, 1 deletion(-) diff --git a/_posts/02-01-01-Code-Style-Guide.md b/_posts/02-01-01-Code-Style-Guide.md index 3cd3fbb3f..e9d4657a6 100644 --- a/_posts/02-01-01-Code-Style-Guide.md +++ b/_posts/02-01-01-Code-Style-Guide.md @@ -33,7 +33,6 @@ by all current and future parties who may be working on the codebase. [psr0]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md [psr1]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-1-basic-coding-standard.md [psr2]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md -[psr3]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md [pear-cs]: http://pear.php.net/manual/en/standards.php [zend-cs]: http://framework.zend.com/wiki/display/ZFDEV2/Coding+Standards [phpcs]: http://pear.php.net/package/PHP_CodeSniffer/ From cf4f77ecaeb5b530c6c4a7e7d8f0878046e91312 Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Thu, 12 Sep 2013 11:34:28 +0200 Subject: [PATCH 157/843] XDebug title added --- _posts/03-06-01-XDebug.md | 1 + 1 file changed, 1 insertion(+) diff --git a/_posts/03-06-01-XDebug.md b/_posts/03-06-01-XDebug.md index be511f309..402eb1ec6 100644 --- a/_posts/03-06-01-XDebug.md +++ b/_posts/03-06-01-XDebug.md @@ -1,4 +1,5 @@ --- +title: XDebug isChild: true --- From 1216c2e7daa3136529c8e5c97a0141bb87657c8f Mon Sep 17 00:00:00 2001 From: Mathieu Rochette Date: Fri, 13 Sep 2013 19:45:23 +0200 Subject: [PATCH 158/843] Hightlight web banners exemple code as HTML --- banners.md | 64 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 40 insertions(+), 24 deletions(-) diff --git a/banners.md b/banners.md index 20ead1937..b4a06bb97 100644 --- a/banners.md +++ b/banners.md @@ -12,62 +12,78 @@ Spread the word with _PHP: The Right Way_ banner images! Show new PHP developers

PHP: The Right Way

- - PHP: The Right Way - +{% highlight html %} + + PHP: The Right Way + +{% endhighlight %} ## Button 2 (120x60)

PHP: The Right Way

- - PHP: The Right Way - +{% highlight html %} + + PHP: The Right Way + +{% endhighlight %} ## Leaderboard (728x90)

PHP: The Right Way

- - PHP: The Right Way - +{% highlight html %} + + PHP: The Right Way + +{% endhighlight %} ## Large Rectangle (386x280)

PHP: The Right Way

- - PHP: The Right Way - +{% highlight html %} + + PHP: The Right Way + +{% endhighlight %} ## Medium Rectangle (300x250)

PHP: The Right Way

- - PHP: The Right Way - +{% highlight html %} + + PHP: The Right Way + +{% endhighlight %} ## Rectangle (180x150)

PHP: The Right Way

- - PHP: The Right Way - +{% highlight html %} + + PHP: The Right Way + +{% endhighlight %} ## Square Button (125x125)

PHP: The Right Way

- - PHP: The Right Way - +{% highlight html %} + + PHP: The Right Way + +{% endhighlight %} ## Vertical Rectangle (240x400)

PHP: The Right Way

- - PHP: The Right Way - +{% highlight html %} + + PHP: The Right Way + +{% endhighlight %} From 59d2ab2ce7ffc5fdad3164ff46cc209fde0026f4 Mon Sep 17 00:00:00 2001 From: Mathieu Rochette Date: Sat, 21 Sep 2013 19:53:41 +0200 Subject: [PATCH 159/843] fix vertical scrollbar --- _posts/08-03-01-Password-Hashing.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/_posts/08-03-01-Password-Hashing.md b/_posts/08-03-01-Password-Hashing.md index 0bc6bc582..cf9f544be 100644 --- a/_posts/08-03-01-Password-Hashing.md +++ b/_posts/08-03-01-Password-Hashing.md @@ -14,8 +14,9 @@ In PHP 5.5 `password_hash` was introduced. At this time it is using BCrypt, the Below we hash a string, and then check the hash against a new string. Because our two source strings are different ('secret-password' vs. 'bad-password') this login will fail. -{% highlight php %} - Date: Wed, 2 Oct 2013 15:39:27 +0100 Subject: [PATCH 160/843] Update 07-03-01-Exceptions.md Change misleading comment. --- _posts/07-03-01-Exceptions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/07-03-01-Exceptions.md b/_posts/07-03-01-Exceptions.md index f5d68c30f..13b3a8dd2 100644 --- a/_posts/07-03-01-Exceptions.md +++ b/_posts/07-03-01-Exceptions.md @@ -40,7 +40,7 @@ catch(Fuel\Email\SendingFailedException $e) } finally { - // Use this to let user know email was sent + // Executed regardless of whether an exception has been thrown, and before normal execution resumes } {% endhighlight %} From 44ed5460dcefe5f1f7dd69dbd14ba2efcd555131 Mon Sep 17 00:00:00 2001 From: kenden Date: Tue, 8 Oct 2013 13:47:59 +0200 Subject: [PATCH 161/843] Update 09-04-01-Complementary-Testing-Tools.md Updating link to the PHPUnit-Selenium integration page to the current version of PHPUnit --- _posts/09-04-01-Complementary-Testing-Tools.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/09-04-01-Complementary-Testing-Tools.md b/_posts/09-04-01-Complementary-Testing-Tools.md index 034937ad3..1cbc3043f 100644 --- a/_posts/09-04-01-Complementary-Testing-Tools.md +++ b/_posts/09-04-01-Complementary-Testing-Tools.md @@ -8,6 +8,6 @@ Besides individual testing and behavior driven frameworks, there are also a numb ### Tool Links -* [Selenium](http://seleniumhq.org/) is a browser automation tool which can be [integrated with PHPUnit](http://www.phpunit.de/manual/3.1/en/selenium.html) +* [Selenium](http://seleniumhq.org/) is a browser automation tool which can be [integrated with PHPUnit](http://phpunit.de/manual/current/en/selenium.html) * [Mockery](https://github.com/padraic/mockery) is a Mock Object Framework which can be integrated with [PHPUnit](http://phpunit.de/) or [PHPSpec](http://www.phpspec.net/) * [Prophecy](https://github.com/phpspec/prophecy) is a highly opinionated yet very powerful and flexible PHP object mocking framework. It's integrated with [PHPSpec](http://www.phpspec.net/) and can be used with [PHPUnit](http://phpunit.de/). From 737c15f18e628c816fe12a6e9588dab306cddf9f Mon Sep 17 00:00:00 2001 From: Jacek Kobus Date: Tue, 8 Oct 2013 22:27:05 +0200 Subject: [PATCH 162/843] added link to symfony coding standards --- _posts/02-01-01-Code-Style-Guide.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/_posts/02-01-01-Code-Style-Guide.md b/_posts/02-01-01-Code-Style-Guide.md index e9d4657a6..f7a6d0c12 100644 --- a/_posts/02-01-01-Code-Style-Guide.md +++ b/_posts/02-01-01-Code-Style-Guide.md @@ -19,6 +19,7 @@ and applications that implement the components can have consistency even when wo * [Read about PSR-2][psr2] * [Read about PEAR Coding Standards][pear-cs] * [Read about Zend Coding Standards][zend-cs] +* [Read about Symfony Coding Standards][symfony-cs] You can use [PHP_CodeSniffer][phpcs] to check code against any one of these recommendations, and plugins for text editors like [Sublime Text 2][st-cs] to be given real time feedback. @@ -35,6 +36,7 @@ by all current and future parties who may be working on the codebase. [psr2]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md [pear-cs]: http://pear.php.net/manual/en/standards.php [zend-cs]: http://framework.zend.com/wiki/display/ZFDEV2/Coding+Standards +[symfony-cs]: http://symfony.com/doc/current/contributing/code/standards.html [phpcs]: http://pear.php.net/package/PHP_CodeSniffer/ [st-cs]: https://github.com/benmatselby/sublime-phpcs [phpcsfixer]: http://cs.sensiolabs.org/ From d02c7d66e827e9fdaa98be0a0d6d6648733d40e3 Mon Sep 17 00:00:00 2001 From: Matthew Malinowski Date: Wed, 6 Nov 2013 10:03:23 -0500 Subject: [PATCH 163/843] Add Mavericks PHP version to Mac Setup. --- _posts/01-04-01-Mac-Setup.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_posts/01-04-01-Mac-Setup.md b/_posts/01-04-01-Mac-Setup.md index c394dea76..aa2fa2930 100644 --- a/_posts/01-04-01-Mac-Setup.md +++ b/_posts/01-04-01-Mac-Setup.md @@ -4,8 +4,8 @@ isChild: true ## Mac Setup {#mac_setup_title} -OSX comes prepackaged with PHP but it is normally a little behind the latest stable. Lion comes with PHP 5.3.6 and -Mountain Lion has 5.3.10. +OSX comes prepackaged with PHP but it is normally a little behind the latest stable. Lion comes with PHP 5.3.6, +Mountain Lion has 5.3.10, and Mavericks has 5.4.17. To update PHP on OSX you can get it installed through a number of Mac [package managers][mac-package-managers], with [php-osx by Liip][php-osx-downloads] being recommended. From 7136211fd0ad2d224192b17343cd26a55997cc36 Mon Sep 17 00:00:00 2001 From: Alastair Hole Date: Wed, 20 Nov 2013 16:29:44 +0000 Subject: [PATCH 164/843] Update 03-06-01-XDebug.md Corrected MacGBDp to MacGDBp --- _posts/03-06-01-XDebug.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/03-06-01-XDebug.md b/_posts/03-06-01-XDebug.md index 402eb1ec6..8334b5c4e 100644 --- a/_posts/03-06-01-XDebug.md +++ b/_posts/03-06-01-XDebug.md @@ -31,7 +31,7 @@ Your IDE will now intercept the current state as the script executes, allowing y values in memory. Graphical debuggers make it very easy to step through code, inspect variables, and eval code against the live runtime. -Many IDE's have built-in or plugin-based support for graphical debugging with xdebug. MacGBDp is a free, open-source, +Many IDE's have built-in or plugin-based support for graphical debugging with xdebug. MacGDBp is a free, open-source, stand-alone xdebug GUI for Mac. * [Learn more about XDebug][xdebug-docs] From c5ebc871dc801f4acb171a2f677e86d470d5f551 Mon Sep 17 00:00:00 2001 From: happyaccidents Date: Tue, 26 Nov 2013 14:35:06 +0000 Subject: [PATCH 165/843] Renamed posts to allow Dependency Injection to be added --- _posts/{06-01-01-Databases.md => 08-01-01-Databases.md} | 0 _posts/{07-02-01-Errors.md => 08-02-01-Errors.md} | 0 _posts/{07-03-01-Exceptions.md => 08-03-01-Exceptions.md} | 0 _posts/{08-01-01-Security.md => 09-01-01-Security.md} | 0 ...plication-Security.md => 09-02-01-Web-Application-Security.md} | 0 ...{08-03-01-Password-Hashing.md => 09-03-01-Password-Hashing.md} | 0 _posts/{08-04-01-Data-Filtering.md => 09-04-01-Data-Filtering.md} | 0 ...-01-Configuration-Files.md => 09-05-01-Configuration-Files.md} | 0 ...{08-06-01-Register-Globals.md => 09-06-01-Register-Globals.md} | 0 .../{08-07-01-Error-Reporting.md => 09-07-01-Error-Reporting.md} | 0 _posts/{09-01-01-Testing.md => 10-01-01-Testing.md} | 0 ...-Driven-Development.md => 10-02-01-Test-Driven-Development.md} | 0 ...ven-Development.md => 10-03-01-Behavior-Driven-Development.md} | 0 ...y-Testing-Tools.md => 10-04-01-Complementary-Testing-Tools.md} | 0 ...rvers-and-Deployment.md => 11-01-01-Servers-and-Deployment.md} | 0 ...Platform-as-a-Service.md => 11-02-01-Platform-as-a-Service.md} | 0 ...icated-Servers.md => 11-03-01-Virtual-or-Dedicated-Servers.md} | 0 _posts/{10-04-01-Shared-Servers.md => 11-04-01-Shared-Servers.md} | 0 ...-your-Application.md => 11-05-01-Building-your-Application.md} | 0 _posts/{11-01-01-Caching.md => 12-01-01-Caching.md} | 0 _posts/{11-02-01-Bytecode-Cache.md => 12-02-01-Bytecode-Cache.md} | 0 _posts/{11-03-01-Object-Caching.md => 12-03-01-Object-Caching.md} | 0 _posts/{12-01-01-Resources.md => 13-01-01-Resources.md} | 0 _posts/{12-02-01-Frameworks.md => 13-02-01-Frameworks.md} | 0 _posts/{12-03-01-Components.md => 13-03-01-Components.md} | 0 _posts/{13-01-01-Community.md => 14-01-01-Community.md} | 0 26 files changed, 0 insertions(+), 0 deletions(-) rename _posts/{06-01-01-Databases.md => 08-01-01-Databases.md} (100%) rename _posts/{07-02-01-Errors.md => 08-02-01-Errors.md} (100%) rename _posts/{07-03-01-Exceptions.md => 08-03-01-Exceptions.md} (100%) rename _posts/{08-01-01-Security.md => 09-01-01-Security.md} (100%) rename _posts/{08-02-01-Web-Application-Security.md => 09-02-01-Web-Application-Security.md} (100%) rename _posts/{08-03-01-Password-Hashing.md => 09-03-01-Password-Hashing.md} (100%) rename _posts/{08-04-01-Data-Filtering.md => 09-04-01-Data-Filtering.md} (100%) rename _posts/{08-05-01-Configuration-Files.md => 09-05-01-Configuration-Files.md} (100%) rename _posts/{08-06-01-Register-Globals.md => 09-06-01-Register-Globals.md} (100%) rename _posts/{08-07-01-Error-Reporting.md => 09-07-01-Error-Reporting.md} (100%) rename _posts/{09-01-01-Testing.md => 10-01-01-Testing.md} (100%) rename _posts/{09-02-01-Test-Driven-Development.md => 10-02-01-Test-Driven-Development.md} (100%) rename _posts/{09-03-01-Behavior-Driven-Development.md => 10-03-01-Behavior-Driven-Development.md} (100%) rename _posts/{09-04-01-Complementary-Testing-Tools.md => 10-04-01-Complementary-Testing-Tools.md} (100%) rename _posts/{10-01-01-Servers-and-Deployment.md => 11-01-01-Servers-and-Deployment.md} (100%) rename _posts/{10-02-01-Platform-as-a-Service.md => 11-02-01-Platform-as-a-Service.md} (100%) rename _posts/{10-03-01-Virtual-or-Dedicated-Servers.md => 11-03-01-Virtual-or-Dedicated-Servers.md} (100%) rename _posts/{10-04-01-Shared-Servers.md => 11-04-01-Shared-Servers.md} (100%) rename _posts/{10-05-01-Building-your-Application.md => 11-05-01-Building-your-Application.md} (100%) rename _posts/{11-01-01-Caching.md => 12-01-01-Caching.md} (100%) rename _posts/{11-02-01-Bytecode-Cache.md => 12-02-01-Bytecode-Cache.md} (100%) rename _posts/{11-03-01-Object-Caching.md => 12-03-01-Object-Caching.md} (100%) rename _posts/{12-01-01-Resources.md => 13-01-01-Resources.md} (100%) rename _posts/{12-02-01-Frameworks.md => 13-02-01-Frameworks.md} (100%) rename _posts/{12-03-01-Components.md => 13-03-01-Components.md} (100%) rename _posts/{13-01-01-Community.md => 14-01-01-Community.md} (100%) diff --git a/_posts/06-01-01-Databases.md b/_posts/08-01-01-Databases.md similarity index 100% rename from _posts/06-01-01-Databases.md rename to _posts/08-01-01-Databases.md diff --git a/_posts/07-02-01-Errors.md b/_posts/08-02-01-Errors.md similarity index 100% rename from _posts/07-02-01-Errors.md rename to _posts/08-02-01-Errors.md diff --git a/_posts/07-03-01-Exceptions.md b/_posts/08-03-01-Exceptions.md similarity index 100% rename from _posts/07-03-01-Exceptions.md rename to _posts/08-03-01-Exceptions.md diff --git a/_posts/08-01-01-Security.md b/_posts/09-01-01-Security.md similarity index 100% rename from _posts/08-01-01-Security.md rename to _posts/09-01-01-Security.md diff --git a/_posts/08-02-01-Web-Application-Security.md b/_posts/09-02-01-Web-Application-Security.md similarity index 100% rename from _posts/08-02-01-Web-Application-Security.md rename to _posts/09-02-01-Web-Application-Security.md diff --git a/_posts/08-03-01-Password-Hashing.md b/_posts/09-03-01-Password-Hashing.md similarity index 100% rename from _posts/08-03-01-Password-Hashing.md rename to _posts/09-03-01-Password-Hashing.md diff --git a/_posts/08-04-01-Data-Filtering.md b/_posts/09-04-01-Data-Filtering.md similarity index 100% rename from _posts/08-04-01-Data-Filtering.md rename to _posts/09-04-01-Data-Filtering.md diff --git a/_posts/08-05-01-Configuration-Files.md b/_posts/09-05-01-Configuration-Files.md similarity index 100% rename from _posts/08-05-01-Configuration-Files.md rename to _posts/09-05-01-Configuration-Files.md diff --git a/_posts/08-06-01-Register-Globals.md b/_posts/09-06-01-Register-Globals.md similarity index 100% rename from _posts/08-06-01-Register-Globals.md rename to _posts/09-06-01-Register-Globals.md diff --git a/_posts/08-07-01-Error-Reporting.md b/_posts/09-07-01-Error-Reporting.md similarity index 100% rename from _posts/08-07-01-Error-Reporting.md rename to _posts/09-07-01-Error-Reporting.md diff --git a/_posts/09-01-01-Testing.md b/_posts/10-01-01-Testing.md similarity index 100% rename from _posts/09-01-01-Testing.md rename to _posts/10-01-01-Testing.md diff --git a/_posts/09-02-01-Test-Driven-Development.md b/_posts/10-02-01-Test-Driven-Development.md similarity index 100% rename from _posts/09-02-01-Test-Driven-Development.md rename to _posts/10-02-01-Test-Driven-Development.md diff --git a/_posts/09-03-01-Behavior-Driven-Development.md b/_posts/10-03-01-Behavior-Driven-Development.md similarity index 100% rename from _posts/09-03-01-Behavior-Driven-Development.md rename to _posts/10-03-01-Behavior-Driven-Development.md diff --git a/_posts/09-04-01-Complementary-Testing-Tools.md b/_posts/10-04-01-Complementary-Testing-Tools.md similarity index 100% rename from _posts/09-04-01-Complementary-Testing-Tools.md rename to _posts/10-04-01-Complementary-Testing-Tools.md diff --git a/_posts/10-01-01-Servers-and-Deployment.md b/_posts/11-01-01-Servers-and-Deployment.md similarity index 100% rename from _posts/10-01-01-Servers-and-Deployment.md rename to _posts/11-01-01-Servers-and-Deployment.md diff --git a/_posts/10-02-01-Platform-as-a-Service.md b/_posts/11-02-01-Platform-as-a-Service.md similarity index 100% rename from _posts/10-02-01-Platform-as-a-Service.md rename to _posts/11-02-01-Platform-as-a-Service.md diff --git a/_posts/10-03-01-Virtual-or-Dedicated-Servers.md b/_posts/11-03-01-Virtual-or-Dedicated-Servers.md similarity index 100% rename from _posts/10-03-01-Virtual-or-Dedicated-Servers.md rename to _posts/11-03-01-Virtual-or-Dedicated-Servers.md diff --git a/_posts/10-04-01-Shared-Servers.md b/_posts/11-04-01-Shared-Servers.md similarity index 100% rename from _posts/10-04-01-Shared-Servers.md rename to _posts/11-04-01-Shared-Servers.md diff --git a/_posts/10-05-01-Building-your-Application.md b/_posts/11-05-01-Building-your-Application.md similarity index 100% rename from _posts/10-05-01-Building-your-Application.md rename to _posts/11-05-01-Building-your-Application.md diff --git a/_posts/11-01-01-Caching.md b/_posts/12-01-01-Caching.md similarity index 100% rename from _posts/11-01-01-Caching.md rename to _posts/12-01-01-Caching.md diff --git a/_posts/11-02-01-Bytecode-Cache.md b/_posts/12-02-01-Bytecode-Cache.md similarity index 100% rename from _posts/11-02-01-Bytecode-Cache.md rename to _posts/12-02-01-Bytecode-Cache.md diff --git a/_posts/11-03-01-Object-Caching.md b/_posts/12-03-01-Object-Caching.md similarity index 100% rename from _posts/11-03-01-Object-Caching.md rename to _posts/12-03-01-Object-Caching.md diff --git a/_posts/12-01-01-Resources.md b/_posts/13-01-01-Resources.md similarity index 100% rename from _posts/12-01-01-Resources.md rename to _posts/13-01-01-Resources.md diff --git a/_posts/12-02-01-Frameworks.md b/_posts/13-02-01-Frameworks.md similarity index 100% rename from _posts/12-02-01-Frameworks.md rename to _posts/13-02-01-Frameworks.md diff --git a/_posts/12-03-01-Components.md b/_posts/13-03-01-Components.md similarity index 100% rename from _posts/12-03-01-Components.md rename to _posts/13-03-01-Components.md diff --git a/_posts/13-01-01-Community.md b/_posts/14-01-01-Community.md similarity index 100% rename from _posts/13-01-01-Community.md rename to _posts/14-01-01-Community.md From 79334026462b892c8a984708ddb4bc9e36d471c2 Mon Sep 17 00:00:00 2001 From: happyaccidents Date: Tue, 26 Nov 2013 14:37:09 +0000 Subject: [PATCH 166/843] Missed a rename --- _posts/{08-01-01-Databases.md => 07-01-01-Databases.md} | 0 ...Errors-and-Exceptions.md => 08-01-01-Errors-and-Exceptions.md} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename _posts/{08-01-01-Databases.md => 07-01-01-Databases.md} (100%) rename _posts/{07-01-01-Errors-and-Exceptions.md => 08-01-01-Errors-and-Exceptions.md} (100%) diff --git a/_posts/08-01-01-Databases.md b/_posts/07-01-01-Databases.md similarity index 100% rename from _posts/08-01-01-Databases.md rename to _posts/07-01-01-Databases.md diff --git a/_posts/07-01-01-Errors-and-Exceptions.md b/_posts/08-01-01-Errors-and-Exceptions.md similarity index 100% rename from _posts/07-01-01-Errors-and-Exceptions.md rename to _posts/08-01-01-Errors-and-Exceptions.md From 192a207e2db94a2050b025e168b4a729fef4a517 Mon Sep 17 00:00:00 2001 From: happyaccidents Date: Thu, 28 Nov 2013 12:17:44 +0000 Subject: [PATCH 167/843] First draft - Resolves #280 --- _posts/06-01-01-Dependency-Injection.md | 8 ++++ _posts/06-02-01-Basic-Concept.md | 57 +++++++++++++++++++++++++ _posts/06-03-01-Complex-Problem.md | 49 +++++++++++++++++++++ _posts/06-04-01-Containers.md | 14 ++++++ _posts/06-05-01-Further-Reading.md | 11 +++++ 5 files changed, 139 insertions(+) create mode 100644 _posts/06-01-01-Dependency-Injection.md create mode 100644 _posts/06-02-01-Basic-Concept.md create mode 100644 _posts/06-03-01-Complex-Problem.md create mode 100644 _posts/06-04-01-Containers.md create mode 100644 _posts/06-05-01-Further-Reading.md diff --git a/_posts/06-01-01-Dependency-Injection.md b/_posts/06-01-01-Dependency-Injection.md new file mode 100644 index 000000000..3bac06ed7 --- /dev/null +++ b/_posts/06-01-01-Dependency-Injection.md @@ -0,0 +1,8 @@ +--- +title: Dependency Injection +--- + +# Dependency Injection {#dependency_injection_title} + +Dependency Injection is a basic concept that solves a complex problem. As a software design pattern it is being adopted in +some way or another by all major PHP projects. diff --git a/_posts/06-02-01-Basic-Concept.md b/_posts/06-02-01-Basic-Concept.md new file mode 100644 index 000000000..1748afea0 --- /dev/null +++ b/_posts/06-02-01-Basic-Concept.md @@ -0,0 +1,57 @@ +--- +isChild: true +--- + +## Basic Concept {#basic_concept_title} + +From [Wikipedia](http://en.wikipedia.org/wiki/Dependency_injection): + +> Dependency injection is a software design pattern that allows the removal of hard-coded dependencies and makes it +> possible to change them, whether at run-time or compile-time. + +This quote makes the concept sound much more complicated than it actually is. Dependency Injection is providing a component +with it's dependencies either through constructor injection, method calls or the setting of properties. It is that simple. + +We can demonstrate the concept with a simple, yet naive, example. + +{% highlight php %} +adapter = new MySqlAdapter; + } +} + +class MysqlAdapter {} +{% endhighlight %} + +Here we have a `Database` class that requires an adapter to speak to the database. We instantiate the +adapter in the constructor and create a hard dependency. This code can be refactored to use Dependency Injection +and therefore loosen the dependency. + +{% highlight php %} +adapter = $adapter; + } +} + +class MysqlAdapter {} +{% endhighlight %} + +Now we are giving the `Database` class it's dependency rather than it creating it itself. We could even create a method +that would accept an argument of the dependency and set it that way, or if the `$adapter` property was `public` we could +set it directly. diff --git a/_posts/06-03-01-Complex-Problem.md b/_posts/06-03-01-Complex-Problem.md new file mode 100644 index 000000000..07050d2f7 --- /dev/null +++ b/_posts/06-03-01-Complex-Problem.md @@ -0,0 +1,49 @@ +--- +isChild: true +--- + +## Complex Problem {#complex_problem_title} + +If you have ever read about Dependency Injection then you have probably seen the terms *"Inversion of Control"* or *"Dependency Inversion Principle"*. +These are the complex problems that Dependency Injection solves, or to be more precise, elegantly solves. + +For years, PHP frameworks have been achieving Inversion of Control, however, the question became, which part of control +are you inverting, and where to? For example, MVC frameworks would generally provide a super object or base controller that other +controllers must extend to gain access to it's dependencies. This **is** Inversion of Control, however, instead of loosening +dependencies, this method simply moved them. + +Dependency Injection allows us to more elegantly solve this problem by only injecting the dependencies we need, when we need them, +without the need for any hard coded dependencies at all. + +Dependency Inversion Principle is the "D" in the S.O.L.I.D set of object oriented design principles that states one should +*"Depend on Abstractions. Do not depend on concretions."*. Put simply, this means our dependencies should be interfaces/contracts or abstract +classes rather than concrete implementations. We can easily refactor the above example to follow this principle. + +{% highlight php %} +adapter = $adapter; + } +} + +interface AdapterInterface {} + +class MysqlAdapter implements AdapterInterface {} +{% endhighlight %} + +There are several benefits to the Database class now depending on an interface rather than a concretion. + +Consider that you are working in a team and the adapter is being worked on by a colleague. In our first example, we would have +to wait for said colleague to finish the adapter before we could properly mock it for our unit tests. Now that the dependency +is an interface/contract we can happily mock that interface knowing that our colleague will build the adapter based on that contract. + +An even bigger benefit to this method is that our code is now much more scalable. If a year down the line we decide that we +want to migrate to a different type of database, we can write an adapter that implements the original interface and inject that instead, +no more refactoring would be required as we can ensure that the adapter follows the contract set by the interface. diff --git a/_posts/06-04-01-Containers.md b/_posts/06-04-01-Containers.md new file mode 100644 index 000000000..b3eca748b --- /dev/null +++ b/_posts/06-04-01-Containers.md @@ -0,0 +1,14 @@ +--- +isChild: true +--- + +## Containers {#containers_title} + +The first thing you should understand about Dependency Injection Containers is that they are not the same thing as Dependency +Injection. A container is a convenience utility that helps us implement Dependency Injection, however, they can be and often +are misused to implement an anti pattern, Service Location. Using a container as a Service Locator within your classes arguably +creates a harder dependency on the container than the dependency you are replacing. It also makes your code much less transparent +and ultimately harder to test. + +Most modern frameworks have their own Dependency Injection Container that allows you to wire your dependencies together through configuration. +What this means in practice is that you can write application code that is as clean and de-coupled as the framework it is built on. diff --git a/_posts/06-05-01-Further-Reading.md b/_posts/06-05-01-Further-Reading.md new file mode 100644 index 000000000..e1d3645ba --- /dev/null +++ b/_posts/06-05-01-Further-Reading.md @@ -0,0 +1,11 @@ +--- +isChild: true +--- + +## Further Reading {#further_reading_title} + +- [Learning about Dependency Injection and PHP](http://ralphschindler.com/2011/05/18/learning-about-dependency-injection-and-php) +- [What is Dependency Injection?](http://fabien.potencier.org/article/11/what-is-dependency-injection) +- [Dependency Injection: An analogy](http://mwop.net/blog/260-Dependency-Injection-An-analogy.html) +- [Dependency Injection: Huh?](http://net.tutsplus.com/tutorials/php/dependency-injection-huh/) +- [Dependency Injection as a tool for testing](http://www.happyaccidents.me/dependency-injection-as-a-tool-for-testing/) From ea4a6bebe236b7437cd0afba54233204cb3ef83e Mon Sep 17 00:00:00 2001 From: happyaccidents Date: Thu, 28 Nov 2013 14:00:56 +0000 Subject: [PATCH 168/843] Revisions --- _posts/06-01-01-Dependency-Injection.md | 9 +++++++-- _posts/06-02-01-Basic-Concept.md | 16 +++++----------- _posts/06-03-01-Complex-Problem.md | 9 ++++++++- 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/_posts/06-01-01-Dependency-Injection.md b/_posts/06-01-01-Dependency-Injection.md index 3bac06ed7..e69c4a254 100644 --- a/_posts/06-01-01-Dependency-Injection.md +++ b/_posts/06-01-01-Dependency-Injection.md @@ -4,5 +4,10 @@ title: Dependency Injection # Dependency Injection {#dependency_injection_title} -Dependency Injection is a basic concept that solves a complex problem. As a software design pattern it is being adopted in -some way or another by all major PHP projects. +From [Wikipedia](http://en.wikipedia.org/wiki/Dependency_injection): + +> Dependency injection is a software design pattern that allows the removal of hard-coded dependencies and makes it +> possible to change them, whether at run-time or compile-time. + +This quote makes the concept sound much more complicated than it actually is. Dependency Injection is providing a component +with it's dependencies either through constructor injection, method calls or the setting of properties. It is that simple. diff --git a/_posts/06-02-01-Basic-Concept.md b/_posts/06-02-01-Basic-Concept.md index 1748afea0..520415bac 100644 --- a/_posts/06-02-01-Basic-Concept.md +++ b/_posts/06-02-01-Basic-Concept.md @@ -4,15 +4,11 @@ isChild: true ## Basic Concept {#basic_concept_title} -From [Wikipedia](http://en.wikipedia.org/wiki/Dependency_injection): +We can demonstrate the concept with a simple, yet naive. -> Dependency injection is a software design pattern that allows the removal of hard-coded dependencies and makes it -> possible to change them, whether at run-time or compile-time. - -This quote makes the concept sound much more complicated than it actually is. Dependency Injection is providing a component -with it's dependencies either through constructor injection, method calls or the setting of properties. It is that simple. - -We can demonstrate the concept with a simple, yet naive, example. +Here we have a `Database` class that requires an adapter to speak to the database. We instantiate the +adapter in the constructor and create a hard dependency. This makes testing difficult and means the `Database` class is +very tightly coupled to the adapter. {% highlight php %} Date: Fri, 29 Nov 2013 09:46:15 +0000 Subject: [PATCH 169/843] Typos and further change re comments --- _posts/06-03-01-Complex-Problem.md | 26 +++++++++++++------------- _posts/06-04-01-Containers.md | 10 +++++----- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/_posts/06-03-01-Complex-Problem.md b/_posts/06-03-01-Complex-Problem.md index 69e69fb0c..9fd0f21c1 100644 --- a/_posts/06-03-01-Complex-Problem.md +++ b/_posts/06-03-01-Complex-Problem.md @@ -4,26 +4,26 @@ isChild: true ## Complex Problem {#complex_problem_title} -If you have ever read about Dependency Injection then you have probably seen the terms *"Inversion of Control"* or *"Dependency Inversion Principle"*. +If you have ever read about Dependency Injection then you have probably seen the terms *"Inversion of Control"* or *"Dependency Inversion Principle"*. These are the complex problems that Dependency Injection solves. ### Inversion of Control -Inversion of Control is as it says, "inverting the control" of a system by keeping organisational control entirely separate from our objects. +Inversion of Control is as it says, "inverting the control" of a system by keeping organisational control entirely separate from our objects. In terms of Dependency Injection, this means loosening our dependencies by controlling and instantiating them elsewhere in the system. -For years, PHP frameworks have been achieving Inversion of Control, however, the question became, which part of control -are you inverting, and where to? For example, MVC frameworks would generally provide a super object or base controller that other -controllers must extend to gain access to it's dependencies. This **is** Inversion of Control, however, instead of loosening +For years, PHP frameworks have been achieving Inversion of Control, however, the question became, which part of control +are you inverting, and where to? For example, MVC frameworks would generally provide a super object or base controller that other +controllers must extend to gain access to its dependencies. This **is** Inversion of Control, however, instead of loosening dependencies, this method simply moved them. -Dependency Injection allows us to more elegantly solve this problem by only injecting the dependencies we need, when we need them, +Dependency Injection allows us to more elegantly solve this problem by only injecting the dependencies we need, when we need them, without the need for any hard coded dependencies at all. ### Dependency Inversion Principle -Dependency Inversion Principle is the "D" in the S.O.L.I.D set of object oriented design principles that states one should -*"Depend on Abstractions. Do not depend on concretions."*. Put simply, this means our dependencies should be interfaces/contracts or abstract +Dependency Inversion Principle is the "D" in the S.O.L.I.D set of object oriented design principles that states one should +*"Depend on Abstractions. Do not depend on concretions."*. Put simply, this means our dependencies should be interfaces/contracts or abstract classes rather than concrete implementations. We can easily refactor the above example to follow this principle. {% highlight php %} @@ -45,12 +45,12 @@ interface AdapterInterface {} class MysqlAdapter implements AdapterInterface {} {% endhighlight %} -There are several benefits to the Database class now depending on an interface rather than a concretion. +There are several benefits to the `Database` class now depending on an interface rather than a concretion. -Consider that you are working in a team and the adapter is being worked on by a colleague. In our first example, we would have -to wait for said colleague to finish the adapter before we could properly mock it for our unit tests. Now that the dependency +Consider that you are working in a team and the adapter is being worked on by a colleague. In our first example, we would have +to wait for said colleague to finish the adapter before we could properly mock it for our unit tests. Now that the dependency is an interface/contract we can happily mock that interface knowing that our colleague will build the adapter based on that contract. -An even bigger benefit to this method is that our code is now much more scalable. If a year down the line we decide that we -want to migrate to a different type of database, we can write an adapter that implements the original interface and inject that instead, +An even bigger benefit to this method is that our code is now much more scalable. If a year down the line we decide that we +want to migrate to a different type of database, we can write an adapter that implements the original interface and inject that instead, no more refactoring would be required as we can ensure that the adapter follows the contract set by the interface. diff --git a/_posts/06-04-01-Containers.md b/_posts/06-04-01-Containers.md index b3eca748b..f0e5466f8 100644 --- a/_posts/06-04-01-Containers.md +++ b/_posts/06-04-01-Containers.md @@ -4,11 +4,11 @@ isChild: true ## Containers {#containers_title} -The first thing you should understand about Dependency Injection Containers is that they are not the same thing as Dependency -Injection. A container is a convenience utility that helps us implement Dependency Injection, however, they can be and often -are misused to implement an anti pattern, Service Location. Using a container as a Service Locator within your classes arguably -creates a harder dependency on the container than the dependency you are replacing. It also makes your code much less transparent +The first thing you should understand about Dependency Injection Containers is that they are not the same thing as Dependency +Injection. A container is a convenience utility that helps us implement Dependency Injection, however, they can be and often +are misused to implement an anti-pattern, Service Location. Injecting a DI container as a Service Locator in to your classes arguably +creates a harder dependency on the container than the dependency you are replacing. It also makes your code much less transparent and ultimately harder to test. -Most modern frameworks have their own Dependency Injection Container that allows you to wire your dependencies together through configuration. +Most modern frameworks have their own Dependency Injection Container that allows you to wire your dependencies together through configuration. What this means in practice is that you can write application code that is as clean and de-coupled as the framework it is built on. From fd21b24e3f48a2f9e9880eb22b1a9ed222e0b210 Mon Sep 17 00:00:00 2001 From: Josh Lockhart Date: Fri, 29 Nov 2013 11:56:00 -0500 Subject: [PATCH 170/843] Fix DI typo --- _posts/06-02-01-Basic-Concept.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/_posts/06-02-01-Basic-Concept.md b/_posts/06-02-01-Basic-Concept.md index 520415bac..727ba7a2e 100644 --- a/_posts/06-02-01-Basic-Concept.md +++ b/_posts/06-02-01-Basic-Concept.md @@ -4,10 +4,10 @@ isChild: true ## Basic Concept {#basic_concept_title} -We can demonstrate the concept with a simple, yet naive. +We can demonstrate the concept with a simple, yet naive example. -Here we have a `Database` class that requires an adapter to speak to the database. We instantiate the -adapter in the constructor and create a hard dependency. This makes testing difficult and means the `Database` class is +Here we have a `Database` class that requires an adapter to speak to the database. We instantiate the +adapter in the constructor and create a hard dependency. This makes testing difficult and means the `Database` class is very tightly coupled to the adapter. {% highlight php %} @@ -46,6 +46,6 @@ class Database class MysqlAdapter {} {% endhighlight %} -Now we are giving the `Database` class it's dependency rather than it creating it itself. We could even create a method -that would accept an argument of the dependency and set it that way, or if the `$adapter` property was `public` we could +Now we are giving the `Database` class it's dependency rather than it creating it itself. We could even create a method +that would accept an argument of the dependency and set it that way, or if the `$adapter` property was `public` we could set it directly. From 81ae63d5da54184d0dc85c2c90b4dae2c0ac039f Mon Sep 17 00:00:00 2001 From: Josh Lockhart Date: Fri, 29 Nov 2013 11:57:23 -0500 Subject: [PATCH 171/843] Fix DI typo --- _posts/06-02-01-Basic-Concept.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/06-02-01-Basic-Concept.md b/_posts/06-02-01-Basic-Concept.md index 727ba7a2e..fb9954be3 100644 --- a/_posts/06-02-01-Basic-Concept.md +++ b/_posts/06-02-01-Basic-Concept.md @@ -46,6 +46,6 @@ class Database class MysqlAdapter {} {% endhighlight %} -Now we are giving the `Database` class it's dependency rather than it creating it itself. We could even create a method +Now we are giving the `Database` class its dependency rather than it creating it itself. We could even create a method that would accept an argument of the dependency and set it that way, or if the `$adapter` property was `public` we could set it directly. From 3bd78009eb2b1e16f64cf00f3158f789d9c5f1fc Mon Sep 17 00:00:00 2001 From: Phil Sturgeon Date: Mon, 2 Dec 2013 10:23:11 -0500 Subject: [PATCH 172/843] Fixed link for Enhance PHP Thanks to @w00 for pointing this one out in #332. --- _posts/10-02-01-Test-Driven-Development.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/_posts/10-02-01-Test-Driven-Development.md b/_posts/10-02-01-Test-Driven-Development.md index f6571d4cb..71528d6c9 100644 --- a/_posts/10-02-01-Test-Driven-Development.md +++ b/_posts/10-02-01-Test-Driven-Development.md @@ -30,10 +30,11 @@ you run a project which accepts pull requests then you should suggest this as a [PHPUnit](http://phpunit.de) is the de-facto testing framework for writing unit tests for PHP applications, but there are several alternatives -* [SimpleTest](http://simpletest.org) -* [Enhance PHP](http://www.enhance-php.com/) -* [PUnit](http://punit.smf.me.uk/) * [atoum](https://github.com/atoum/atoum) +* [Enhance PHP](https://github.com/Enhance-PHP/Enhance-PHP) +* [PUnit](http://punit.smf.me.uk/) +* [SimpleTest](http://simpletest.org) + ### Integration Testing From 67df3eb54e7e20e9310ca05657f12f8e2bff4d47 Mon Sep 17 00:00:00 2001 From: Ryan Koven Date: Tue, 3 Dec 2013 13:45:16 -0800 Subject: [PATCH 173/843] Remove an extraneous 'to'; rectify an instance of an incorrect verb tense; small adjust to punctuation. Original text noted that it's "usually a good idea to follow to common patterns". Removed extra 'to'. In MVC section the sentence "The model-view-controller (MVC) pattern... let..." should be changed to "The model-view-controller (MVC) pattern...lets..." Also added a semicolon to a sentence in the Factory section that Strunk and White would agree enhances the clarity of the sentence. --- pages/Design-Patterns.md | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/pages/Design-Patterns.md b/pages/Design-Patterns.md index 4a3fe45ab..64618c2bc 100644 --- a/pages/Design-Patterns.md +++ b/pages/Design-Patterns.md @@ -6,7 +6,7 @@ title: Design Patterns # Design Patterns There are numerous ways to structure the code and project for you web application, and you can put as much or as little -thought as you like into architecting. But it is usually a good idea to follow to common patterns because it will make +thought as you like into architecting. But it is usually a good idea to follow common patterns because it will make your code easier to manage and easier for others to understand. * [Architectural pattern on Wikipedia](https://en.wikipedia.org/wiki/Architectural_pattern) @@ -51,7 +51,7 @@ print_r($veyron->get_make_and_model()); // outputs "Bugatti Veyron" {% endhighlight %} This code uses a factory to create the Automobile object. There are two possible benefits to building your code this -way, the first is that if you need to change, rename, or replace the Automobile class later on you can do so and you +way; the first is that if you need to change, rename, or replace the Automobile class later on you can do so and you will only have to modify the code in the factory, instead of every place in your project that uses the Automobile class. The second possible benefit is that if creating the object is a complicated job you can do all of the work in the factory, instead of repeating it every time you want to create a new instance. @@ -250,11 +250,7 @@ and gives you a central place to hook in code that should be run for every reque ## Model-View-Controller -The model-view-controller (MVC) pattern and its relatives HMVC and MVVM let you break up code into logical objects that -serve very specific purposes. Models serve as a data access layer where data is fetched and returned in formats usable -throughout your application. Controllers handle the request, process the data returned from models and load views to -send in the response. And views are display templates (markup, xml, etc) that are sent in the response to the web -browser. +The model-view-controller (MVC) pattern and its relatives HMVC and MVVM lets you break up code into logical objects that serve very specific purposes. Models serve as a data access layer where data is fetched and returned in formats usable throughout your application. Controllers handle the request, process the data returned from models and load views to send in the response. And views are display templates (markup, xml, etc) that are sent in the response to the web browser. MVC is the most common architectural pattern used in the popular [PHP frameworks](https://github.com/codeguy/php-the-right-way/wiki/Frameworks). From 9bca711909bfcb893e7f949d46474c98aa43befb Mon Sep 17 00:00:00 2001 From: Jakukyo Friel Date: Sat, 7 Dec 2013 20:12:02 +0800 Subject: [PATCH 174/843] higher order functions Functions using functions as input and/or output are higher order functions. --- pages/Functional-Programming.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pages/Functional-Programming.md b/pages/Functional-Programming.md index f9dc9a006..f5eb792e1 100644 --- a/pages/Functional-Programming.md +++ b/pages/Functional-Programming.md @@ -7,14 +7,14 @@ title: Functional Programming in PHP PHP supports first-class functions, meaning that a function can be assigned to a variable. Both user-defined and built-in functions can be referenced by a variable and invoked dynamically. Functions can be passed as arguments to other -functions (a feature called higher-order functions) and a function can return other functions. +functions and a function can return other functions (a feature called higher-order functions). Recursion, a feature that allows a function to call itself, is supported by the language, but most of the PHP code focus is on iteration. Anonymous functions (with support for closures) have been present since PHP 5.3 (2009). -PHP 5.4 added the ability to bind closures to an object's scope and also improved support for callables such that they +PHP 5.4 added the ability to bind closures to an object's scope and also improved support for callables such that they can be used interchangeably with anonymous functions in almost all cases. The most common usage of higher-order functions is when implementing a strategy pattern. The built-in `array_filter` From c406b927230a61d6daeff384fc771500224f7228 Mon Sep 17 00:00:00 2001 From: Phil Sturgeon Date: Sat, 7 Dec 2013 09:26:04 -0500 Subject: [PATCH 175/843] Updated mwop's Twitter account --- _posts/13-01-01-Resources.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/13-01-01-Resources.md b/_posts/13-01-01-Resources.md index 3837fbcd0..9466aa581 100644 --- a/_posts/13-01-01-Resources.md +++ b/_posts/13-01-01-Resources.md @@ -12,7 +12,7 @@ * [Derick Rethans](http://twitter.com/derickr) * [Chris Shiflett](http://twitter.com/shiflett) * [Sebastian Bergmann](http://twitter.com/s_bergmann) -* [Matthew Weier O'Phinney](http://twitter.com/weierophinney) +* [Matthew Weier O'Phinney](http://twitter.com/mwop) * [Pádraic Brady](http://twitter.com/padraicb) * [Anthony Ferrara](http://twitter.com/ircmaxell) * [Nikita Popov](http://twitter.com/nikita_ppv) From 710cba2569c15d94127438a21a05ea7e2bceaf83 Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Sun, 8 Dec 2013 16:02:22 +0100 Subject: [PATCH 176/843] coding style fix --- _posts/07-01-01-Databases.md | 2 +- _posts/09-03-01-Password-Hashing.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/_posts/07-01-01-Databases.md b/_posts/07-01-01-Databases.md index 5f024fa33..7f37417bb 100644 --- a/_posts/07-01-01-Databases.md +++ b/_posts/07-01-01-Databases.md @@ -45,7 +45,7 @@ which will delete all of your users! Instead, you should sanitize the ID input u prepare('SELECT name FROM users WHERE id = :id'); -$stmt->bindParam(':id', $_GET['id'], PDO::PARAM_INT); //<-- Automatically sanitized by PDO +$stmt->bindParam(':id', $_GET['id'], PDO::PARAM_INT); // <-- Automatically sanitized by PDO $stmt->execute(); {% endhighlight %} diff --git a/_posts/09-03-01-Password-Hashing.md b/_posts/09-03-01-Password-Hashing.md index cf9f544be..ad82acd63 100644 --- a/_posts/09-03-01-Password-Hashing.md +++ b/_posts/09-03-01-Password-Hashing.md @@ -22,9 +22,9 @@ require 'password.php'; $passwordHash = password_hash('secret-password', PASSWORD_DEFAULT); if (password_verify('bad-password', $passwordHash)) { - //Correct Password + // Correct Password } else { - //Wrong password + // Wrong password } {% endhighlight %} From 346e3fabdef5fee80bb8d411b219d39fbbc4b5f4 Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Sat, 2 Nov 2013 23:57:11 +0100 Subject: [PATCH 177/843] link to openshift fixed --- _posts/13-01-01-Resources.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/13-01-01-Resources.md b/_posts/13-01-01-Resources.md index 9466aa581..61c42fe6c 100644 --- a/_posts/13-01-01-Resources.md +++ b/_posts/13-01-01-Resources.md @@ -29,7 +29,7 @@ (PHP support is undocumented but based on stable Facebook partnership [link](http://net.tutsplus.com/tutorials/php/quick-tip-deploy-php-to-heroku-in-seconds/)) * [fortrabbit](http://fortrabbit.com/) * [Engine Yard Cloud](https://www.engineyard.com/products/cloud) -* [Red Hat OpenShift Platform](http://www.redhat.com/products/cloud-computing/openshift/) +* [Red Hat OpenShift Platform](http://openshift.com) * [dotCloud](http://docs.dotcloud.com/services/php/) * [AWS Elastic Beanstalk](http://aws.amazon.com/elasticbeanstalk/) * [cloudControl](https://www.cloudcontrol.com/) From eb3cdfcbf65b72205c7d5360362051218bdaa5c1 Mon Sep 17 00:00:00 2001 From: Josh Lockhart Date: Fri, 13 Dec 2013 12:10:23 -0500 Subject: [PATCH 178/843] Update GA snippet --- _layouts/default.html | 2 +- _layouts/page.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/_layouts/default.html b/_layouts/default.html index aeb97c599..863dfa880 100644 --- a/_layouts/default.html +++ b/_layouts/default.html @@ -23,7 +23,7 @@ _gaq.push(['_trackPageview']); (function() { var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; - ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; + ga.src = ('https:' == document.location.protocol ? 'https://' : 'http://') + 'stats.g.doubleclick.net/dc.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); })(); diff --git a/_layouts/page.html b/_layouts/page.html index a3556b9d6..9c22aab4d 100644 --- a/_layouts/page.html +++ b/_layouts/page.html @@ -22,7 +22,7 @@ _gaq.push(['_trackPageview']); (function() { var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; - ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; + ga.src = ('https:' == document.location.protocol ? 'https://' : 'http://') + 'stats.g.doubleclick.net/dc.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); })(); From 371e113a91e4ba54e9a4f6e5a3c5b4b7405a24ac Mon Sep 17 00:00:00 2001 From: Phil Sturgeon Date: Wed, 8 Jan 2014 23:12:03 -0500 Subject: [PATCH 179/843] Added a note about VersionEye for Composer --- _posts/04-02-01-Composer-and-Packagist.md | 24 +++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/_posts/04-02-01-Composer-and-Packagist.md b/_posts/04-02-01-Composer-and-Packagist.md index fc67e0ba2..8cafc0922 100644 --- a/_posts/04-02-01-Composer-and-Packagist.md +++ b/_posts/04-02-01-Composer-and-Packagist.md @@ -36,16 +36,18 @@ The path `$HOME/local/bin` (or a directory of your choice) should be in your `$P When you come across documentation that states to run Composer as `php composer.phar install`, you can substitute that with: composer install + +This section will assume you have installed composer globally. ### How to Define and Install Dependencies -Composer keeps track of your project's dependencies in a file called `composer.json`. You can manage it by hand if you like, or use Composer itself. The `php composer.phar require` command adds a project dependency and if you don't have a `composer.json` file, one will be created. Here's an example that adds [Twig][2] as a dependency of your project. Run it in your project's root directory where you've downloaded `composer.phar`: +Composer keeps track of your project's dependencies in a file called `composer.json`. You can manage it by hand if you like, or use Composer itself. The `composer require` command adds a project dependency and if you don't have a `composer.json` file, one will be created. Here's an example that adds [Twig][2] as a dependency of your project. - php composer.phar require twig/twig:~1.8 + composer require twig/twig:~1.8 -Alternatively the `php composer.phar init` command will guide you through creating a full `composer.json` file for your project. Either way, once you've created your `composer.json` file you can tell Composer to download and install your dependencies into the `vendors/` directory. This also applies to projects you've downloaded that already provide a `composer.json` file: +Alternatively the `composer init` command will guide you through creating a full `composer.json` file for your project. Either way, once you've created your `composer.json` file you can tell Composer to download and install your dependencies into the `vendors/` directory. This also applies to projects you've downloaded that already provide a `composer.json` file: - php composer.phar install + composer install Next, add this line to your application's primary PHP file; this will tell PHP to use Composer's autoloader for your project dependencies. @@ -62,14 +64,20 @@ Composer creates a file called `composer.lock` which stores the exact version of This is most useful when you define your version requirements flexibly. For instance a version requirement of ~1.8 means "anything newer than 1.8.0, but less than 2.0.x-dev". You can also use the `*` wildcard as in `1.8.*`. Now Composer's `php composer.phar update` command will upgrade all your dependencies to the newest version that fits the restrictions you define. +### Update Notifcations + +To receive notifications about new version releases you can sign up for [VersionEye][3], a web service that can monitor +your GitHub and BitBucket accounts for `composer.json` files and send emails with new package releases. + ### Checking your dependencies for security issues -The [Security Advisories Checker][3] is a web service and a command-line tool, both will examine your `composer.lock` file and tell you if you need to update any of your dependencies. +The [Security Advisories Checker][4] is a web service and a command-line tool, both will examine your `composer.lock` file and tell you if you need to update any of your dependencies. -* [Learn about Composer][4] +* [Learn about Composer][5] [1]: http://packagist.org/ [2]: http://twig.sensiolabs.org -[3]: https://security.sensiolabs.org/ -[4]: http://getcomposer.org/doc/00-intro.md +[3]: https://www.versioneye.com/ +[4]: https://security.sensiolabs.org/ +[5]: http://getcomposer.org/doc/00-intro.md From 575297558681c212c0129340ee69b4e1db4e92bd Mon Sep 17 00:00:00 2001 From: Antonio Spinelli Date: Fri, 17 Jan 2014 10:42:14 -0200 Subject: [PATCH 180/843] Composer and Pakagist, fix typo --- _posts/04-02-01-Composer-and-Packagist.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/04-02-01-Composer-and-Packagist.md b/_posts/04-02-01-Composer-and-Packagist.md index 8cafc0922..0d45435ce 100644 --- a/_posts/04-02-01-Composer-and-Packagist.md +++ b/_posts/04-02-01-Composer-and-Packagist.md @@ -64,7 +64,7 @@ Composer creates a file called `composer.lock` which stores the exact version of This is most useful when you define your version requirements flexibly. For instance a version requirement of ~1.8 means "anything newer than 1.8.0, but less than 2.0.x-dev". You can also use the `*` wildcard as in `1.8.*`. Now Composer's `php composer.phar update` command will upgrade all your dependencies to the newest version that fits the restrictions you define. -### Update Notifcations +### Update Notifications To receive notifications about new version releases you can sign up for [VersionEye][3], a web service that can monitor your GitHub and BitBucket accounts for `composer.json` files and send emails with new package releases. From 960a5c529237025e1901cdf12dcda3ee70430718 Mon Sep 17 00:00:00 2001 From: kfuchs Date: Fri, 31 Jan 2014 10:31:45 -0500 Subject: [PATCH 181/843] Added Propel to the list --- _posts/07-01-01-Databases.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/_posts/07-01-01-Databases.md b/_posts/07-01-01-Databases.md index 7f37417bb..31ee070b1 100644 --- a/_posts/07-01-01-Databases.md +++ b/_posts/07-01-01-Databases.md @@ -73,6 +73,7 @@ Some abstraction layers have been built using the PSR-0 namespace standard so ca * [Aura SQL][6] * [Doctrine2 DBAL][2] +* [Propel][7] * [ZF2 Db][4] * [ZF1 Db][3] @@ -82,6 +83,7 @@ Some abstraction layers have been built using the PSR-0 namespace standard so ca [4]: http://packages.zendframework.com/docs/latest/manual/en/index.html#zend-db [5]: http://php.net/manual/en/pdo.connections.php [6]: https://github.com/auraphp/Aura.Sql +[7]: http://propelorm.org/Propel/ [mysql]: http://php.net/mysql [mysqli]: http://php.net/mysqli From 822da9c725bae26e08b369d6f4ca2267fb0343cc Mon Sep 17 00:00:00 2001 From: Phil Sturgeon Date: Fri, 31 Jan 2014 16:57:28 -0500 Subject: [PATCH 182/843] Hi PSR-0, this is PSR-4. I'm coming for you. --- _posts/02-01-01-Code-Style-Guide.md | 10 ++++++---- _posts/03-03-01-Namespaces.md | 22 ++++++++++++++++++---- _posts/07-01-01-Databases.md | 4 +++- 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/_posts/02-01-01-Code-Style-Guide.md b/_posts/02-01-01-Code-Style-Guide.md index f7a6d0c12..099d09b55 100644 --- a/_posts/02-01-01-Code-Style-Guide.md +++ b/_posts/02-01-01-Code-Style-Guide.md @@ -5,10 +5,10 @@ PHP developers to choose several of these and combine them into a single project (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] 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, Symfony, 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] has proposed and approved a series of style recommendations. Not all of them related +to code-style, but those that do are [PSR-0][psr0], [PSR-1][psr1], [PSR-2][psr2] and [PSR-4][psr4]. These recommendations +are merely a set of rules that some projects like Drupal, Zend, Symfony, 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 a known standard. This could be any combination of PSR's, or one of the coding standards made by PEAR or Zend. This means other developers can easily read and work with your code, @@ -17,6 +17,7 @@ and applications that implement the components can have consistency even when wo * [Read about PSR-0][psr0] * [Read about PSR-1][psr1] * [Read about PSR-2][psr2] +* [Read about PSR-4][psr4] * [Read about PEAR Coding Standards][pear-cs] * [Read about Zend Coding Standards][zend-cs] * [Read about Symfony Coding Standards][symfony-cs] @@ -34,6 +35,7 @@ by all current and future parties who may be working on the codebase. [psr0]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md [psr1]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-1-basic-coding-standard.md [psr2]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md +[psr4]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader.md [pear-cs]: http://pear.php.net/manual/en/standards.php [zend-cs]: http://framework.zend.com/wiki/display/ZFDEV2/Coding+Standards [symfony-cs]: http://symfony.com/doc/current/contributing/code/standards.html diff --git a/_posts/03-03-01-Namespaces.md b/_posts/03-03-01-Namespaces.md index bc6eed8dd..3f1fc2312 100644 --- a/_posts/03-03-01-Namespaces.md +++ b/_posts/03-03-01-Namespaces.md @@ -4,16 +4,30 @@ isChild: true ## Namespaces {#namespaces_title} -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. +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. +_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. +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. -One recommended way to use namespaces is outlined in [PSR-0][psr0], which aims to provide a standard file, class and namespace convention to allow plug-and-play code. +One recommended way to use namespaces is outlined in [PSR-0][psr0], which aims to provide a standard file, +class and namespace convention to allow plug-and-play code. + +In December 2013 the PHP-FIG created a new autoloading standard: [PSR-4][psr4], which one day will +probably replace PSR-0. Currently both are still usable, as PSR-4 required PHP 5.3 and many PHP 5.2-only +projects currently implement PSR-0. If you're going to use an autoloader standard for a new application or +package then you almost certainly want to look into PSR-4. * [Read about Namespaces][namespaces] * [Read about PSR-0][psr0] +* [Read about PSR-4][psr4] [namespaces]: http://php.net/manual/en/language.namespaces.php [psr0]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md +[psr4]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader.md \ No newline at end of file diff --git a/_posts/07-01-01-Databases.md b/_posts/07-01-01-Databases.md index 31ee070b1..17c5e5119 100644 --- a/_posts/07-01-01-Databases.md +++ b/_posts/07-01-01-Databases.md @@ -69,7 +69,7 @@ one database system that another is missing from another by wrapping your querie This will of course add a little overhead, but if you are building a portable application that needs to work with MySQL, PostgreSQL and SQLite then a little overhead will be worth it the sake of code cleanliness. -Some abstraction layers have been built using the PSR-0 namespace standard so can be installed in any application you like: +Some abstraction layers have been built using the [PSR-0][psr0] or [PSR-4][psr4] namespace standards so can be installed in any application you like: * [Aura SQL][6] * [Doctrine2 DBAL][2] @@ -88,3 +88,5 @@ Some abstraction layers have been built using the PSR-0 namespace standard so ca [mysql]: http://php.net/mysql [mysqli]: http://php.net/mysqli [pgsql]: http://php.net/pgsql +[psr0]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md +[psr4]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader.md From 3de54f0946593c6dd78e0bee91cace30a94bc07b Mon Sep 17 00:00:00 2001 From: Phil Sturgeon Date: Fri, 31 Jan 2014 16:58:37 -0500 Subject: [PATCH 183/843] s/d/s. --- _posts/03-03-01-Namespaces.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/03-03-01-Namespaces.md b/_posts/03-03-01-Namespaces.md index 3f1fc2312..23c728002 100644 --- a/_posts/03-03-01-Namespaces.md +++ b/_posts/03-03-01-Namespaces.md @@ -20,7 +20,7 @@ One recommended way to use namespaces is outlined in [PSR-0][psr0], which aims t class and namespace convention to allow plug-and-play code. In December 2013 the PHP-FIG created a new autoloading standard: [PSR-4][psr4], which one day will -probably replace PSR-0. Currently both are still usable, as PSR-4 required PHP 5.3 and many PHP 5.2-only +probably replace PSR-0. Currently both are still usable, as PSR-4 requires PHP 5.3 and many PHP 5.2-only projects currently implement PSR-0. If you're going to use an autoloader standard for a new application or package then you almost certainly want to look into PSR-4. From 90ff4d657b91859af58252cda09f3321361601ee Mon Sep 17 00:00:00 2001 From: kenden Date: Tue, 8 Oct 2013 13:47:59 +0200 Subject: [PATCH 184/843] Update 09-04-01-Complementary-Testing-Tools.md Updating link to the PHPUnit-Selenium integration page to the current version of PHPUnit --- _posts/09-04-01-Complementary-Testing-Tools.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/09-04-01-Complementary-Testing-Tools.md b/_posts/09-04-01-Complementary-Testing-Tools.md index 034937ad3..1cbc3043f 100644 --- a/_posts/09-04-01-Complementary-Testing-Tools.md +++ b/_posts/09-04-01-Complementary-Testing-Tools.md @@ -8,6 +8,6 @@ Besides individual testing and behavior driven frameworks, there are also a numb ### Tool Links -* [Selenium](http://seleniumhq.org/) is a browser automation tool which can be [integrated with PHPUnit](http://www.phpunit.de/manual/3.1/en/selenium.html) +* [Selenium](http://seleniumhq.org/) is a browser automation tool which can be [integrated with PHPUnit](http://phpunit.de/manual/current/en/selenium.html) * [Mockery](https://github.com/padraic/mockery) is a Mock Object Framework which can be integrated with [PHPUnit](http://phpunit.de/) or [PHPSpec](http://www.phpspec.net/) * [Prophecy](https://github.com/phpspec/prophecy) is a highly opinionated yet very powerful and flexible PHP object mocking framework. It's integrated with [PHPSpec](http://www.phpspec.net/) and can be used with [PHPUnit](http://phpunit.de/). From 6a875d46774a2925d345ef230e29dbd05bd9b728 Mon Sep 17 00:00:00 2001 From: Jacek Kobus Date: Tue, 8 Oct 2013 22:27:05 +0200 Subject: [PATCH 185/843] added link to symfony coding standards --- _posts/02-01-01-Code-Style-Guide.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/_posts/02-01-01-Code-Style-Guide.md b/_posts/02-01-01-Code-Style-Guide.md index e9d4657a6..f7a6d0c12 100644 --- a/_posts/02-01-01-Code-Style-Guide.md +++ b/_posts/02-01-01-Code-Style-Guide.md @@ -19,6 +19,7 @@ and applications that implement the components can have consistency even when wo * [Read about PSR-2][psr2] * [Read about PEAR Coding Standards][pear-cs] * [Read about Zend Coding Standards][zend-cs] +* [Read about Symfony Coding Standards][symfony-cs] You can use [PHP_CodeSniffer][phpcs] to check code against any one of these recommendations, and plugins for text editors like [Sublime Text 2][st-cs] to be given real time feedback. @@ -35,6 +36,7 @@ by all current and future parties who may be working on the codebase. [psr2]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md [pear-cs]: http://pear.php.net/manual/en/standards.php [zend-cs]: http://framework.zend.com/wiki/display/ZFDEV2/Coding+Standards +[symfony-cs]: http://symfony.com/doc/current/contributing/code/standards.html [phpcs]: http://pear.php.net/package/PHP_CodeSniffer/ [st-cs]: https://github.com/benmatselby/sublime-phpcs [phpcsfixer]: http://cs.sensiolabs.org/ From 8ae8f569454e5da352785c97ec61cfd09fe8b2d4 Mon Sep 17 00:00:00 2001 From: Matthew Malinowski Date: Wed, 6 Nov 2013 10:03:23 -0500 Subject: [PATCH 186/843] Add Mavericks PHP version to Mac Setup. --- _posts/01-04-01-Mac-Setup.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_posts/01-04-01-Mac-Setup.md b/_posts/01-04-01-Mac-Setup.md index c394dea76..aa2fa2930 100644 --- a/_posts/01-04-01-Mac-Setup.md +++ b/_posts/01-04-01-Mac-Setup.md @@ -4,8 +4,8 @@ isChild: true ## Mac Setup {#mac_setup_title} -OSX comes prepackaged with PHP but it is normally a little behind the latest stable. Lion comes with PHP 5.3.6 and -Mountain Lion has 5.3.10. +OSX comes prepackaged with PHP but it is normally a little behind the latest stable. Lion comes with PHP 5.3.6, +Mountain Lion has 5.3.10, and Mavericks has 5.4.17. To update PHP on OSX you can get it installed through a number of Mac [package managers][mac-package-managers], with [php-osx by Liip][php-osx-downloads] being recommended. From 12414b2f6cf528ab1109818474fd60b53555e16a Mon Sep 17 00:00:00 2001 From: Alastair Hole Date: Wed, 20 Nov 2013 16:29:44 +0000 Subject: [PATCH 187/843] Update 03-06-01-XDebug.md Corrected MacGBDp to MacGDBp --- _posts/03-06-01-XDebug.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/03-06-01-XDebug.md b/_posts/03-06-01-XDebug.md index 402eb1ec6..8334b5c4e 100644 --- a/_posts/03-06-01-XDebug.md +++ b/_posts/03-06-01-XDebug.md @@ -31,7 +31,7 @@ Your IDE will now intercept the current state as the script executes, allowing y values in memory. Graphical debuggers make it very easy to step through code, inspect variables, and eval code against the live runtime. -Many IDE's have built-in or plugin-based support for graphical debugging with xdebug. MacGBDp is a free, open-source, +Many IDE's have built-in or plugin-based support for graphical debugging with xdebug. MacGDBp is a free, open-source, stand-alone xdebug GUI for Mac. * [Learn more about XDebug][xdebug-docs] From 688ef4f99fe8bc42c156149e42988712ad280a34 Mon Sep 17 00:00:00 2001 From: happyaccidents Date: Tue, 26 Nov 2013 14:35:06 +0000 Subject: [PATCH 188/843] Renamed posts to allow Dependency Injection to be added --- _posts/{06-01-01-Databases.md => 08-01-01-Databases.md} | 0 _posts/{07-02-01-Errors.md => 08-02-01-Errors.md} | 0 _posts/{07-03-01-Exceptions.md => 08-03-01-Exceptions.md} | 0 _posts/{08-01-01-Security.md => 09-01-01-Security.md} | 0 ...plication-Security.md => 09-02-01-Web-Application-Security.md} | 0 ...{08-03-01-Password-Hashing.md => 09-03-01-Password-Hashing.md} | 0 _posts/{08-04-01-Data-Filtering.md => 09-04-01-Data-Filtering.md} | 0 ...-01-Configuration-Files.md => 09-05-01-Configuration-Files.md} | 0 ...{08-06-01-Register-Globals.md => 09-06-01-Register-Globals.md} | 0 .../{08-07-01-Error-Reporting.md => 09-07-01-Error-Reporting.md} | 0 _posts/{09-01-01-Testing.md => 10-01-01-Testing.md} | 0 ...-Driven-Development.md => 10-02-01-Test-Driven-Development.md} | 0 ...ven-Development.md => 10-03-01-Behavior-Driven-Development.md} | 0 ...y-Testing-Tools.md => 10-04-01-Complementary-Testing-Tools.md} | 0 ...rvers-and-Deployment.md => 11-01-01-Servers-and-Deployment.md} | 0 ...Platform-as-a-Service.md => 11-02-01-Platform-as-a-Service.md} | 0 ...icated-Servers.md => 11-03-01-Virtual-or-Dedicated-Servers.md} | 0 _posts/{10-04-01-Shared-Servers.md => 11-04-01-Shared-Servers.md} | 0 ...-your-Application.md => 11-05-01-Building-your-Application.md} | 0 _posts/{11-01-01-Caching.md => 12-01-01-Caching.md} | 0 _posts/{11-02-01-Bytecode-Cache.md => 12-02-01-Bytecode-Cache.md} | 0 _posts/{11-03-01-Object-Caching.md => 12-03-01-Object-Caching.md} | 0 _posts/{12-01-01-Resources.md => 13-01-01-Resources.md} | 0 _posts/{12-02-01-Frameworks.md => 13-02-01-Frameworks.md} | 0 _posts/{12-03-01-Components.md => 13-03-01-Components.md} | 0 _posts/{13-01-01-Community.md => 14-01-01-Community.md} | 0 26 files changed, 0 insertions(+), 0 deletions(-) rename _posts/{06-01-01-Databases.md => 08-01-01-Databases.md} (100%) rename _posts/{07-02-01-Errors.md => 08-02-01-Errors.md} (100%) rename _posts/{07-03-01-Exceptions.md => 08-03-01-Exceptions.md} (100%) rename _posts/{08-01-01-Security.md => 09-01-01-Security.md} (100%) rename _posts/{08-02-01-Web-Application-Security.md => 09-02-01-Web-Application-Security.md} (100%) rename _posts/{08-03-01-Password-Hashing.md => 09-03-01-Password-Hashing.md} (100%) rename _posts/{08-04-01-Data-Filtering.md => 09-04-01-Data-Filtering.md} (100%) rename _posts/{08-05-01-Configuration-Files.md => 09-05-01-Configuration-Files.md} (100%) rename _posts/{08-06-01-Register-Globals.md => 09-06-01-Register-Globals.md} (100%) rename _posts/{08-07-01-Error-Reporting.md => 09-07-01-Error-Reporting.md} (100%) rename _posts/{09-01-01-Testing.md => 10-01-01-Testing.md} (100%) rename _posts/{09-02-01-Test-Driven-Development.md => 10-02-01-Test-Driven-Development.md} (100%) rename _posts/{09-03-01-Behavior-Driven-Development.md => 10-03-01-Behavior-Driven-Development.md} (100%) rename _posts/{09-04-01-Complementary-Testing-Tools.md => 10-04-01-Complementary-Testing-Tools.md} (100%) rename _posts/{10-01-01-Servers-and-Deployment.md => 11-01-01-Servers-and-Deployment.md} (100%) rename _posts/{10-02-01-Platform-as-a-Service.md => 11-02-01-Platform-as-a-Service.md} (100%) rename _posts/{10-03-01-Virtual-or-Dedicated-Servers.md => 11-03-01-Virtual-or-Dedicated-Servers.md} (100%) rename _posts/{10-04-01-Shared-Servers.md => 11-04-01-Shared-Servers.md} (100%) rename _posts/{10-05-01-Building-your-Application.md => 11-05-01-Building-your-Application.md} (100%) rename _posts/{11-01-01-Caching.md => 12-01-01-Caching.md} (100%) rename _posts/{11-02-01-Bytecode-Cache.md => 12-02-01-Bytecode-Cache.md} (100%) rename _posts/{11-03-01-Object-Caching.md => 12-03-01-Object-Caching.md} (100%) rename _posts/{12-01-01-Resources.md => 13-01-01-Resources.md} (100%) rename _posts/{12-02-01-Frameworks.md => 13-02-01-Frameworks.md} (100%) rename _posts/{12-03-01-Components.md => 13-03-01-Components.md} (100%) rename _posts/{13-01-01-Community.md => 14-01-01-Community.md} (100%) diff --git a/_posts/06-01-01-Databases.md b/_posts/08-01-01-Databases.md similarity index 100% rename from _posts/06-01-01-Databases.md rename to _posts/08-01-01-Databases.md diff --git a/_posts/07-02-01-Errors.md b/_posts/08-02-01-Errors.md similarity index 100% rename from _posts/07-02-01-Errors.md rename to _posts/08-02-01-Errors.md diff --git a/_posts/07-03-01-Exceptions.md b/_posts/08-03-01-Exceptions.md similarity index 100% rename from _posts/07-03-01-Exceptions.md rename to _posts/08-03-01-Exceptions.md diff --git a/_posts/08-01-01-Security.md b/_posts/09-01-01-Security.md similarity index 100% rename from _posts/08-01-01-Security.md rename to _posts/09-01-01-Security.md diff --git a/_posts/08-02-01-Web-Application-Security.md b/_posts/09-02-01-Web-Application-Security.md similarity index 100% rename from _posts/08-02-01-Web-Application-Security.md rename to _posts/09-02-01-Web-Application-Security.md diff --git a/_posts/08-03-01-Password-Hashing.md b/_posts/09-03-01-Password-Hashing.md similarity index 100% rename from _posts/08-03-01-Password-Hashing.md rename to _posts/09-03-01-Password-Hashing.md diff --git a/_posts/08-04-01-Data-Filtering.md b/_posts/09-04-01-Data-Filtering.md similarity index 100% rename from _posts/08-04-01-Data-Filtering.md rename to _posts/09-04-01-Data-Filtering.md diff --git a/_posts/08-05-01-Configuration-Files.md b/_posts/09-05-01-Configuration-Files.md similarity index 100% rename from _posts/08-05-01-Configuration-Files.md rename to _posts/09-05-01-Configuration-Files.md diff --git a/_posts/08-06-01-Register-Globals.md b/_posts/09-06-01-Register-Globals.md similarity index 100% rename from _posts/08-06-01-Register-Globals.md rename to _posts/09-06-01-Register-Globals.md diff --git a/_posts/08-07-01-Error-Reporting.md b/_posts/09-07-01-Error-Reporting.md similarity index 100% rename from _posts/08-07-01-Error-Reporting.md rename to _posts/09-07-01-Error-Reporting.md diff --git a/_posts/09-01-01-Testing.md b/_posts/10-01-01-Testing.md similarity index 100% rename from _posts/09-01-01-Testing.md rename to _posts/10-01-01-Testing.md diff --git a/_posts/09-02-01-Test-Driven-Development.md b/_posts/10-02-01-Test-Driven-Development.md similarity index 100% rename from _posts/09-02-01-Test-Driven-Development.md rename to _posts/10-02-01-Test-Driven-Development.md diff --git a/_posts/09-03-01-Behavior-Driven-Development.md b/_posts/10-03-01-Behavior-Driven-Development.md similarity index 100% rename from _posts/09-03-01-Behavior-Driven-Development.md rename to _posts/10-03-01-Behavior-Driven-Development.md diff --git a/_posts/09-04-01-Complementary-Testing-Tools.md b/_posts/10-04-01-Complementary-Testing-Tools.md similarity index 100% rename from _posts/09-04-01-Complementary-Testing-Tools.md rename to _posts/10-04-01-Complementary-Testing-Tools.md diff --git a/_posts/10-01-01-Servers-and-Deployment.md b/_posts/11-01-01-Servers-and-Deployment.md similarity index 100% rename from _posts/10-01-01-Servers-and-Deployment.md rename to _posts/11-01-01-Servers-and-Deployment.md diff --git a/_posts/10-02-01-Platform-as-a-Service.md b/_posts/11-02-01-Platform-as-a-Service.md similarity index 100% rename from _posts/10-02-01-Platform-as-a-Service.md rename to _posts/11-02-01-Platform-as-a-Service.md diff --git a/_posts/10-03-01-Virtual-or-Dedicated-Servers.md b/_posts/11-03-01-Virtual-or-Dedicated-Servers.md similarity index 100% rename from _posts/10-03-01-Virtual-or-Dedicated-Servers.md rename to _posts/11-03-01-Virtual-or-Dedicated-Servers.md diff --git a/_posts/10-04-01-Shared-Servers.md b/_posts/11-04-01-Shared-Servers.md similarity index 100% rename from _posts/10-04-01-Shared-Servers.md rename to _posts/11-04-01-Shared-Servers.md diff --git a/_posts/10-05-01-Building-your-Application.md b/_posts/11-05-01-Building-your-Application.md similarity index 100% rename from _posts/10-05-01-Building-your-Application.md rename to _posts/11-05-01-Building-your-Application.md diff --git a/_posts/11-01-01-Caching.md b/_posts/12-01-01-Caching.md similarity index 100% rename from _posts/11-01-01-Caching.md rename to _posts/12-01-01-Caching.md diff --git a/_posts/11-02-01-Bytecode-Cache.md b/_posts/12-02-01-Bytecode-Cache.md similarity index 100% rename from _posts/11-02-01-Bytecode-Cache.md rename to _posts/12-02-01-Bytecode-Cache.md diff --git a/_posts/11-03-01-Object-Caching.md b/_posts/12-03-01-Object-Caching.md similarity index 100% rename from _posts/11-03-01-Object-Caching.md rename to _posts/12-03-01-Object-Caching.md diff --git a/_posts/12-01-01-Resources.md b/_posts/13-01-01-Resources.md similarity index 100% rename from _posts/12-01-01-Resources.md rename to _posts/13-01-01-Resources.md diff --git a/_posts/12-02-01-Frameworks.md b/_posts/13-02-01-Frameworks.md similarity index 100% rename from _posts/12-02-01-Frameworks.md rename to _posts/13-02-01-Frameworks.md diff --git a/_posts/12-03-01-Components.md b/_posts/13-03-01-Components.md similarity index 100% rename from _posts/12-03-01-Components.md rename to _posts/13-03-01-Components.md diff --git a/_posts/13-01-01-Community.md b/_posts/14-01-01-Community.md similarity index 100% rename from _posts/13-01-01-Community.md rename to _posts/14-01-01-Community.md From 009ce6b18b19f1c48c82249401a49beb234c877b Mon Sep 17 00:00:00 2001 From: happyaccidents Date: Tue, 26 Nov 2013 14:37:09 +0000 Subject: [PATCH 189/843] Missed a rename --- _posts/{08-01-01-Databases.md => 07-01-01-Databases.md} | 0 ...Errors-and-Exceptions.md => 08-01-01-Errors-and-Exceptions.md} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename _posts/{08-01-01-Databases.md => 07-01-01-Databases.md} (100%) rename _posts/{07-01-01-Errors-and-Exceptions.md => 08-01-01-Errors-and-Exceptions.md} (100%) diff --git a/_posts/08-01-01-Databases.md b/_posts/07-01-01-Databases.md similarity index 100% rename from _posts/08-01-01-Databases.md rename to _posts/07-01-01-Databases.md diff --git a/_posts/07-01-01-Errors-and-Exceptions.md b/_posts/08-01-01-Errors-and-Exceptions.md similarity index 100% rename from _posts/07-01-01-Errors-and-Exceptions.md rename to _posts/08-01-01-Errors-and-Exceptions.md From 5e0f12004c5d962b17cd9b30fef01d80a46a96b5 Mon Sep 17 00:00:00 2001 From: happyaccidents Date: Thu, 28 Nov 2013 12:17:44 +0000 Subject: [PATCH 190/843] First draft - Resolves #280 --- _posts/06-01-01-Dependency-Injection.md | 8 ++++ _posts/06-02-01-Basic-Concept.md | 57 +++++++++++++++++++++++++ _posts/06-03-01-Complex-Problem.md | 49 +++++++++++++++++++++ _posts/06-04-01-Containers.md | 14 ++++++ _posts/06-05-01-Further-Reading.md | 11 +++++ 5 files changed, 139 insertions(+) create mode 100644 _posts/06-01-01-Dependency-Injection.md create mode 100644 _posts/06-02-01-Basic-Concept.md create mode 100644 _posts/06-03-01-Complex-Problem.md create mode 100644 _posts/06-04-01-Containers.md create mode 100644 _posts/06-05-01-Further-Reading.md diff --git a/_posts/06-01-01-Dependency-Injection.md b/_posts/06-01-01-Dependency-Injection.md new file mode 100644 index 000000000..3bac06ed7 --- /dev/null +++ b/_posts/06-01-01-Dependency-Injection.md @@ -0,0 +1,8 @@ +--- +title: Dependency Injection +--- + +# Dependency Injection {#dependency_injection_title} + +Dependency Injection is a basic concept that solves a complex problem. As a software design pattern it is being adopted in +some way or another by all major PHP projects. diff --git a/_posts/06-02-01-Basic-Concept.md b/_posts/06-02-01-Basic-Concept.md new file mode 100644 index 000000000..1748afea0 --- /dev/null +++ b/_posts/06-02-01-Basic-Concept.md @@ -0,0 +1,57 @@ +--- +isChild: true +--- + +## Basic Concept {#basic_concept_title} + +From [Wikipedia](http://en.wikipedia.org/wiki/Dependency_injection): + +> Dependency injection is a software design pattern that allows the removal of hard-coded dependencies and makes it +> possible to change them, whether at run-time or compile-time. + +This quote makes the concept sound much more complicated than it actually is. Dependency Injection is providing a component +with it's dependencies either through constructor injection, method calls or the setting of properties. It is that simple. + +We can demonstrate the concept with a simple, yet naive, example. + +{% highlight php %} +adapter = new MySqlAdapter; + } +} + +class MysqlAdapter {} +{% endhighlight %} + +Here we have a `Database` class that requires an adapter to speak to the database. We instantiate the +adapter in the constructor and create a hard dependency. This code can be refactored to use Dependency Injection +and therefore loosen the dependency. + +{% highlight php %} +adapter = $adapter; + } +} + +class MysqlAdapter {} +{% endhighlight %} + +Now we are giving the `Database` class it's dependency rather than it creating it itself. We could even create a method +that would accept an argument of the dependency and set it that way, or if the `$adapter` property was `public` we could +set it directly. diff --git a/_posts/06-03-01-Complex-Problem.md b/_posts/06-03-01-Complex-Problem.md new file mode 100644 index 000000000..07050d2f7 --- /dev/null +++ b/_posts/06-03-01-Complex-Problem.md @@ -0,0 +1,49 @@ +--- +isChild: true +--- + +## Complex Problem {#complex_problem_title} + +If you have ever read about Dependency Injection then you have probably seen the terms *"Inversion of Control"* or *"Dependency Inversion Principle"*. +These are the complex problems that Dependency Injection solves, or to be more precise, elegantly solves. + +For years, PHP frameworks have been achieving Inversion of Control, however, the question became, which part of control +are you inverting, and where to? For example, MVC frameworks would generally provide a super object or base controller that other +controllers must extend to gain access to it's dependencies. This **is** Inversion of Control, however, instead of loosening +dependencies, this method simply moved them. + +Dependency Injection allows us to more elegantly solve this problem by only injecting the dependencies we need, when we need them, +without the need for any hard coded dependencies at all. + +Dependency Inversion Principle is the "D" in the S.O.L.I.D set of object oriented design principles that states one should +*"Depend on Abstractions. Do not depend on concretions."*. Put simply, this means our dependencies should be interfaces/contracts or abstract +classes rather than concrete implementations. We can easily refactor the above example to follow this principle. + +{% highlight php %} +adapter = $adapter; + } +} + +interface AdapterInterface {} + +class MysqlAdapter implements AdapterInterface {} +{% endhighlight %} + +There are several benefits to the Database class now depending on an interface rather than a concretion. + +Consider that you are working in a team and the adapter is being worked on by a colleague. In our first example, we would have +to wait for said colleague to finish the adapter before we could properly mock it for our unit tests. Now that the dependency +is an interface/contract we can happily mock that interface knowing that our colleague will build the adapter based on that contract. + +An even bigger benefit to this method is that our code is now much more scalable. If a year down the line we decide that we +want to migrate to a different type of database, we can write an adapter that implements the original interface and inject that instead, +no more refactoring would be required as we can ensure that the adapter follows the contract set by the interface. diff --git a/_posts/06-04-01-Containers.md b/_posts/06-04-01-Containers.md new file mode 100644 index 000000000..b3eca748b --- /dev/null +++ b/_posts/06-04-01-Containers.md @@ -0,0 +1,14 @@ +--- +isChild: true +--- + +## Containers {#containers_title} + +The first thing you should understand about Dependency Injection Containers is that they are not the same thing as Dependency +Injection. A container is a convenience utility that helps us implement Dependency Injection, however, they can be and often +are misused to implement an anti pattern, Service Location. Using a container as a Service Locator within your classes arguably +creates a harder dependency on the container than the dependency you are replacing. It also makes your code much less transparent +and ultimately harder to test. + +Most modern frameworks have their own Dependency Injection Container that allows you to wire your dependencies together through configuration. +What this means in practice is that you can write application code that is as clean and de-coupled as the framework it is built on. diff --git a/_posts/06-05-01-Further-Reading.md b/_posts/06-05-01-Further-Reading.md new file mode 100644 index 000000000..e1d3645ba --- /dev/null +++ b/_posts/06-05-01-Further-Reading.md @@ -0,0 +1,11 @@ +--- +isChild: true +--- + +## Further Reading {#further_reading_title} + +- [Learning about Dependency Injection and PHP](http://ralphschindler.com/2011/05/18/learning-about-dependency-injection-and-php) +- [What is Dependency Injection?](http://fabien.potencier.org/article/11/what-is-dependency-injection) +- [Dependency Injection: An analogy](http://mwop.net/blog/260-Dependency-Injection-An-analogy.html) +- [Dependency Injection: Huh?](http://net.tutsplus.com/tutorials/php/dependency-injection-huh/) +- [Dependency Injection as a tool for testing](http://www.happyaccidents.me/dependency-injection-as-a-tool-for-testing/) From aaebe65095c2f17726dc086e8d108642eac5aefd Mon Sep 17 00:00:00 2001 From: happyaccidents Date: Thu, 28 Nov 2013 14:00:56 +0000 Subject: [PATCH 191/843] Revisions --- _posts/06-01-01-Dependency-Injection.md | 9 +++++++-- _posts/06-02-01-Basic-Concept.md | 16 +++++----------- _posts/06-03-01-Complex-Problem.md | 9 ++++++++- 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/_posts/06-01-01-Dependency-Injection.md b/_posts/06-01-01-Dependency-Injection.md index 3bac06ed7..e69c4a254 100644 --- a/_posts/06-01-01-Dependency-Injection.md +++ b/_posts/06-01-01-Dependency-Injection.md @@ -4,5 +4,10 @@ title: Dependency Injection # Dependency Injection {#dependency_injection_title} -Dependency Injection is a basic concept that solves a complex problem. As a software design pattern it is being adopted in -some way or another by all major PHP projects. +From [Wikipedia](http://en.wikipedia.org/wiki/Dependency_injection): + +> Dependency injection is a software design pattern that allows the removal of hard-coded dependencies and makes it +> possible to change them, whether at run-time or compile-time. + +This quote makes the concept sound much more complicated than it actually is. Dependency Injection is providing a component +with it's dependencies either through constructor injection, method calls or the setting of properties. It is that simple. diff --git a/_posts/06-02-01-Basic-Concept.md b/_posts/06-02-01-Basic-Concept.md index 1748afea0..520415bac 100644 --- a/_posts/06-02-01-Basic-Concept.md +++ b/_posts/06-02-01-Basic-Concept.md @@ -4,15 +4,11 @@ isChild: true ## Basic Concept {#basic_concept_title} -From [Wikipedia](http://en.wikipedia.org/wiki/Dependency_injection): +We can demonstrate the concept with a simple, yet naive. -> Dependency injection is a software design pattern that allows the removal of hard-coded dependencies and makes it -> possible to change them, whether at run-time or compile-time. - -This quote makes the concept sound much more complicated than it actually is. Dependency Injection is providing a component -with it's dependencies either through constructor injection, method calls or the setting of properties. It is that simple. - -We can demonstrate the concept with a simple, yet naive, example. +Here we have a `Database` class that requires an adapter to speak to the database. We instantiate the +adapter in the constructor and create a hard dependency. This makes testing difficult and means the `Database` class is +very tightly coupled to the adapter. {% highlight php %} Date: Fri, 29 Nov 2013 09:46:15 +0000 Subject: [PATCH 192/843] Typos and further change re comments --- _posts/06-03-01-Complex-Problem.md | 26 +++++++++++++------------- _posts/06-04-01-Containers.md | 10 +++++----- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/_posts/06-03-01-Complex-Problem.md b/_posts/06-03-01-Complex-Problem.md index 69e69fb0c..9fd0f21c1 100644 --- a/_posts/06-03-01-Complex-Problem.md +++ b/_posts/06-03-01-Complex-Problem.md @@ -4,26 +4,26 @@ isChild: true ## Complex Problem {#complex_problem_title} -If you have ever read about Dependency Injection then you have probably seen the terms *"Inversion of Control"* or *"Dependency Inversion Principle"*. +If you have ever read about Dependency Injection then you have probably seen the terms *"Inversion of Control"* or *"Dependency Inversion Principle"*. These are the complex problems that Dependency Injection solves. ### Inversion of Control -Inversion of Control is as it says, "inverting the control" of a system by keeping organisational control entirely separate from our objects. +Inversion of Control is as it says, "inverting the control" of a system by keeping organisational control entirely separate from our objects. In terms of Dependency Injection, this means loosening our dependencies by controlling and instantiating them elsewhere in the system. -For years, PHP frameworks have been achieving Inversion of Control, however, the question became, which part of control -are you inverting, and where to? For example, MVC frameworks would generally provide a super object or base controller that other -controllers must extend to gain access to it's dependencies. This **is** Inversion of Control, however, instead of loosening +For years, PHP frameworks have been achieving Inversion of Control, however, the question became, which part of control +are you inverting, and where to? For example, MVC frameworks would generally provide a super object or base controller that other +controllers must extend to gain access to its dependencies. This **is** Inversion of Control, however, instead of loosening dependencies, this method simply moved them. -Dependency Injection allows us to more elegantly solve this problem by only injecting the dependencies we need, when we need them, +Dependency Injection allows us to more elegantly solve this problem by only injecting the dependencies we need, when we need them, without the need for any hard coded dependencies at all. ### Dependency Inversion Principle -Dependency Inversion Principle is the "D" in the S.O.L.I.D set of object oriented design principles that states one should -*"Depend on Abstractions. Do not depend on concretions."*. Put simply, this means our dependencies should be interfaces/contracts or abstract +Dependency Inversion Principle is the "D" in the S.O.L.I.D set of object oriented design principles that states one should +*"Depend on Abstractions. Do not depend on concretions."*. Put simply, this means our dependencies should be interfaces/contracts or abstract classes rather than concrete implementations. We can easily refactor the above example to follow this principle. {% highlight php %} @@ -45,12 +45,12 @@ interface AdapterInterface {} class MysqlAdapter implements AdapterInterface {} {% endhighlight %} -There are several benefits to the Database class now depending on an interface rather than a concretion. +There are several benefits to the `Database` class now depending on an interface rather than a concretion. -Consider that you are working in a team and the adapter is being worked on by a colleague. In our first example, we would have -to wait for said colleague to finish the adapter before we could properly mock it for our unit tests. Now that the dependency +Consider that you are working in a team and the adapter is being worked on by a colleague. In our first example, we would have +to wait for said colleague to finish the adapter before we could properly mock it for our unit tests. Now that the dependency is an interface/contract we can happily mock that interface knowing that our colleague will build the adapter based on that contract. -An even bigger benefit to this method is that our code is now much more scalable. If a year down the line we decide that we -want to migrate to a different type of database, we can write an adapter that implements the original interface and inject that instead, +An even bigger benefit to this method is that our code is now much more scalable. If a year down the line we decide that we +want to migrate to a different type of database, we can write an adapter that implements the original interface and inject that instead, no more refactoring would be required as we can ensure that the adapter follows the contract set by the interface. diff --git a/_posts/06-04-01-Containers.md b/_posts/06-04-01-Containers.md index b3eca748b..f0e5466f8 100644 --- a/_posts/06-04-01-Containers.md +++ b/_posts/06-04-01-Containers.md @@ -4,11 +4,11 @@ isChild: true ## Containers {#containers_title} -The first thing you should understand about Dependency Injection Containers is that they are not the same thing as Dependency -Injection. A container is a convenience utility that helps us implement Dependency Injection, however, they can be and often -are misused to implement an anti pattern, Service Location. Using a container as a Service Locator within your classes arguably -creates a harder dependency on the container than the dependency you are replacing. It also makes your code much less transparent +The first thing you should understand about Dependency Injection Containers is that they are not the same thing as Dependency +Injection. A container is a convenience utility that helps us implement Dependency Injection, however, they can be and often +are misused to implement an anti-pattern, Service Location. Injecting a DI container as a Service Locator in to your classes arguably +creates a harder dependency on the container than the dependency you are replacing. It also makes your code much less transparent and ultimately harder to test. -Most modern frameworks have their own Dependency Injection Container that allows you to wire your dependencies together through configuration. +Most modern frameworks have their own Dependency Injection Container that allows you to wire your dependencies together through configuration. What this means in practice is that you can write application code that is as clean and de-coupled as the framework it is built on. From 3cb8aea787549ca68d231b19ac2fec7bf78dae73 Mon Sep 17 00:00:00 2001 From: Josh Lockhart Date: Fri, 29 Nov 2013 11:56:00 -0500 Subject: [PATCH 193/843] Fix DI typo --- _posts/06-02-01-Basic-Concept.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/_posts/06-02-01-Basic-Concept.md b/_posts/06-02-01-Basic-Concept.md index 520415bac..727ba7a2e 100644 --- a/_posts/06-02-01-Basic-Concept.md +++ b/_posts/06-02-01-Basic-Concept.md @@ -4,10 +4,10 @@ isChild: true ## Basic Concept {#basic_concept_title} -We can demonstrate the concept with a simple, yet naive. +We can demonstrate the concept with a simple, yet naive example. -Here we have a `Database` class that requires an adapter to speak to the database. We instantiate the -adapter in the constructor and create a hard dependency. This makes testing difficult and means the `Database` class is +Here we have a `Database` class that requires an adapter to speak to the database. We instantiate the +adapter in the constructor and create a hard dependency. This makes testing difficult and means the `Database` class is very tightly coupled to the adapter. {% highlight php %} @@ -46,6 +46,6 @@ class Database class MysqlAdapter {} {% endhighlight %} -Now we are giving the `Database` class it's dependency rather than it creating it itself. We could even create a method -that would accept an argument of the dependency and set it that way, or if the `$adapter` property was `public` we could +Now we are giving the `Database` class it's dependency rather than it creating it itself. We could even create a method +that would accept an argument of the dependency and set it that way, or if the `$adapter` property was `public` we could set it directly. From cd130fcb20f6aae8d1b5e31dfabe475d8c3433f9 Mon Sep 17 00:00:00 2001 From: Josh Lockhart Date: Fri, 29 Nov 2013 11:57:23 -0500 Subject: [PATCH 194/843] Fix DI typo --- _posts/06-02-01-Basic-Concept.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/06-02-01-Basic-Concept.md b/_posts/06-02-01-Basic-Concept.md index 727ba7a2e..fb9954be3 100644 --- a/_posts/06-02-01-Basic-Concept.md +++ b/_posts/06-02-01-Basic-Concept.md @@ -46,6 +46,6 @@ class Database class MysqlAdapter {} {% endhighlight %} -Now we are giving the `Database` class it's dependency rather than it creating it itself. We could even create a method +Now we are giving the `Database` class its dependency rather than it creating it itself. We could even create a method that would accept an argument of the dependency and set it that way, or if the `$adapter` property was `public` we could set it directly. From 0cc17ac2e19900d0292b0a6cae6129b8e9221ae5 Mon Sep 17 00:00:00 2001 From: Phil Sturgeon Date: Mon, 2 Dec 2013 10:23:11 -0500 Subject: [PATCH 195/843] Fixed link for Enhance PHP Thanks to @w00 for pointing this one out in #332. --- _posts/10-02-01-Test-Driven-Development.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/_posts/10-02-01-Test-Driven-Development.md b/_posts/10-02-01-Test-Driven-Development.md index f6571d4cb..71528d6c9 100644 --- a/_posts/10-02-01-Test-Driven-Development.md +++ b/_posts/10-02-01-Test-Driven-Development.md @@ -30,10 +30,11 @@ you run a project which accepts pull requests then you should suggest this as a [PHPUnit](http://phpunit.de) is the de-facto testing framework for writing unit tests for PHP applications, but there are several alternatives -* [SimpleTest](http://simpletest.org) -* [Enhance PHP](http://www.enhance-php.com/) -* [PUnit](http://punit.smf.me.uk/) * [atoum](https://github.com/atoum/atoum) +* [Enhance PHP](https://github.com/Enhance-PHP/Enhance-PHP) +* [PUnit](http://punit.smf.me.uk/) +* [SimpleTest](http://simpletest.org) + ### Integration Testing From 36135d613e1149530e400f6ec352ad48e8e49d08 Mon Sep 17 00:00:00 2001 From: Ryan Koven Date: Tue, 3 Dec 2013 13:45:16 -0800 Subject: [PATCH 196/843] Remove an extraneous 'to'; rectify an instance of an incorrect verb tense; small adjust to punctuation. Original text noted that it's "usually a good idea to follow to common patterns". Removed extra 'to'. In MVC section the sentence "The model-view-controller (MVC) pattern... let..." should be changed to "The model-view-controller (MVC) pattern...lets..." Also added a semicolon to a sentence in the Factory section that Strunk and White would agree enhances the clarity of the sentence. --- pages/Design-Patterns.md | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/pages/Design-Patterns.md b/pages/Design-Patterns.md index 4a3fe45ab..64618c2bc 100644 --- a/pages/Design-Patterns.md +++ b/pages/Design-Patterns.md @@ -6,7 +6,7 @@ title: Design Patterns # Design Patterns There are numerous ways to structure the code and project for you web application, and you can put as much or as little -thought as you like into architecting. But it is usually a good idea to follow to common patterns because it will make +thought as you like into architecting. But it is usually a good idea to follow common patterns because it will make your code easier to manage and easier for others to understand. * [Architectural pattern on Wikipedia](https://en.wikipedia.org/wiki/Architectural_pattern) @@ -51,7 +51,7 @@ print_r($veyron->get_make_and_model()); // outputs "Bugatti Veyron" {% endhighlight %} This code uses a factory to create the Automobile object. There are two possible benefits to building your code this -way, the first is that if you need to change, rename, or replace the Automobile class later on you can do so and you +way; the first is that if you need to change, rename, or replace the Automobile class later on you can do so and you will only have to modify the code in the factory, instead of every place in your project that uses the Automobile class. The second possible benefit is that if creating the object is a complicated job you can do all of the work in the factory, instead of repeating it every time you want to create a new instance. @@ -250,11 +250,7 @@ and gives you a central place to hook in code that should be run for every reque ## Model-View-Controller -The model-view-controller (MVC) pattern and its relatives HMVC and MVVM let you break up code into logical objects that -serve very specific purposes. Models serve as a data access layer where data is fetched and returned in formats usable -throughout your application. Controllers handle the request, process the data returned from models and load views to -send in the response. And views are display templates (markup, xml, etc) that are sent in the response to the web -browser. +The model-view-controller (MVC) pattern and its relatives HMVC and MVVM lets you break up code into logical objects that serve very specific purposes. Models serve as a data access layer where data is fetched and returned in formats usable throughout your application. Controllers handle the request, process the data returned from models and load views to send in the response. And views are display templates (markup, xml, etc) that are sent in the response to the web browser. MVC is the most common architectural pattern used in the popular [PHP frameworks](https://github.com/codeguy/php-the-right-way/wiki/Frameworks). From b41eeca6dad3b53dddbb06ec3df9552c5c7f969d Mon Sep 17 00:00:00 2001 From: Phil Sturgeon Date: Sat, 7 Dec 2013 09:26:04 -0500 Subject: [PATCH 197/843] Updated mwop's Twitter account --- _posts/13-01-01-Resources.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/13-01-01-Resources.md b/_posts/13-01-01-Resources.md index 3837fbcd0..9466aa581 100644 --- a/_posts/13-01-01-Resources.md +++ b/_posts/13-01-01-Resources.md @@ -12,7 +12,7 @@ * [Derick Rethans](http://twitter.com/derickr) * [Chris Shiflett](http://twitter.com/shiflett) * [Sebastian Bergmann](http://twitter.com/s_bergmann) -* [Matthew Weier O'Phinney](http://twitter.com/weierophinney) +* [Matthew Weier O'Phinney](http://twitter.com/mwop) * [Pádraic Brady](http://twitter.com/padraicb) * [Anthony Ferrara](http://twitter.com/ircmaxell) * [Nikita Popov](http://twitter.com/nikita_ppv) From ff25a697d4350db5270d1894695f6b5714ba617a Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Sun, 8 Dec 2013 16:02:22 +0100 Subject: [PATCH 198/843] coding style fix --- _posts/07-01-01-Databases.md | 2 +- _posts/09-03-01-Password-Hashing.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/_posts/07-01-01-Databases.md b/_posts/07-01-01-Databases.md index 5f024fa33..7f37417bb 100644 --- a/_posts/07-01-01-Databases.md +++ b/_posts/07-01-01-Databases.md @@ -45,7 +45,7 @@ which will delete all of your users! Instead, you should sanitize the ID input u prepare('SELECT name FROM users WHERE id = :id'); -$stmt->bindParam(':id', $_GET['id'], PDO::PARAM_INT); //<-- Automatically sanitized by PDO +$stmt->bindParam(':id', $_GET['id'], PDO::PARAM_INT); // <-- Automatically sanitized by PDO $stmt->execute(); {% endhighlight %} diff --git a/_posts/09-03-01-Password-Hashing.md b/_posts/09-03-01-Password-Hashing.md index cf9f544be..ad82acd63 100644 --- a/_posts/09-03-01-Password-Hashing.md +++ b/_posts/09-03-01-Password-Hashing.md @@ -22,9 +22,9 @@ require 'password.php'; $passwordHash = password_hash('secret-password', PASSWORD_DEFAULT); if (password_verify('bad-password', $passwordHash)) { - //Correct Password + // Correct Password } else { - //Wrong password + // Wrong password } {% endhighlight %} From 7e2b75d83a842d569ce9aa82bdd113ddfd529f2d Mon Sep 17 00:00:00 2001 From: Josh Lockhart Date: Fri, 13 Dec 2013 12:10:23 -0500 Subject: [PATCH 199/843] Update GA snippet --- _layouts/default.html | 2 +- _layouts/page.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/_layouts/default.html b/_layouts/default.html index aeb97c599..863dfa880 100644 --- a/_layouts/default.html +++ b/_layouts/default.html @@ -23,7 +23,7 @@ _gaq.push(['_trackPageview']); (function() { var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; - ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; + ga.src = ('https:' == document.location.protocol ? 'https://' : 'http://') + 'stats.g.doubleclick.net/dc.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); })(); diff --git a/_layouts/page.html b/_layouts/page.html index a3556b9d6..9c22aab4d 100644 --- a/_layouts/page.html +++ b/_layouts/page.html @@ -22,7 +22,7 @@ _gaq.push(['_trackPageview']); (function() { var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; - ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; + ga.src = ('https:' == document.location.protocol ? 'https://' : 'http://') + 'stats.g.doubleclick.net/dc.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); })(); From 28abaf18e5d2257f95b7a3ea268f8f3d45e9d49c Mon Sep 17 00:00:00 2001 From: Eric Martel Date: Sat, 1 Feb 2014 11:48:10 -0500 Subject: [PATCH 200/843] Style update changed the css to add the same 10px margin at the bottom of each section --- styles/site/site-navigation.less | 1 + 1 file changed, 1 insertion(+) diff --git a/styles/site/site-navigation.less b/styles/site/site-navigation.less index 4f5917990..5c9e80f77 100644 --- a/styles/site/site-navigation.less +++ b/styles/site/site-navigation.less @@ -19,6 +19,7 @@ .pan; .no-list; font-size: 16px; + margin-bottom: 10px; } .site-navigation > ul > li{ margin-bottom: 10px; From da53e99c4d0cb85c15e1f15c2e46cca26cf7a195 Mon Sep 17 00:00:00 2001 From: "Syed I.R" Date: Sun, 2 Feb 2014 20:16:04 +0530 Subject: [PATCH 201/843] Include Protobox Another online GUI service for Vagrant. It has some nice features like web apps and various other configs. [More info](http://getprotobox.com/) --- _posts/01-06-01-Vagrant.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/_posts/01-06-01-Vagrant.md b/_posts/01-06-01-Vagrant.md index c3768a548..4d64f1f26 100644 --- a/_posts/01-06-01-Vagrant.md +++ b/_posts/01-06-01-Vagrant.md @@ -21,15 +21,17 @@ create and edit your files on your host machine and then run the code inside you ### A little help -If you need a little help to start using Vagrant there are two services that might be useful: +If you need a little help to start using Vagrant there are three services that might be useful: - [Rove][rove]: service that allows you to pregenerate typical Vagrant builds, PHP among the options. The provisioning is made with Chef. - [Puphpet][puphpet]: simple GUI to set up virtual machines for PHP development. **Heavily focused in PHP**. Besides local VMs, can be used to deploy to cloud services as well. The provisioning is made with Puppet. +- [Protobox][protobox]: is a layer on top of vagrant and a web GUI to setup virtual machines for web development. A single YAML document controls everything that is installed on the virtual machine. [vagrant]: http://vagrantup.com/ [puppet]: http://www.puppetlabs.com/ [chef]: http://www.opscode.com/ [rove]: http://rove.io/ [puphpet]: https://puphpet.com/ +[protobox]: http://getprotobox.com/ From f03f924e9a361aefb434821a67892e3699f5bd5d Mon Sep 17 00:00:00 2001 From: e Date: Sun, 2 Feb 2014 23:43:19 -0500 Subject: [PATCH 202/843] Reformatted the index of the page and fixed the credits section --- _layouts/default.html | 55 +++++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 25 deletions(-) diff --git a/_layouts/default.html b/_layouts/default.html index 863dfa880..a30682015 100644 --- a/_layouts/default.html +++ b/_layouts/default.html @@ -32,7 +32,13 @@ diff --git a/_posts/01-01-01-Getting-Started.md b/_posts/01-01-01-Getting-Started.md index b3a75a0bf..5b28d5536 100644 --- a/_posts/01-01-01-Getting-Started.md +++ b/_posts/01-01-01-Getting-Started.md @@ -1,2 +1,6 @@ +--- +anchor: getting_started +--- + # Getting Started {#getting_started_title} diff --git a/_posts/01-02-01-Use-the-Current-Stable-Version.md b/_posts/01-02-01-Use-the-Current-Stable-Version.md index 1edc3ec82..16d2f1d34 100644 --- a/_posts/01-02-01-Use-the-Current-Stable-Version.md +++ b/_posts/01-02-01-Use-the-Current-Stable-Version.md @@ -1,9 +1,10 @@ --- title: Use the Current Stable Version (5.5) isChild: true +anchor: use_the_current_stable_version --- -## Use the Current Stable Version (5.5) {#use_the_current_stable_version_55_title} +## Use the Current Stable Version (5.5) {#use_the_current_stable_version_title} If you are just getting started with PHP make sure to start with the current stable release of [PHP 5.5][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.5 fool you, it represents _major_ improvements. If you are looking for a function or its usage, the documentation on the [php.net][php-docs] website will have the answer. diff --git a/_posts/01-03-01-Built-in-Web-Server.md b/_posts/01-03-01-Built-in-Web-Server.md index 2e9228d2a..a7b9fffad 100644 --- a/_posts/01-03-01-Built-in-Web-Server.md +++ b/_posts/01-03-01-Built-in-Web-Server.md @@ -1,6 +1,7 @@ --- title: Built-in Web Server isChild: true +anchor: builtin_web_server --- ## Built-in web server {#builtin_web_server_title} diff --git a/_posts/01-04-01-Mac-Setup.md b/_posts/01-04-01-Mac-Setup.md index aa2fa2930..3aed1e638 100644 --- a/_posts/01-04-01-Mac-Setup.md +++ b/_posts/01-04-01-Mac-Setup.md @@ -1,5 +1,6 @@ --- isChild: true +anchor: mac_setup --- ## Mac Setup {#mac_setup_title} diff --git a/_posts/01-05-01-Windows-Setup.md b/_posts/01-05-01-Windows-Setup.md index 87021e35f..cced0aea2 100644 --- a/_posts/01-05-01-Windows-Setup.md +++ b/_posts/01-05-01-Windows-Setup.md @@ -1,5 +1,6 @@ --- isChild: true +anchor: windows_setup --- ## Windows Setup {#windows_setup_title} diff --git a/_posts/01-06-01-Vagrant.md b/_posts/01-06-01-Vagrant.md index 4d64f1f26..b1b3a01b3 100644 --- a/_posts/01-06-01-Vagrant.md +++ b/_posts/01-06-01-Vagrant.md @@ -1,5 +1,6 @@ --- isChild: true +anchor: vagrant --- ## Vagrant {#vagrant_title} diff --git a/_posts/02-01-01-Code-Style-Guide.md b/_posts/02-01-01-Code-Style-Guide.md index 099d09b55..a48d6995c 100644 --- a/_posts/02-01-01-Code-Style-Guide.md +++ b/_posts/02-01-01-Code-Style-Guide.md @@ -1,3 +1,7 @@ +--- +anchor: code_style_guide +--- + # Code Style Guide {#code_style_guide_title} The PHP community is large and diverse, composed of innumerable libraries, frameworks, and components. It is common for diff --git a/_posts/03-01-01-Language-Highlights.md b/_posts/03-01-01-Language-Highlights.md index 9251ef3b0..c1f66c568 100644 --- a/_posts/03-01-01-Language-Highlights.md +++ b/_posts/03-01-01-Language-Highlights.md @@ -1 +1,5 @@ +--- +anchor: language_highlights +--- + # Language Highlights {#language_highlights_title} diff --git a/_posts/03-02-01-Programming-Paradigms.md b/_posts/03-02-01-Programming-Paradigms.md index 2da54d91b..bc7c486b3 100644 --- a/_posts/03-02-01-Programming-Paradigms.md +++ b/_posts/03-02-01-Programming-Paradigms.md @@ -1,5 +1,6 @@ --- isChild: true +anchor: programming_paradigms --- ## Programming Paradigms {#programming_paradigms_title} diff --git a/_posts/03-03-01-Namespaces.md b/_posts/03-03-01-Namespaces.md index 23c728002..e22b9684e 100644 --- a/_posts/03-03-01-Namespaces.md +++ b/_posts/03-03-01-Namespaces.md @@ -1,5 +1,6 @@ --- isChild: true +anchor: namespaces --- ## Namespaces {#namespaces_title} diff --git a/_posts/03-04-01-Standard-PHP-Library.md b/_posts/03-04-01-Standard-PHP-Library.md index 6ad4caaa7..3ce419a6a 100644 --- a/_posts/03-04-01-Standard-PHP-Library.md +++ b/_posts/03-04-01-Standard-PHP-Library.md @@ -1,6 +1,7 @@ --- title: Standard PHP Library isChild: true +anchor: standard_php_library --- ## Standard PHP Library {#standard_php_library_title} diff --git a/_posts/03-05-01-Command-Line-Interface.md b/_posts/03-05-01-Command-Line-Interface.md index 3cbaa16fb..bf40a8813 100644 --- a/_posts/03-05-01-Command-Line-Interface.md +++ b/_posts/03-05-01-Command-Line-Interface.md @@ -1,5 +1,6 @@ --- isChild: true +anchor: command_line_interface --- ## Command Line Interface {#command_line_interface_title} diff --git a/_posts/03-06-01-XDebug.md b/_posts/03-06-01-XDebug.md index 8334b5c4e..0f0622be8 100644 --- a/_posts/03-06-01-XDebug.md +++ b/_posts/03-06-01-XDebug.md @@ -1,6 +1,7 @@ --- title: XDebug isChild: true +anchor: xdebug --- ## XDebug {#xdebug_title} diff --git a/_posts/04-01-01-Dependency-Management.md b/_posts/04-01-01-Dependency-Management.md index 6937a7269..95be99436 100644 --- a/_posts/04-01-01-Dependency-Management.md +++ b/_posts/04-01-01-Dependency-Management.md @@ -1,3 +1,7 @@ +--- +anchor: dependency_management +--- + # Dependency Management {#dependency_management_title} 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. diff --git a/_posts/04-02-01-Composer-and-Packagist.md b/_posts/04-02-01-Composer-and-Packagist.md index 0d45435ce..ff532b8dc 100644 --- a/_posts/04-02-01-Composer-and-Packagist.md +++ b/_posts/04-02-01-Composer-and-Packagist.md @@ -1,5 +1,6 @@ --- isChild: true +anchor: composer_and_packagist --- ## Composer and Packagist {#composer_and_packagist_title} diff --git a/_posts/04-03-01-PEAR.md b/_posts/04-03-01-PEAR.md index f5315a8b0..c00b819f5 100644 --- a/_posts/04-03-01-PEAR.md +++ b/_posts/04-03-01-PEAR.md @@ -1,5 +1,6 @@ --- isChild: true +anchor: pear --- ## PEAR {#pear_title} diff --git a/_posts/05-01-01-Coding-Practices.md b/_posts/05-01-01-Coding-Practices.md index eff0ab3e2..8c41fd7ac 100644 --- a/_posts/05-01-01-Coding-Practices.md +++ b/_posts/05-01-01-Coding-Practices.md @@ -1 +1,5 @@ +--- +anchor: coding_practices +--- + # Coding Practices {#coding_practices_title} diff --git a/_posts/05-02-01-The-Basics.md b/_posts/05-02-01-The-Basics.md index 1e73d6ea2..78df40f16 100644 --- a/_posts/05-02-01-The-Basics.md +++ b/_posts/05-02-01-The-Basics.md @@ -1,5 +1,6 @@ --- isChild: true +anchor: the_basics --- ## The Basics {#the_basics_title} diff --git a/_posts/05-03-01-Date-and-Time.md b/_posts/05-03-01-Date-and-Time.md index e7af15918..f7f9a7b61 100644 --- a/_posts/05-03-01-Date-and-Time.md +++ b/_posts/05-03-01-Date-and-Time.md @@ -1,5 +1,6 @@ --- isChild: true +anchor: date_and_time --- ## Date and Time {#date_and_time_title} diff --git a/_posts/05-04-01-Design-Patterns.md b/_posts/05-04-01-Design-Patterns.md index eaf7f0eb9..3f6a0320b 100644 --- a/_posts/05-04-01-Design-Patterns.md +++ b/_posts/05-04-01-Design-Patterns.md @@ -1,5 +1,6 @@ --- isChild: true +anchor: design_patterns --- ## Design Patterns {#design_patterns_title} diff --git a/_posts/06-01-01-Dependency-Injection.md b/_posts/06-01-01-Dependency-Injection.md index 3bc3c07e5..f3e1ccbb7 100644 --- a/_posts/06-01-01-Dependency-Injection.md +++ b/_posts/06-01-01-Dependency-Injection.md @@ -1,5 +1,6 @@ --- title: Dependency Injection +anchor: dependency_injection --- # Dependency Injection {#dependency_injection_title} diff --git a/_posts/06-02-01-Basic-Concept.md b/_posts/06-02-01-Basic-Concept.md index fb9954be3..cc2eca765 100644 --- a/_posts/06-02-01-Basic-Concept.md +++ b/_posts/06-02-01-Basic-Concept.md @@ -1,5 +1,6 @@ --- isChild: true +anchor: basic_concept --- ## Basic Concept {#basic_concept_title} diff --git a/_posts/06-03-01-Complex-Problem.md b/_posts/06-03-01-Complex-Problem.md index 9fd0f21c1..3f2ae1c14 100644 --- a/_posts/06-03-01-Complex-Problem.md +++ b/_posts/06-03-01-Complex-Problem.md @@ -1,5 +1,6 @@ --- isChild: true +anchor: complex_problem --- ## Complex Problem {#complex_problem_title} diff --git a/_posts/06-04-01-Containers.md b/_posts/06-04-01-Containers.md index f0e5466f8..4b3acee83 100644 --- a/_posts/06-04-01-Containers.md +++ b/_posts/06-04-01-Containers.md @@ -1,5 +1,6 @@ --- isChild: true +anchor: containers --- ## Containers {#containers_title} diff --git a/_posts/06-05-01-Further-Reading.md b/_posts/06-05-01-Further-Reading.md index e1d3645ba..a437131cd 100644 --- a/_posts/06-05-01-Further-Reading.md +++ b/_posts/06-05-01-Further-Reading.md @@ -1,5 +1,6 @@ --- isChild: true +anchor: further_reading --- ## Further Reading {#further_reading_title} diff --git a/_posts/07-01-01-Databases.md b/_posts/07-01-01-Databases.md index 998040d5d..26258dc1e 100644 --- a/_posts/07-01-01-Databases.md +++ b/_posts/07-01-01-Databases.md @@ -1,5 +1,6 @@ --- title: Databases +anchor: databases --- # Databases {#databases_title} diff --git a/_posts/08-01-01-Errors-and-Exceptions.md b/_posts/08-01-01-Errors-and-Exceptions.md index f1b85667a..27e0b2ed8 100644 --- a/_posts/08-01-01-Errors-and-Exceptions.md +++ b/_posts/08-01-01-Errors-and-Exceptions.md @@ -1,5 +1,6 @@ --- title: Errors and Exceptions +anchor: errors_and_exceptions --- # Errors and Exceptions {#errors_and_exceptions_title} diff --git a/_posts/08-02-01-Errors.md b/_posts/08-02-01-Errors.md index 7edb5d2fd..be359e157 100644 --- a/_posts/08-02-01-Errors.md +++ b/_posts/08-02-01-Errors.md @@ -1,5 +1,6 @@ --- isChild: true +anchor: errors --- ## Errors {#errors_title} diff --git a/_posts/08-03-01-Exceptions.md b/_posts/08-03-01-Exceptions.md index 13b3a8dd2..e70169446 100644 --- a/_posts/08-03-01-Exceptions.md +++ b/_posts/08-03-01-Exceptions.md @@ -1,5 +1,6 @@ --- isChild: true +anchor: exceptions --- ## Exceptions {#exceptions_title} diff --git a/_posts/09-01-01-Security.md b/_posts/09-01-01-Security.md index 9c0b0007a..c8e3b489e 100644 --- a/_posts/09-01-01-Security.md +++ b/_posts/09-01-01-Security.md @@ -1 +1,5 @@ +--- +anchor: security +--- + # Security {#security_title} diff --git a/_posts/09-02-01-Web-Application-Security.md b/_posts/09-02-01-Web-Application-Security.md index 91709574e..da60b5f89 100644 --- a/_posts/09-02-01-Web-Application-Security.md +++ b/_posts/09-02-01-Web-Application-Security.md @@ -1,5 +1,6 @@ --- isChild: true +anchor: web_application_security --- ## Web Application Security {#web_application_security_title} diff --git a/_posts/09-03-01-Password-Hashing.md b/_posts/09-03-01-Password-Hashing.md index ad82acd63..d3e194d50 100644 --- a/_posts/09-03-01-Password-Hashing.md +++ b/_posts/09-03-01-Password-Hashing.md @@ -1,5 +1,6 @@ --- isChild: true +anchor: password_hashing --- ## Password Hashing {#password_hashing_title} diff --git a/_posts/09-04-01-Data-Filtering.md b/_posts/09-04-01-Data-Filtering.md index e262aaa68..b930eeb82 100644 --- a/_posts/09-04-01-Data-Filtering.md +++ b/_posts/09-04-01-Data-Filtering.md @@ -1,5 +1,6 @@ --- isChild: true +anchor: data_filtering --- ## Data Filtering {#data_filtering_title} diff --git a/_posts/09-05-01-Configuration-Files.md b/_posts/09-05-01-Configuration-Files.md index 50be4bc2b..c5da2b3cd 100644 --- a/_posts/09-05-01-Configuration-Files.md +++ b/_posts/09-05-01-Configuration-Files.md @@ -1,5 +1,6 @@ --- isChild: true +anchor: configuration_files --- ## Configuration Files {#configuration_files_title} diff --git a/_posts/09-06-01-Register-Globals.md b/_posts/09-06-01-Register-Globals.md index d7c8268a9..b2d1a6275 100644 --- a/_posts/09-06-01-Register-Globals.md +++ b/_posts/09-06-01-Register-Globals.md @@ -1,5 +1,6 @@ --- isChild: true +anchor: register_globals --- ## Register Globals {#register_globals_title} diff --git a/_posts/09-07-01-Error-Reporting.md b/_posts/09-07-01-Error-Reporting.md index 3d84b5cd0..b715ac155 100644 --- a/_posts/09-07-01-Error-Reporting.md +++ b/_posts/09-07-01-Error-Reporting.md @@ -1,5 +1,6 @@ --- isChild: true +anchor: error_reporting --- ## Error Reporting {#error_reporting_title} diff --git a/_posts/10-01-01-Testing.md b/_posts/10-01-01-Testing.md index 2eac35cd7..f08fc4d18 100644 --- a/_posts/10-01-01-Testing.md +++ b/_posts/10-01-01-Testing.md @@ -1,3 +1,7 @@ +--- +anchor: testing +--- + # Testing {#testing_title} Writing automated tests for your PHP code is considered a best practice and can lead to well-built diff --git a/_posts/10-02-01-Test-Driven-Development.md b/_posts/10-02-01-Test-Driven-Development.md index 71528d6c9..b3a7e4685 100644 --- a/_posts/10-02-01-Test-Driven-Development.md +++ b/_posts/10-02-01-Test-Driven-Development.md @@ -1,5 +1,6 @@ --- isChild: true +anchor: test_driven_development --- ## Test Driven Development {#test_driven_development_title} diff --git a/_posts/10-03-01-Behavior-Driven-Development.md b/_posts/10-03-01-Behavior-Driven-Development.md index d0cde20b0..94779c066 100644 --- a/_posts/10-03-01-Behavior-Driven-Development.md +++ b/_posts/10-03-01-Behavior-Driven-Development.md @@ -1,5 +1,6 @@ --- isChild: true +anchor: behavior_driven_development --- ## Behavior Driven Development {#behavior_driven_development_title} diff --git a/_posts/10-04-01-Complementary-Testing-Tools.md b/_posts/10-04-01-Complementary-Testing-Tools.md index 1cbc3043f..181824d17 100644 --- a/_posts/10-04-01-Complementary-Testing-Tools.md +++ b/_posts/10-04-01-Complementary-Testing-Tools.md @@ -1,5 +1,6 @@ --- isChild: true +anchor: complementary_testing_tools --- ## Complementary Testing Tools {#complementary_testing_tools_title} diff --git a/_posts/11-01-01-Servers-and-Deployment.md b/_posts/11-01-01-Servers-and-Deployment.md index 700ca16e6..f54a0e279 100644 --- a/_posts/11-01-01-Servers-and-Deployment.md +++ b/_posts/11-01-01-Servers-and-Deployment.md @@ -1,3 +1,7 @@ +--- +anchor: servers_and_deployment +--- + # Servers and Deployment {#servers_and_deployment_title} PHP applications can be deployed and run on production web servers in a number of ways. diff --git a/_posts/11-02-01-Platform-as-a-Service.md b/_posts/11-02-01-Platform-as-a-Service.md index e2aa16635..b72ba6f9a 100644 --- a/_posts/11-02-01-Platform-as-a-Service.md +++ b/_posts/11-02-01-Platform-as-a-Service.md @@ -1,9 +1,10 @@ --- title: Platform as a Service (PaaS) isChild: true +anchor: platform_as_a_service --- -## Platform as a Service (PaaS) {#platform_as_a_service_paas_title} +## Platform as a Service (PaaS) {#platform_as_a_service_title} PaaS provides the system and network architecture necessary to run PHP applications on the web. This means little to no configuration for launching PHP applications or PHP frameworks. diff --git a/_posts/11-03-01-Virtual-or-Dedicated-Servers.md b/_posts/11-03-01-Virtual-or-Dedicated-Servers.md index 2c1e72550..465b31901 100644 --- a/_posts/11-03-01-Virtual-or-Dedicated-Servers.md +++ b/_posts/11-03-01-Virtual-or-Dedicated-Servers.md @@ -1,5 +1,6 @@ --- isChild: true +anchor: virtual_or_dedicated_servers --- ## Virtual or Dedicated Servers {#virtual_or_dedicated_servers_title} diff --git a/_posts/11-04-01-Shared-Servers.md b/_posts/11-04-01-Shared-Servers.md index 3334bc893..d21afbefe 100644 --- a/_posts/11-04-01-Shared-Servers.md +++ b/_posts/11-04-01-Shared-Servers.md @@ -1,5 +1,6 @@ --- isChild: true +anchor: shared_servers --- ## Shared Servers {#shared_servers_title} diff --git a/_posts/11-05-01-Building-your-Application.md b/_posts/11-05-01-Building-your-Application.md index 59f6f9a09..6a9e5bc10 100644 --- a/_posts/11-05-01-Building-your-Application.md +++ b/_posts/11-05-01-Building-your-Application.md @@ -1,8 +1,9 @@ --- isChild: true +anchor: building_and_deploying_your_application --- -## Building and Deploying your Application {#build_title} +## Building and Deploying your Application {#building_and_deploying_your_application_title} If you find yourself doing manual database schema changes or running your tests manually before updating your files (manually), think twice! With every additional manual task needed to deploy a new version of your app, the chances for diff --git a/_posts/12-01-01-Caching.md b/_posts/12-01-01-Caching.md index 14bf05531..ce3c77e5c 100644 --- a/_posts/12-01-01-Caching.md +++ b/_posts/12-01-01-Caching.md @@ -1,3 +1,7 @@ +--- +anchor: caching +--- + # Caching {#caching_title} PHP is pretty quick by itself, but bottlenecks can arise when you make remote connections, load files, etc. diff --git a/_posts/12-02-01-Bytecode-Cache.md b/_posts/12-02-01-Bytecode-Cache.md index 73a583d11..4ae98a094 100644 --- a/_posts/12-02-01-Bytecode-Cache.md +++ b/_posts/12-02-01-Bytecode-Cache.md @@ -1,5 +1,6 @@ --- isChild: true +anchor: bytecode_cache --- ## Bytecode Cache {#bytecode_cache_title} diff --git a/_posts/12-03-01-Object-Caching.md b/_posts/12-03-01-Object-Caching.md index 7a91115c4..7fabfa91a 100644 --- a/_posts/12-03-01-Object-Caching.md +++ b/_posts/12-03-01-Object-Caching.md @@ -1,5 +1,6 @@ --- isChild: true +anchor: object_caching --- ## Object Caching {#object_caching_title} diff --git a/_posts/13-01-01-Resources.md b/_posts/13-01-01-Resources.md index 61c42fe6c..0d3ac38a4 100644 --- a/_posts/13-01-01-Resources.md +++ b/_posts/13-01-01-Resources.md @@ -1,3 +1,7 @@ +--- +anchor: resources +--- + # Resources {#resources_title} ## From the Source diff --git a/_posts/13-02-01-Frameworks.md b/_posts/13-02-01-Frameworks.md index 11e96f252..b2ea1227d 100644 --- a/_posts/13-02-01-Frameworks.md +++ b/_posts/13-02-01-Frameworks.md @@ -1,5 +1,6 @@ --- isChild: true +anchor: frameworks --- ## Frameworks {#frameworks_title} diff --git a/_posts/13-03-01-Components.md b/_posts/13-03-01-Components.md index a85c226e8..4669fadd8 100644 --- a/_posts/13-03-01-Components.md +++ b/_posts/13-03-01-Components.md @@ -1,5 +1,6 @@ --- isChild: true +anchor: components --- ## Components {#components_title} diff --git a/_posts/14-01-01-Community.md b/_posts/14-01-01-Community.md index 3c15f45cb..e89f9c86d 100644 --- a/_posts/14-01-01-Community.md +++ b/_posts/14-01-01-Community.md @@ -1,3 +1,7 @@ +--- +anchor: community +--- + # Community {#community_title} The PHP community is as diverse as it is large, and its members are ready and willing to support new PHP programmers. Consider joining your local PHP user group (PUG) or attending larger PHP conferences to learn more about the best practices shown here. You can hang out on IRC in the #phpc channel on [irc.freenode.com][php-irc] and follow the [@phpc][phpc-twitter] twitter account. Get out there, meet new developers, learn new topics, and above all, make new friends! Other community resources include the Google+ PHP [Programmer community][php-programmers-gplus] and [StackOverflow][php-so]. diff --git a/index.html b/index.html index f22d1fcb8..54bd0cd6f 100644 --- a/index.html +++ b/index.html @@ -11,7 +11,7 @@ {% if post.isChild != true and loop.first != true %} {{ backtotop|markdownify }} {% endif %} -
+
{{ post.content }}
{% endfor %} From ea52149ce03c10986ff9f6a0e41704b072dfc0d5 Mon Sep 17 00:00:00 2001 From: Phil Sturgeon Date: Tue, 18 Mar 2014 11:10:25 -0400 Subject: [PATCH 245/843] Added Orno to Components list --- _posts/13-03-01-Components.md | 1 + 1 file changed, 1 insertion(+) diff --git a/_posts/13-03-01-Components.md b/_posts/13-03-01-Components.md index 4669fadd8..b6809177f 100644 --- a/_posts/13-03-01-Components.md +++ b/_posts/13-03-01-Components.md @@ -26,6 +26,7 @@ itself. * [Aura](http://auraphp.github.com/) * [FuelPHP](https://github.com/fuelphp) * [Hoa Project](https://github.com/hoaproject) +* [Orno](https://github.com/orno) * [Symfony Components](http://symfony.com/doc/current/components/index.html) * [The League of Extraordinary Packages](http://thephpleague.com/) * Laravel's Illuminate Components From 5ef51c56265fbd3150cf6fca2c9b6c2e057ade91 Mon Sep 17 00:00:00 2001 From: Phil Sturgeon Date: Sun, 23 Mar 2014 17:53:15 -0400 Subject: [PATCH 246/843] Manually implemented #310 from @Trismegiste. --- _posts/08-03-01-Exceptions.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/_posts/08-03-01-Exceptions.md b/_posts/08-03-01-Exceptions.md index 13b3a8dd2..b5679a1f9 100644 --- a/_posts/08-03-01-Exceptions.md +++ b/_posts/08-03-01-Exceptions.md @@ -16,8 +16,8 @@ looking for a mistake and check the docs to see what the error method is for thi obvious. Another problem is when classes automatically throw an error to the screen and exit the process. When you do this you -stop another developer from being able to dynamically handle that error. Exceptions should be thrown to make a developer aware -of an error; they then can choose how to handle this. E.g.: +stop another developer from being able to dynamically handle that error. Exceptions should be thrown to make a developer +aware of an error; they then can choose how to handle this. E.g.: {% highlight php %} lot of custom Exceptions, some of which could have be provided in the [SPL extension][splext]. If for example you use the `__call()` Magic Method and an invalid method is requested then instead of throwing a standard -Exception which is vague, or creating a custom Exception just for that, you could just `throw new BadFunctionCallException;`. +Exception which is vague, or creating a custom Exception just for that, you could just `throw new BadMethodCallException;`. * [Read about Exceptions][exceptions] * [Read about SPL Exceptions][splexe] From 145e5eef7487fa94f6f2e7f0bf6c1a94f6cb88d6 Mon Sep 17 00:00:00 2001 From: George Mihailov Date: Wed, 26 Mar 2014 10:44:47 +0200 Subject: [PATCH 247/843] Link to collection of pattern implementations See https://github.com/domnikl/DesignPatternsPHP --- pages/Design-Patterns.md | 1 + 1 file changed, 1 insertion(+) diff --git a/pages/Design-Patterns.md b/pages/Design-Patterns.md index 22d85a08f..046db3ab1 100644 --- a/pages/Design-Patterns.md +++ b/pages/Design-Patterns.md @@ -11,6 +11,7 @@ your code easier to manage and easier for others to understand. * [Architectural pattern on Wikipedia](https://en.wikipedia.org/wiki/Architectural_pattern) * [Software design pattern on Wikipedia](https://en.wikipedia.org/wiki/Software_design_pattern) +* [Collection of implementation examples](https://github.com/domnikl/DesignPatternsPHP) ## Factory From df00f7ef0b1b10eff1c9b7f5d4d4d26ce53eae3d Mon Sep 17 00:00:00 2001 From: John Stevenson Date: Fri, 7 Feb 2014 17:16:46 +0000 Subject: [PATCH 248/843] Trim install instructions, add Windows installer --- _posts/04-02-01-Composer-and-Packagist.md | 33 ++++------------------- 1 file changed, 5 insertions(+), 28 deletions(-) diff --git a/_posts/04-02-01-Composer-and-Packagist.md b/_posts/04-02-01-Composer-and-Packagist.md index ff532b8dc..84d535b6e 100644 --- a/_posts/04-02-01-Composer-and-Packagist.md +++ b/_posts/04-02-01-Composer-and-Packagist.md @@ -9,36 +9,12 @@ Composer is a **brilliant** dependency manager for PHP. List your project's depe 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][1], the official repository for Composer-compatible PHP libraries. -### How to Install Composer - -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 https://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 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 https://getcomposer.org/composer.phar -o $HOME/local/bin/composer - chmod +x $HOME/local/bin/composer - -The path `$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: +### Installing Composer +Composer is a single file called `composer.phar`, which is a PHP binary archive. It can either be installed locally in each of your project directories or in a single global location that is in your `$PATH` environment variable. The global method is recommended because it enables you to run it from your current working directory with the command `composer`. So when you come across documentation that states to run Composer as `php composer.phar install`, you can substitute that with: composer install - -This section will assume you have installed composer globally. + +Detailed [installation instructions][5] can be found in the Composer documentation. For Windows users the easiest way to get up and running is to use the [ComposerSetup][6] installer. This section will assume you have installed Composer globally. ### How to Define and Install Dependencies @@ -81,4 +57,5 @@ The [Security Advisories Checker][4] is a web service and a command-line tool, b [3]: https://www.versioneye.com/ [4]: https://security.sensiolabs.org/ [5]: http://getcomposer.org/doc/00-intro.md +[6]: https://getcomposer.org/Composer-Setup.exe From e9a27625f20978bf0330820ea3b6c11a62079e1b Mon Sep 17 00:00:00 2001 From: johnstevenson Date: Wed, 26 Mar 2014 17:34:43 +0000 Subject: [PATCH 249/843] Add Windows installer --- _posts/04-02-01-Composer-and-Packagist.md | 35 ++++++++++++++++++++--- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/_posts/04-02-01-Composer-and-Packagist.md b/_posts/04-02-01-Composer-and-Packagist.md index 84d535b6e..9f3fa2721 100644 --- a/_posts/04-02-01-Composer-and-Packagist.md +++ b/_posts/04-02-01-Composer-and-Packagist.md @@ -9,12 +9,39 @@ Composer is a **brilliant** dependency manager for PHP. List your project's depe 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][1], the official repository for Composer-compatible PHP libraries. -### Installing Composer -Composer is a single file called `composer.phar`, which is a PHP binary archive. It can either be installed locally in each of your project directories or in a single global location that is in your `$PATH` environment variable. The global method is recommended because it enables you to run it from your current working directory with the command `composer`. So when you come across documentation that states to run Composer as `php composer.phar install`, you can substitute that with: +### How to Install Composer - composer install +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 https://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. + +#### Installing on Windows +For Windows users the easiest way to get up and running is to use the [ComposerSetup][6] installer, which performs a global install and sets up your `$PATH` so that you can just call `composer` from any directory in your command line. + +### 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: -Detailed [installation instructions][5] can be found in the Composer documentation. For Windows users the easiest way to get up and running is to use the [ComposerSetup][6] installer. This section will assume you have installed Composer globally. +- 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 https://getcomposer.org/composer.phar -o $HOME/local/bin/composer + chmod +x $HOME/local/bin/composer + +The path `$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 + +This section will assume you have installed composer globally. ### How to Define and Install Dependencies From bb34ffc77f2c1bfa6bf80297f0c20baaf1131115 Mon Sep 17 00:00:00 2001 From: phpdistiller Date: Sun, 30 Mar 2014 19:03:16 +0800 Subject: [PATCH 250/843] EasyPHP added EasyPHP is the oldest PHP package for Windows, and is more "up-to-date" than Wamp. It comes with a lot more features for developers: modules, components... --- _posts/01-05-01-Windows-Setup.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/_posts/01-05-01-Windows-Setup.md b/_posts/01-05-01-Windows-Setup.md index cced0aea2..f37e75d39 100644 --- a/_posts/01-05-01-Windows-Setup.md +++ b/_posts/01-05-01-Windows-Setup.md @@ -10,7 +10,7 @@ installer. The installer is no longer supported and stops at PHP 5.3.0. For learning and local development you can use the built in webserver with PHP 5.4+ so you don't need to worry about configuring it. If you would like an "all-in-one" which includes a full-blown webserver and MySQL too then tools such as the [Web Platform Installer][wpi], -[Zend Server CE][zsce], [XAMPP][xampp] and [WAMP][wamp] will help get a Windows development environment up and running fast. That said, these tools will be +[Zend Server CE][zsce], [XAMPP][xampp], [EasyPHP][easyphp] and [WAMP][wamp] will help get a Windows development environment up and running fast. That said, these tools will be a little different from production so be careful of environment differences if you are working on Windows and deploying to Linux. If you need to run your production system on Windows then IIS7 will give you the most stable and best performance. You can use @@ -23,5 +23,6 @@ PHP. [wpi]: http://www.microsoft.com/web/downloads/platform.aspx [zsce]: http://www.zend.com/en/products/server-ce/ [xampp]: http://www.apachefriends.org/en/xampp.html +[easyphp]: http://www.easyphp.org/ [wamp]: http://www.wampserver.com/ [php-iis]: http://php.iis.net/ From 059d3ff4bceaebb05d9c22093b92eb63ce0a5170 Mon Sep 17 00:00:00 2001 From: Yannick Lyn Fatt Date: Mon, 31 Mar 2014 00:36:31 -0500 Subject: [PATCH 251/843] fixed word wrapping (now 120 chars) Also added note about default encoding for htmlentities and htmlspecialchars and added link to php docs for htmlspecialchars --- _posts/05-05-01-PHP-and-UTF8.md | 49 +++++++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 12 deletions(-) diff --git a/_posts/05-05-01-PHP-and-UTF8.md b/_posts/05-05-01-PHP-and-UTF8.md index e0bd47ebc..7c98c0368 100644 --- a/_posts/05-05-01-PHP-and-UTF8.md +++ b/_posts/05-05-01-PHP-and-UTF8.md @@ -4,37 +4,61 @@ isChild: true ## PHP and UTF-8 {#php_and_utf8_title} -_This section was originally written by [Alex Cabal](https://alexcabal.com/) over at [PHP Best Practices](https://phpbestpractices.org/#utf-8) and has now been shared here_. +_This section was originally written by [Alex Cabal](https://alexcabal.com/) over at +[PHP Best Practices](https://phpbestpractices.org/#utf-8) and has now been shared here_. ### There's no one-liner. Be careful, detailed, and consistent. -Right now PHP does not support Unicode at a low level. There are ways to ensure that UTF-8 strings are processed OK, but it's not easy, and it requires digging in to almost all levels of the web app, from HTML to SQL to PHP. We'll aim for a brief, practical summary. +Right now PHP does not support Unicode at a low level. There are ways to ensure that UTF-8 strings are processed OK, +but it's not easy, and it requires digging in to almost all levels of the web app, from HTML to SQL to PHP. We'll aim +for a brief, practical summary. ### UTF-8 at the PHP level -The basic string operations, like concatenating two strings and assigning strings to variables, don't need anything special for UTF-8. However most string functions, like `strpos()` and `strlen()`, do need special consideration. These functions often have an `mb_*` counterpart: for example, `mb_strpos()` and `mb_strlen()`. Together, these counterpart functions are called the Multibyte String Functions. The multibyte string functions are specifically designed to operate on Unicode strings. +The basic string operations, like concatenating two strings and assigning strings to variables, don't need anything +special for UTF-8. However most string functions, like `strpos()` and `strlen()`, do need special consideration. These +functions often have an `mb_*` counterpart: for example, `mb_strpos()` and `mb_strlen()`. Together, these counterpart +functions are called the Multibyte String Functions. The multibyte string functions are specifically designed to +operate on Unicode strings. -You must use the `mb_*` functions whenever you operate on a Unicode string. For example, if you use `substr()` on a UTF-8 string, there's a good chance the result will include some garbled half-characters. The correct function to use would be the multibyte counterpart, `mb_substr()`. +You must use the `mb_*` functions whenever you operate on a Unicode string. For example, if you use `substr()` on a +UTF-8 string, there's a good chance the result will include some garbled half-characters. The correct function to use +would be the multibyte counterpart, `mb_substr()`. -The hard part is remembering to use the `mb_*` functions at all times. If you forget even just once, your Unicode string has a chance of being garbled during further processing. +The hard part is remembering to use the `mb_*` functions at all times. If you forget even just once, your Unicode +string has a chance of being garbled during further processing. -Not all string functions have an `mb_*` counterpart. If there isn't one for what you want to do, then you might be out of luck. +Not all string functions have an `mb_*` counterpart. If there isn't one for what you want to do, then you might be out +of luck. -Additionally, you should use the `mb_internal_encoding()` function at the top of every PHP script you write (or at the top of your global include script), and the `mb_http_output()` function right after it if your script is outputting to a browser. Explicitly defining the encoding of your strings in every script will save you a lot of headaches down the road. +Additionally, you should use the `mb_internal_encoding()` function at the top of every PHP script you write (or at the +top of your global include script), and the `mb_http_output()` function right after it if your script is outputting to +a browser. Explicitly defining the encoding of your strings in every script will save you a lot of headaches down the +road. + +Finally, many PHP functions that operate on strings have an optional parameter letting you specify the character +encoding. You should always explicitly indicate UTF-8 when given the option. For example, `htmlentities()` has an +option for character encoding, and you should always specify UTF-8 if dealing with such strings. + +Note that as of PHP 5.4.0, UTF-8 is the default encoding for `htmlentities()` and `htmlspecialchars()`. -Finally, many PHP functions that operate on strings have an optional parameter letting you specify the character encoding. You should always explicitly indicate UTF-8 when given the option. For example, `htmlentities()` has an option for character encoding, and you should always specify UTF-8 if dealing with such strings. ### UTF-8 at the Database level -If your PHP script accesses MySQL, there's a chance your strings could be stored as non-UTF-8 strings in the database even if you follow all of the precautions above. +If your PHP script accesses MySQL, there's a chance your strings could be stored as non-UTF-8 strings in the database +even if you follow all of the precautions above. -To make sure your strings go from PHP to MySQL as UTF-8, make sure your database and tables are all set to the `utf8mb4` character set and collation, and that you use the `utf8mb4` character set in the PDO connection string. See example code below. This is _critically important_. +To make sure your strings go from PHP to MySQL as UTF-8, make sure your database and tables are all set to the +`utf8mb4` character set and collation, and that you use the `utf8mb4` character set in the PDO connection string. See +example code below. This is _critically important_. -Note that you must use the `utf8mb4` character set for complete UTF-8 support, not the `utf8` character set! See Further Reading for why. +Note that you must use the `utf8mb4` character set for complete UTF-8 support, not the `utf8` character set! See +Further Reading for why. ### UTF-8 at the browser level -Use the `mb_http_output()` function to ensure that your PHP script outputs UTF-8 strings to your browser. In your HTML, include the [charset `` tag](http://htmlpurifier.org/docs/enduser-utf8.html) in your page's `` tag. +Use the `mb_http_output()` function to ensure that your PHP script outputs UTF-8 strings to your browser. In your HTML, +include the [charset `` tag](http://htmlpurifier.org/docs/enduser-utf8.html) in your page's `` tag. {% highlight php %} fetchAll(\PDO::FETCH_OBJ); * [`mb_internal_encoding()`](http://php.net/manual/en/function.mb-internal-encoding.php) * [`mb_http_output()`](http://php.net/manual/en/function.mb-http-output.php) * [`htmlentities()`](http://php.net/manual/en/function.htmlentities.php) + * [`htmlspecialchars()`](http://www.php.net/manual/en/function.htmlspecialchars.php) * [PHP UTF-8 Cheatsheet](http://blog.loftdigital.com/blog/php-utf-8-cheatsheet) * [Stack Overflow: What factors make PHP Unicode-incompatible?](http://stackoverflow.com/questions/571694/what-factors-make-php-unicode-incompatible) * [Stack Overflow: Best practices in PHP and MySQL with international strings](http://stackoverflow.com/questions/140728/best-practices-in-php-and-mysql-with-international-strings) From a6c7aec126f0966c12e689c56f7d0bef65e30671 Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Tue, 1 Apr 2014 02:02:26 +0200 Subject: [PATCH 252/843] anchor for php and UTF-8 section added --- _posts/05-05-01-PHP-and-UTF8.md | 1 + 1 file changed, 1 insertion(+) diff --git a/_posts/05-05-01-PHP-and-UTF8.md b/_posts/05-05-01-PHP-and-UTF8.md index 7c98c0368..96952e401 100644 --- a/_posts/05-05-01-PHP-and-UTF8.md +++ b/_posts/05-05-01-PHP-and-UTF8.md @@ -1,5 +1,6 @@ --- isChild: true +anchor: php_and_utf8 --- ## PHP and UTF-8 {#php_and_utf8_title} From eee3bb9e1ba4156cb58ebb2dcc0d1b70ef6eb37d Mon Sep 17 00:00:00 2001 From: Phil Sturgeon Date: Wed, 16 Apr 2014 10:37:13 +0300 Subject: [PATCH 253/843] Added a new section on Books. --- _posts/13-04-01-Books.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 _posts/13-04-01-Books.md diff --git a/_posts/13-04-01-Books.md b/_posts/13-04-01-Books.md new file mode 100644 index 000000000..c153ebfeb --- /dev/null +++ b/_posts/13-04-01-Books.md @@ -0,0 +1,25 @@ +--- +isChild: true +anchor: components +--- + +## Books {#books_title} + +There are a lot of books around for PHP but some are sadly now quite old and no +longer contain accurate information. There are even books published for "PHP 6" +which does not exist, any might not now ever exist because of those books. + +This section aims to be a living document for recommended books on PHP +development in general. Just like with the list of frameworks, there will no +doubt lots of interest in people adding their own books. Send a PR and see what +happens. + +### Free Books + +* [PHP The Rght Way](https://leanpub.com/phptherightway/) - This website is +available as a book completely for free + +### Paid Books + +* [Modernizing Legacy Applications In PHP](https://leanpub.com/mlaphp) - Get +your code under control in a series of small, specific steps From a6e2350f5d17cbf7e4e04ca35e31d2b30182fe55 Mon Sep 17 00:00:00 2001 From: Tom Houdmont Date: Wed, 16 Apr 2014 11:32:21 +0100 Subject: [PATCH 254/843] Spelling mistake in Books section corrected --- _posts/13-04-01-Books.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/13-04-01-Books.md b/_posts/13-04-01-Books.md index 0bd55586f..372dd863d 100644 --- a/_posts/13-04-01-Books.md +++ b/_posts/13-04-01-Books.md @@ -7,7 +7,7 @@ anchor: books There are a lot of books around for PHP but some are sadly now quite old and no longer contain accurate information. There are even books published for "PHP 6" -which does not exist, any might not now ever exist because of those books. +which does not exist, and might not now ever exist because of those books. This section aims to be a living document for recommended books on PHP development in general. If you would like your book to be added, send a PR and From 2374e862a396374adab77e7a61d69e923550e9a9 Mon Sep 17 00:00:00 2001 From: Ben Edmunds Date: Wed, 16 Apr 2014 10:41:25 -0700 Subject: [PATCH 255/843] Added some of the more popular and high quality modern PHP books Full disclosure - I included my book. --- _posts/13-04-01-Books.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/_posts/13-04-01-Books.md b/_posts/13-04-01-Books.md index 0bd55586f..5f6d10f9c 100644 --- a/_posts/13-04-01-Books.md +++ b/_posts/13-04-01-Books.md @@ -22,3 +22,8 @@ available as a book completely for free * [Modernizing Legacy Applications In PHP](https://leanpub.com/mlaphp) - Get your code under control in a series of small, specific steps +* [Building Secure PHP Apps](https://leanpub.com/buildingsecurephpapps) - Learn the security basics that a senior developer usually acquires over years of experience, all condensed down into one quick and easy handbook +* [The Grumpy Programmer's Guide To Building Testable PHP Applications](https://leanpub.com/grumpy-testing) - Learning to write testable doesn't have to suck +* [Build APIs You Won't Hate](https://leanpub.com/build-apis-you-wont-hate) - Everyone and their dog wants an API, so you should probably learn how to build them +* [Scaling PHP](https://leanpub.com/scalingphp) - Stop playing sysadmin and get back to coding +* [Signaling PHP](https://leanpub.com/signalingphp) - PCNLT signals are a great help when writing PHP scripts that run from the command line. From 8fca7e1f51cc37de5576eea51a7666d37c954a91 Mon Sep 17 00:00:00 2001 From: Josh Date: Wed, 23 Apr 2014 22:48:59 -0700 Subject: [PATCH 256/843] change a few words --- _posts/01-06-01-Vagrant.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_posts/01-06-01-Vagrant.md b/_posts/01-06-01-Vagrant.md index b1b3a01b3..274561d3f 100644 --- a/_posts/01-06-01-Vagrant.md +++ b/_posts/01-06-01-Vagrant.md @@ -10,14 +10,14 @@ popping up when you go live. It's also tricky to keep different development envi version for all libraries used when working with a team of developers. If you are developing on Windows and deploying to Linux (or anything non-Windows) or are developing in a team, you -should consider using a virtual machine. This sounds tricky, but using [Vagrant][vagrant] you can set up a simple +should consider using a virtual machine. This sounds tricky, but by using [Vagrant][vagrant] you can set up a simple virtual machine with only a few steps. These base boxes can then be set up manually, or you can use "provisioning" software such as [Puppet][puppet] or [Chef][chef] to do this for you. Provisioning the base box is a great way to ensure that multiple boxes are set up in an identical fashion and removes the need for you to maintain complicated "set up" command lists. You can also "destroy" your base box and recreate it without many manual steps, making it easy to create a "fresh" installation. -Vagrant creates shared folders used to share your code between your host and your virtual machine, meaning you can +Vagrant creates folders for sharing your code between your host and your virtual machine, which means that you can create and edit your files on your host machine and then run the code inside your virtual machine. ### A little help From d0292a994ac2e9e4a75bb2531c8234ef504ece38 Mon Sep 17 00:00:00 2001 From: Josh Date: Wed, 23 Apr 2014 23:04:22 -0700 Subject: [PATCH 257/843] new commit --- _posts/01-06-01-Vagrant.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/01-06-01-Vagrant.md b/_posts/01-06-01-Vagrant.md index 274561d3f..53fe3973f 100644 --- a/_posts/01-06-01-Vagrant.md +++ b/_posts/01-06-01-Vagrant.md @@ -24,7 +24,7 @@ create and edit your files on your host machine and then run the code inside you If you need a little help to start using Vagrant there are three services that might be useful: -- [Rove][rove]: service that allows you to pregenerate typical Vagrant builds, PHP among the options. The +- [Rove][rove]: service that allows you to pre-generate typical Vagrant builds, PHP among the options. The provisioning is made with Chef. - [Puphpet][puphpet]: simple GUI to set up virtual machines for PHP development. **Heavily focused in PHP**. Besides local VMs, can be used to deploy to cloud services as well. The provisioning is made with Puppet. From c6fc0272351cbd94b7aa8c7a69bcb930e9e2c93c Mon Sep 17 00:00:00 2001 From: Josh Lockhart Date: Fri, 2 May 2014 10:53:12 -0400 Subject: [PATCH 258/843] Add French translation link --- _includes/welcome.md | 1 + 1 file changed, 1 insertion(+) diff --git a/_includes/welcome.md b/_includes/welcome.md index ac614fd02..d524409ec 100644 --- a/_includes/welcome.md +++ b/_includes/welcome.md @@ -22,6 +22,7 @@ _PHP: The Right Way_ is (or soon will be) translated into many different languag * [English](http://www.phptherightway.com) * [Chinese (Simplified)](http://wulijun.github.com/php-the-right-way) +* [French](http://eilgin.github.io/php-the-right-way/) * [Japanese](http://ja.phptherightway.com) * [Korean](http://wafe.github.io/php-the-right-way/) * [Italian](http://it.phptherightway.com/) From 8065ebada1ea7a5d46213d47e1e18786395cebb5 Mon Sep 17 00:00:00 2001 From: Josh Lockhart Date: Fri, 2 May 2014 11:00:16 -0400 Subject: [PATCH 259/843] Add Thai translation link --- _includes/welcome.md | 1 + 1 file changed, 1 insertion(+) diff --git a/_includes/welcome.md b/_includes/welcome.md index d524409ec..a58a201a2 100644 --- a/_includes/welcome.md +++ b/_includes/welcome.md @@ -33,6 +33,7 @@ _PHP: The Right Way_ is (or soon will be) translated into many different languag * [Ukrainian](http://iflista.github.com/php-the-right-way/) * [Bulgarian](http://bg.phptherightway.com/) * [German](http://rwetzlmayr.github.io/php-the-right-way/) +* [Thai](https://apzentral.github.io/php-the-right-way/) * [Turkish](http://hkulekci.github.io/php-the-right-way/) * [Slovenian](http://sl.phptherightway.com) From 26828b1e13785a8cb2320990e6ed18aa01a2d10e Mon Sep 17 00:00:00 2001 From: Josh Lockhart Date: Fri, 2 May 2014 11:07:35 -0400 Subject: [PATCH 260/843] Add Indonesian translation link --- _includes/welcome.md | 1 + 1 file changed, 1 insertion(+) diff --git a/_includes/welcome.md b/_includes/welcome.md index a58a201a2..fc2a72ddd 100644 --- a/_includes/welcome.md +++ b/_includes/welcome.md @@ -25,6 +25,7 @@ _PHP: The Right Way_ is (or soon will be) translated into many different languag * [French](http://eilgin.github.io/php-the-right-way/) * [Japanese](http://ja.phptherightway.com) * [Korean](http://wafe.github.io/php-the-right-way/) +* [Indonesian](http://id.phptherightway.com/) * [Italian](http://it.phptherightway.com/) * [Polish](http://pl.phptherightway.com/) * [Portuguese](http://br.phptherightway.com/) From a1ba588952316543691c1fff3e0a4b8c3e3c6891 Mon Sep 17 00:00:00 2001 From: Josh Lockhart Date: Fri, 2 May 2014 11:11:42 -0400 Subject: [PATCH 261/843] Add Romanian translation link --- _includes/welcome.md | 1 + 1 file changed, 1 insertion(+) diff --git a/_includes/welcome.md b/_includes/welcome.md index fc2a72ddd..dc71bea7d 100644 --- a/_includes/welcome.md +++ b/_includes/welcome.md @@ -29,6 +29,7 @@ _PHP: The Right Way_ is (or soon will be) translated into many different languag * [Italian](http://it.phptherightway.com/) * [Polish](http://pl.phptherightway.com/) * [Portuguese](http://br.phptherightway.com/) +* [Romanian](https://bgui.github.io/php-the-right-way/) * [Russian](http://getjump.github.io/ru-php-the-right-way) * [Spanish](http://phpdevenezuela.github.io/php-the-right-way/) * [Ukrainian](http://iflista.github.com/php-the-right-way/) From c540989abda1fdffe95d5fd5fc41600be1223bac Mon Sep 17 00:00:00 2001 From: Phil Sturgeon Date: Mon, 12 May 2014 00:08:34 +0100 Subject: [PATCH 262/843] Updated to Kramdown. Splode? --- _config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_config.yml b/_config.yml index e13f69ef3..32336e4d2 100644 --- a/_config.yml +++ b/_config.yml @@ -3,7 +3,7 @@ baseurl: / url: http://localhost:4000 pygments: true -markdown: maruku +markdown: kramdown permalink: date maruku: use_tex: false From 1779f7c3708a98c928bcc75f329c1793839012b9 Mon Sep 17 00:00:00 2001 From: Phil Sturgeon Date: Tue, 13 May 2014 12:35:46 +0100 Subject: [PATCH 263/843] Added a little intro-SQL database stuff. --- _posts/07-01-01-Databases.md | 84 ++++++++++++---------- _posts/07-01-02-Interacting-via-Code.md | 95 +++++++++++++++++++++++++ _posts/07-01-03-Abstraction-Layers.md | 28 ++++++++ 3 files changed, 168 insertions(+), 39 deletions(-) create mode 100644 _posts/07-01-02-Interacting-via-Code.md create mode 100644 _posts/07-01-03-Abstraction-Layers.md diff --git a/_posts/07-01-01-Databases.md b/_posts/07-01-01-Databases.md index 26258dc1e..4c2399567 100644 --- a/_posts/07-01-01-Databases.md +++ b/_posts/07-01-01-Databases.md @@ -6,22 +6,46 @@ anchor: databases # Databases {#databases_title} Many times your PHP code will use a database to persist information. You have a few options to connect and interact -with your database. The recommended option _until PHP 5.1.0_ was to use native drivers such as [mysql][mysql], [mysqli][mysqli], [pgsql][pgsql], etc. +with your database. The recommended option **until PHP 5.1.0** was to use native drivers such as [mysqli], [pgsql], [mssql], etc. -Native drivers are great if you are only using ONE database in your application, but if, for example, you are using MySQL and a little bit of MSSQL, -or you need to connect to an Oracle database, then you will not be able to use the same drivers. You'll need to learn a brand new API for each -database — and that can get silly. +Native drivers are great if you are only using _one_ database in your application, but if, for example, you are using +MySQL and a little bit of MSSQL, or you need to connect to an Oracle database, then you will not be able to use the same +drivers. You'll need to learn a brand new API for each database — and that can get silly. -As an extra note on native drivers, the mysql extension for PHP is no longer in active development, and is officially deprecated as of PHP 5.5, meaning that it will be removed within the next few releases. If you are using `mysql_connect()` and `mysql_query()` in your applications then you will be faced with a rewrite at some point down the -line, so the best option is to replace mysql usage with mysqli or PDO in your applications within your own development schedules so you won't -be rushed later on. _If you are starting from scratch then absolutely do not use the mysql extension: use the [MySQLi extension][mysqli], or use PDO._ +## MySQL Extension + +The [mysql] extension for PHP is no longer in active development, and is [officially deprecated as of PHP 5.5.0], +meaning that it will be removed within the next few releases. If you are using any functions that start with `mysql_*` +such as `mysql_connect()` and `mysql_query()` in your applications then these will simply not be available in later +versions of PHP. This means you will be faced with a rewrite at some point down the line, so the best option is to +replace mysql usage with [mysqli] or [PDO] in your applications within your own development schedules so you won't be +rushed later on. + +**If you are starting from scratch then absolutely do not use the [mysql] extension: use the [MySQLi extension][mysqli], or use PDO.** * [PHP: Choosing an API for MySQL](http://php.net/manual/en/mysqlinfo.api.choosing.php) +* [PDO Tutorial for MySQL Developers](http://wiki.hashphp.org/PDO_Tutorial_for_MySQL_Developers) + +## PDO Extension -## PDO +PDO is a database connection abstraction library — built into PHP since 5.1.0 — that provides a common interface to talk with +many different databases. For example, you can use basically identical code to interface with MySQL or SQLite: + +{% highlight php %} +// PDO + MySQL +$pdo = new PDO('mysql:host=example.com;dbname=database', 'user', 'password'); +$statement = $pdo->query("SELECT some\_field FROM some\_table"); +$row = $statement->fetch(PDO::FETCH_ASSOC); +echo htmlentities($row['some_field']); + +// PDO + MySQL +$pdo = new PDO('sqlite:/path/db/foo.sqlite'); +$statement = $pdo->query("SELECT some\_field FROM some\_table"); +$row = $statement->fetch(PDO::FETCH_ASSOC); +echo htmlentities($row['some_field']); +{% endhighlight %} -PDO is a database connection abstraction library — built into PHP since 5.1.0 — that provides a common interface to talk with -many different databases. PDO will not translate your SQL queries or emulate missing features; it is purely for connecting to multiple types +PDO will not translate your SQL queries or emulate missing features; it is purely for connecting to multiple types of database with the same API. More importantly, `PDO` allows you to safely inject foreign input (e.g. IDs) into your SQL queries without worrying about database SQL injection attacks. @@ -32,18 +56,18 @@ way to do this: {% highlight php %} query("SELECT name FROM users WHERE id = " . $_GET['id']); // <-- NO! {% endhighlight %} This is terrible code. You are inserting a raw query parameter into a SQL query. This will get you hacked in a -heartbeat. Just imagine if a hacker passes in an inventive `id` parameter by calling a URL like +heartbeat, using a practice called [SQL Injecton]. Just imagine if a hacker passes in an inventive `id` parameter by calling a URL like `http://domain.com/?id=1%3BDELETE+FROM+users`. This will set the `$_GET['id']` variable to `1;DELETE FROM users` which will delete all of your users! Instead, you should sanitize the ID input using PDO bound parameters. {% highlight php %} prepare('SELECT name FROM users WHERE id = :id'); $stmt->bindParam(':id', $_GET['id'], PDO::PARAM_INT); // <-- Automatically sanitized by PDO $stmt->execute(); @@ -52,7 +76,7 @@ $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] +* [Learn about PDO] You should also be aware that database connections use up resources and it was not unheard-of to have resources exhausted if connections were not implicitly closed, however this was more common in other languages. Using PDO you @@ -60,33 +84,15 @@ can implicitly close the connection by destroying the object by ensuring all rem i.e. set to NULL. If you don't do this explicitly, PHP will automatically close the connection when your script ends - unless of course you are using persistent connections. -* [Learn about PDO connections][5] - -## Abstraction Layers - -Many frameworks provide their own abstraction layer which may or may not sit on top of PDO. These will often emulate features for -one database system that another is missing from another by wrapping your queries in PHP methods, giving you actual database abstraction. -This will of course add a little overhead, but if you are building a portable application that needs to work with MySQL, PostgreSQL and -SQLite then a little overhead will be worth it the sake of code cleanliness. - -Some abstraction layers have been built using the [PSR-0][psr0] or [PSR-4][psr4] namespace standards so can be installed in any application you like: - -* [Aura SQL][6] -* [Doctrine2 DBAL][2] -* [Propel][7] -* [ZF2 Db][4] -* [ZF1 Db][3] +* [Learn about PDO connections] -[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/index.html#zend-db -[5]: http://php.net/manual/en/pdo.connections.php -[6]: https://github.com/auraphp/Aura.Sql -[7]: http://propelorm.org/Propel/ +[Learn about PDO]: http://www.php.net/manual/en/book.pdo.php +[Learn about PDO connections]: http://php.net/manual/en/pdo.connections.php +[officially deprecated as of PHP 5.5.0]: http://php.net/manual/en/migration55.deprecated.php +[SQL Injection]: http://wiki.hashphp.org/Validation +[pdo]: http://php.net/pdo [mysql]: http://php.net/mysql [mysqli]: http://php.net/mysqli [pgsql]: http://php.net/pgsql -[psr0]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md -[psr4]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader.md +[mssql]: http://php.net/mssql diff --git a/_posts/07-01-02-Interacting-via-Code.md b/_posts/07-01-02-Interacting-via-Code.md new file mode 100644 index 000000000..f595dc2c3 --- /dev/null +++ b/_posts/07-01-02-Interacting-via-Code.md @@ -0,0 +1,95 @@ +--- +isChild: true +title: Interacting with Databases +anchor: databases_interacting +--- + +## Interacting with Databases + +When developers first start to learn PHP, they often end up mixing their database interaction up with their +presentation logic, using code that might look like this: + +{% highlight php %} +
    +query('SELECT * FROM table') as $row) { + echo "
  • ".$row['field1']." - ".$row['field1']."
  • "; +} +
+{% endhighlight %} + +This is bad practice for all sorts of reasons, mainly that its hard to debug, hard to test, hard to read and it is going to output a lot of fields if you don't put a limit on there. + +While there are many other solutions to doing this - depending on if you prefer [OOP](/#object-oriented-programming) or [functional programming](/#functional-programming) - there must be some element of seperation. + +Consider the most basic step: + +{% highlight php %} +query('SELECT * FROM table'); +} + +foreach (getAllFoos() as $row) { + echo "
  • ".$row['field1']." - ".$row['field1']."
  • "; // BAD!! +} +{% endhighlight %} + +That is a good start. Put those two items in two different files and you've got some clean seperation. + +Create a class to place that method in and you have a "Model". Create a simple `.php` file to put the presentation logic in and you have a "View", which is very nearly [MVC] - a common OOP architecture for most [frameworks](/#frameworks_title). + +**foo.php** + +{% highlight php %} +db = $db; + } + + public functon getAllFoos() { + return $this->db->query('SELECT * FROM table'); + } +} +{% endhighlight %} + +**views/foo-list.php** + +{% highlight php %} + + - + +{% endhighlight %} + +This is essentially the same as what most modern frameworks are doing, all be it a little more manual. You might +not need to do all of that every time, but mixing together too much presentation logic and database interaction can be a real problem if you ever want to [unit-test](/#unit-testing) your application. + +[PHPBridge] have a great resource called [Creating a Data Class] which covers a very similar topic, and is great +for developers just getting used to the concept of interacting with databases. + +[MVC]: http://code.tutsplus.com/tutorials/mvc-for-noobs--net-10488 +[PHPBridge]: http://phpbridge.org/ +[Creating a Data Class]: http://phpbridge.org/intro-to-php/creating_a_data_class \ No newline at end of file diff --git a/_posts/07-01-03-Abstraction-Layers.md b/_posts/07-01-03-Abstraction-Layers.md new file mode 100644 index 000000000..f2bcfc4e3 --- /dev/null +++ b/_posts/07-01-03-Abstraction-Layers.md @@ -0,0 +1,28 @@ +--- +isChild: true +title: Abstraction Layers +anchor: databases_abstraction_layers +--- + +## Abstraction Layers + +Many frameworks provide their own abstraction layer which may or may not sit on top of PDO. These will often emulate features for +one database system that is missing from another by wrapping your queries in PHP methods, giving you actual database abstraction instead of just the connection abstraction that PDO provides. +This will of course add a little overhead, but if you are building a portable application that needs to work with MySQL, PostgreSQL and +SQLite then a little overhead will be worth it the sake of code cleanliness. + +Some abstraction layers have been built using the [PSR-0][psr0] or [PSR-4][psr4] namespace standards so can be installed in any application you like: + +* [Aura SQL][6] +* [Doctrine2 DBAL][2] +* [Propel][7] +* [ZF2 Db][4] + +[1]: http://www.php.net/manual/en/book.pdo.php +[2]: http://www.doctrine-project.org/projects/dbal.html +[4]: http://packages.zendframework.com/docs/latest/manual/en/index.html#zend-db +[6]: https://github.com/auraphp/Aura.Sql +[7]: http://propelorm.org/Propel/ + +[psr0]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md +[psr4]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader.md From 188501a5fcd76f837e4bee0d2b76cab093695ff8 Mon Sep 17 00:00:00 2001 From: Phil Sturgeon Date: Fri, 16 May 2014 16:25:23 +0100 Subject: [PATCH 264/843] Added Securing PHP: Core Concepts --- _posts/13-04-01-Books.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/13-04-01-Books.md b/_posts/13-04-01-Books.md index 2de5f798e..5282009c3 100644 --- a/_posts/13-04-01-Books.md +++ b/_posts/13-04-01-Books.md @@ -24,6 +24,6 @@ available as a book completely for free your code under control in a series of small, specific steps * [Building Secure PHP Apps](https://leanpub.com/buildingsecurephpapps) - Learn the security basics that a senior developer usually acquires over years of experience, all condensed down into one quick and easy handbook * [The Grumpy Programmer's Guide To Building Testable PHP Applications](https://leanpub.com/grumpy-testing) - Learning to write testable doesn't have to suck -* [Build APIs You Won't Hate](https://leanpub.com/build-apis-you-wont-hate) - Everyone and their dog wants an API, so you should probably learn how to build them +* [Securing PHP: Core Concepts](https://leanpub.com/securingphp-coreconcepts) - A guide to some of the most common security terms and provides some examples of them in every day PHP * [Scaling PHP](https://leanpub.com/scalingphp) - Stop playing sysadmin and get back to coding * [Signaling PHP](https://leanpub.com/signalingphp) - PCNLT signals are a great help when writing PHP scripts that run from the command line. From 5fe7d7fdffb0303182d4ed367b32c5a12029e0cb Mon Sep 17 00:00:00 2001 From: Mazen Abdulaziz Date: Fri, 30 May 2014 17:53:04 +0300 Subject: [PATCH 265/843] Small fix in second example Second example uses PDO to connect to SQLite, comment says it's connecting to MySQL --- _posts/07-01-01-Databases.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/07-01-01-Databases.md b/_posts/07-01-01-Databases.md index 4c2399567..7d16f2aa7 100644 --- a/_posts/07-01-01-Databases.md +++ b/_posts/07-01-01-Databases.md @@ -38,7 +38,7 @@ $statement = $pdo->query("SELECT some\_field FROM some\_table"); $row = $statement->fetch(PDO::FETCH_ASSOC); echo htmlentities($row['some_field']); -// PDO + MySQL +// PDO + SQLite $pdo = new PDO('sqlite:/path/db/foo.sqlite'); $statement = $pdo->query("SELECT some\_field FROM some\_table"); $row = $statement->fetch(PDO::FETCH_ASSOC); From 3c647ba5593693b242b70904c0f2d0a18c8df3b2 Mon Sep 17 00:00:00 2001 From: Neil Masters Date: Mon, 2 Jun 2014 23:32:50 +0100 Subject: [PATCH 266/843] Update The-Basics.md Tidying up the wordyness, removing overused and thus redundant variable assignments and improving explanations in replacement for quick & short comments. --- pages/The-Basics.md | 37 ++++++++----------------------------- 1 file changed, 8 insertions(+), 29 deletions(-) diff --git a/pages/The-Basics.md b/pages/The-Basics.md index e3d7708d1..8a141a79d 100644 --- a/pages/The-Basics.md +++ b/pages/The-Basics.md @@ -285,11 +285,12 @@ stacked/nested, it is advised to use one per line for readability. Date: Mon, 2 Jun 2014 19:07:54 -0400 Subject: [PATCH 267/843] Adds a comma to the description of recursion Parenthetical elements should be set off using a comma. --- _posts/03-02-01-Programming-Paradigms.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/03-02-01-Programming-Paradigms.md b/_posts/03-02-01-Programming-Paradigms.md index bc7c486b3..945a3f7a4 100644 --- a/_posts/03-02-01-Programming-Paradigms.md +++ b/_posts/03-02-01-Programming-Paradigms.md @@ -23,7 +23,7 @@ PHP supports first-class function, meaning that a function can be assigned to a functions can be referenced by a variable and invoked dynamically. Functions can be passed as arguments to other functions (feature called Higher-order functions) and function can return other functions. -Recursion, a feature that allows a function to call itself is supported by the language, but most of the PHP code focus +Recursion, a feature that allows a function to call itself, is supported by the language, but most of the PHP code focus on iteration. New anonymous functions (with support for closures) are present since PHP 5.3 (2009). From 3172368ceeace7ef99a2eaf283e14c988abc5051 Mon Sep 17 00:00:00 2001 From: Joeri Poesen Date: Sun, 8 Jun 2014 23:29:41 +0200 Subject: [PATCH 268/843] Minor grammar/typo fix. --- _posts/08-02-01-Errors.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/08-02-01-Errors.md b/_posts/08-02-01-Errors.md index be359e157..ea2f7717a 100644 --- a/_posts/08-02-01-Errors.md +++ b/_posts/08-02-01-Errors.md @@ -72,7 +72,7 @@ This will output `$foo['bar']` if it exists, but will simply return a null and p This might seem like a good idea, but there are a few undesirable tradeoffs. PHP handles expressions using an `@` in a less performant way than expressions without an `@`. Premature optimization may be the root of all programming arguments, but if performance is particularly important for your application/library it's important to understand the error control operator's performance implications. -Secondly, the error control operator **completely** swallows the error. The error is not displayed, and the error is not send to the error log. Also, stock/production PHP systems have no way to turn off the error control operator. While you may be correct that the error you're seeing is harmless, a different, less harmless error will be just as silent. +Secondly, the error control operator **completely** swallows the error. The error is not displayed, and the error is not sent to the error log. Also, stock/production PHP systems have no way to turn off the error control operator. While you may be correct that the error you're seeing is harmless, a different, less harmless error will be just as silent. If there's a way to avoid the error suppression operator, you should consider it. For example, our code above could be rewritten like this From 351ff4d60cd849bade2b96ce249267cdd470cd44 Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Tue, 10 Jun 2014 02:08:09 +0200 Subject: [PATCH 269/843] kramdown syntax class name fix --- index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.html b/index.html index 54bd0cd6f..5fdb78f0f 100644 --- a/index.html +++ b/index.html @@ -6,7 +6,7 @@ {% capture welcome_content %}{% include welcome.md %}{% endcapture %} {{ welcome_content|markdownify }} -{% capture backtotop %}[Back to Top](#top){.top}{% endcapture %} +{% capture backtotop %}[Back to Top](#top){:.top}{% endcapture %} {% for post in site.posts reversed %} {% if post.isChild != true and loop.first != true %} {{ backtotop|markdownify }} From a7cd47121507a7abb91232ae3046cb1268da0204 Mon Sep 17 00:00:00 2001 From: Phil Sturgeon Date: Tue, 10 Jun 2014 14:41:31 +0100 Subject: [PATCH 270/843] Fixed up a few bits and bobs including syntax error. --- pages/The-Basics.md | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/pages/The-Basics.md b/pages/The-Basics.md index 8a141a79d..bfa9e5b0a 100644 --- a/pages/The-Basics.md +++ b/pages/The-Basics.md @@ -26,7 +26,7 @@ if (strpos('testing', 'test')) { // 'test' is found at position 0, which is i // code... } -vs. +// vs if (strpos('testing', 'test') !== false) { // true, as strict comparison was made (0 !== false) // code... @@ -55,7 +55,7 @@ function test($a) } } -vs. +// vs function test($a) { @@ -132,7 +132,7 @@ function array() ### Concatenation - If your line extends beyond the recommended line length (120 characters), consider concatenating your line -- For readability it's best to use concatenation operators over concatenating assignment operators +- For readability it is best to use concatenation operators over concatenating assignment operators - While within the original scope of the variable, indent when concatenation uses a new line @@ -142,7 +142,7 @@ $a = 'Multi-line example'; // concatenating assignment operator (.=) $a .= "\n"; $a .= 'of what not to do'; -vs. +// vs $a = 'Multi-line example' // concatenation operator (.) . "\n" // indenting new lines @@ -159,7 +159,7 @@ differences between the string types and their benefits/uses. #### Single quotes Single quotes are the simplest way to define a string and are often the quickest. Their speed stems from PHP not -parsing the string (doesn't parse for variables). They're best suited for: +parsing the string (does not parse for variables). They are best suited for: - Strings that do not need to be parsed - Writing of a variable into plain text @@ -179,7 +179,7 @@ echo 'This is my string, look at how pretty it is.'; // no need to parse a si #### Double quotes -Double quotes are the Swiss army knife of strings, but are slower due to the string being parsed. They're best +Double quotes are the Swiss army knife of strings, but are slower due to the string being parsed. They are best suited for: - Escaped strings @@ -192,13 +192,13 @@ echo 'phptherightway is ' . $adjective . '.' // a single quotes example that . "\n" // variables and escaped string . 'I love learning' . $code . '!'; -vs. +// vs echo "phptherightway is $adjective.\n I love learning $code!" // Instead of multiple concatenating, double quotes // enables us to use a parsable string {% endhighlight %} -While using double quotes that contain variables, it's often the case that the variable will be touching another +While using double quotes that contain variables, it is often the case that the variable will be touching another character. This will result in PHP not parsing the variable due to the variable being camouflaged. To fix this problem, wrap the variable within a pair of curly brackets. @@ -207,7 +207,7 @@ wrap the variable within a pair of curly brackets. $juice = 'plum'; echo "I drank some juice made of $juices"; // $juice cannot be parsed -vs. +// vs $juice = 'plum'; echo "I drank some juice made of {$juice}s"; // $juice will be parsed @@ -224,7 +224,7 @@ echo "I drank some juice made of {$juice[1]}s"; // $juice[1] will be parsed #### Nowdoc syntax -Nowdoc syntax was introduced in 5.3 and internally behaves the same way as single quotes except it's suited toward the +Nowdoc syntax was introduced in 5.3 and internally behaves the same way as single quotes except it is suited toward the use of multi-line strings without the need for concatenating. {% highlight php %} @@ -250,7 +250,7 @@ EOD; // closing 'EOD' must be on it's own line, and to th #### Heredoc syntax -Heredoc syntax internally behaves the same way as double quotes except it's suited toward the use of multi-line +Heredoc syntax internally behaves the same way as double quotes except it is suited toward the use of multi-line strings without the need for concatenating. {% highlight php %} @@ -301,7 +301,7 @@ To 'return' a value with ternary operators use the correct syntax. $a = 5; echo ($a == 5) ? return true : return false; // this example will output an error -vs. +// vs $a = 5; return ($a == 5) ? 'yay' : 'nope'; // this example will return 'yay' @@ -315,17 +315,15 @@ It should be noted that you do not need to use a ternary operator for returning $a = 3; return ($a == 3) ? true : false; // Will return true or false if $a == 3 -vs +// vs $a = 3; return $a == 3; // Will return true or false if $a == 3 -{% endhighlight php %} +{% endhighlight %} This can also be said for all operations(===, !==, !=, == etc). -{% endhighlight %} - #### Utilising brackets with ternary operators for form and function When utilising a ternary operator, brackets can play their part to improve code readability and also to include unions within blocks of statements. An example of when there is no requirement to use bracketing is: @@ -335,7 +333,7 @@ When utilising a ternary operator, brackets can play their part to improve code $a = 3; return ($a == 3) ? "yay" : "nope"; // return yay or nope if $a == 3 -vs +// vs Date: Fri, 20 Jun 2014 21:29:47 +0100 Subject: [PATCH 271/843] Add a PHPDoc post --- _posts/15-01-01-PHPDoc.md | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 _posts/15-01-01-PHPDoc.md diff --git a/_posts/15-01-01-PHPDoc.md b/_posts/15-01-01-PHPDoc.md new file mode 100644 index 000000000..6b10b60b1 --- /dev/null +++ b/_posts/15-01-01-PHPDoc.md @@ -0,0 +1,36 @@ +--- +anchor: phpdoc +--- + +# PHPDoc {#phpdoc} + +PHPDoc is an informal standard for commenting PHP code. There are a *lot* of different [tags](http://manual.phpdoc.org/HTMLSmartyConverter/PHP/phpDocumentor/tutorial_tags.pkg.html) available. The full list of tags and examples can be found at the [PHPDoc manual](http://manual.phpdoc.org/HTMLSmartyConverter/PHP/phpDocumentor/tutorial_tags.pkg.html). + +Below is an example of how you might comment a class and a method; + +{% highlight php %} + + * @link http://manual.phpdoc.org/HTMLSmartyConverter/PHP/phpDocumentor/tutorial_tags.link.pkg.html + * @package demo + */ +class DateTimeHelper +{ + /** + * @param mixed $anything + * + * @return \DateTime + * @throws \InvalidArgumentException + */ + public static function dateTimeFromAnything($anything) { + $type = gettype($anything); + + switch ($type) { + case "object": + if ($anything instanceof \DateTime) { + return $anything; + } + break; +... +{% endhighlight %} From c3c45a89698e817c062e9cbbe1ca2a42401753d9 Mon Sep 17 00:00:00 2001 From: Gareth Evans Date: Mon, 23 Jun 2014 09:26:08 +0100 Subject: [PATCH 272/843] Updated the URLs to new documentation after some feedback --- _posts/15-01-01-PHPDoc.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_posts/15-01-01-PHPDoc.md b/_posts/15-01-01-PHPDoc.md index 6b10b60b1..1645f078d 100644 --- a/_posts/15-01-01-PHPDoc.md +++ b/_posts/15-01-01-PHPDoc.md @@ -4,7 +4,7 @@ anchor: phpdoc # PHPDoc {#phpdoc} -PHPDoc is an informal standard for commenting PHP code. There are a *lot* of different [tags](http://manual.phpdoc.org/HTMLSmartyConverter/PHP/phpDocumentor/tutorial_tags.pkg.html) available. The full list of tags and examples can be found at the [PHPDoc manual](http://manual.phpdoc.org/HTMLSmartyConverter/PHP/phpDocumentor/tutorial_tags.pkg.html). +PHPDoc is an informal standard for commenting PHP code. There are a *lot* of different [tags](http://www.phpdoc.org/docs/latest/references/phpdoc/tags/index.html) available. The full list of tags and examples can be found at the [PHPDoc manual](http://www.phpdoc.org/docs/latest/index.html). Below is an example of how you might comment a class and a method; @@ -12,7 +12,7 @@ Below is an example of how you might comment a class and a method; - * @link http://manual.phpdoc.org/HTMLSmartyConverter/PHP/phpDocumentor/tutorial_tags.link.pkg.html + * @link http://www.phpdoc.org/docs/latest/index.html * @package demo */ class DateTimeHelper From de8cef6c7d0bb68591018f4d07fcddcff322a14a Mon Sep 17 00:00:00 2001 From: christian studer Date: Mon, 30 Jun 2014 13:37:13 +0200 Subject: [PATCH 273/843] Typo and missing link for SQL injections --- _posts/07-01-01-Databases.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/07-01-01-Databases.md b/_posts/07-01-01-Databases.md index 7d16f2aa7..a314cfa85 100644 --- a/_posts/07-01-01-Databases.md +++ b/_posts/07-01-01-Databases.md @@ -61,7 +61,7 @@ $pdo->query("SELECT name FROM users WHERE id = " . $_GET['id']); // <-- NO! {% endhighlight %} This is terrible code. You are inserting a raw query parameter into a SQL query. This will get you hacked in a -heartbeat, using a practice called [SQL Injecton]. Just imagine if a hacker passes in an inventive `id` parameter by calling a URL like +heartbeat, using a practice called [SQL Injection](http://wiki.hashphp.org/Validation). Just imagine if a hacker passes in an inventive `id` parameter by calling a URL like `http://domain.com/?id=1%3BDELETE+FROM+users`. This will set the `$_GET['id']` variable to `1;DELETE FROM users` which will delete all of your users! Instead, you should sanitize the ID input using PDO bound parameters. From 1dc778fe07a032727bf76043eb7ae23953d10181 Mon Sep 17 00:00:00 2001 From: Gareth Evans Date: Tue, 1 Jul 2014 13:32:54 +0100 Subject: [PATCH 274/843] Expand documentation and explain (and it's exclusion) --- _posts/15-01-01-PHPDoc.md | 47 ++++++++++++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 10 deletions(-) diff --git a/_posts/15-01-01-PHPDoc.md b/_posts/15-01-01-PHPDoc.md index 1645f078d..f0fec15d9 100644 --- a/_posts/15-01-01-PHPDoc.md +++ b/_posts/15-01-01-PHPDoc.md @@ -6,31 +6,58 @@ anchor: phpdoc PHPDoc is an informal standard for commenting PHP code. There are a *lot* of different [tags](http://www.phpdoc.org/docs/latest/references/phpdoc/tags/index.html) available. The full list of tags and examples can be found at the [PHPDoc manual](http://www.phpdoc.org/docs/latest/index.html). -Below is an example of how you might comment a class and a method; +Below is an example of how you might document a class with a few methods; {% highlight php %} * @link http://www.phpdoc.org/docs/latest/index.html - * @package demo + * @package helper */ class DateTimeHelper { /** - * @param mixed $anything + * @param mixed $anything Anything that we can convert to a \DateTime object * * @return \DateTime * @throws \InvalidArgumentException */ - public static function dateTimeFromAnything($anything) { + public function dateTimeFromAnything($anything) + { $type = gettype($anything); switch ($type) { - case "object": - if ($anything instanceof \DateTime) { - return $anything; - } - break; -... + // Some code that tries to return a \DateTime object + } + + throw new \InvalidArgumentException( + "Failed Converting param of type '{$type}' to DateTime object" + ); + } + + /** + * @param mixed $date Anything that we can convert to a \DateTime object + * + * @return void + */ + public function printISO8601Date($date) + { + echo $this->dateTimeFromAnything($date)->format('c'); + } + + /** + * @param mixed $date Anything that we can convert to a \DateTime object + */ + public function printRFC2822Date($date) + { + echo $this->dateTimeFromAnything($date)->format('r'); + } +} {% endhighlight %} + +The documentation for the class as a whole firstly has the [@author](http://www.phpdoc.org/docs/latest/references/phpdoc/tags/author.html) tag, this tag is used to document the author of the code and can be repeated for documenting several authors. Secondly is the [@link](http://www.phpdoc.org/docs/latest/references/phpdoc/tags/link.html) tag, used to link to a website indicating a relationship between the website and the code. Thirdly it has the [@pacakge](http://www.phpdoc.org/docs/latest/references/phpdoc/tags/package.html) tag, used to categorize the code. + +Inside the class, the first method has an [@param](http://www.phpdoc.org/docs/latest/references/phpdoc/tags/param.html) tag documenting the type, name and description of the parameter being passed to the method. Additionally it has the [@return](http://www.phpdoc.org/docs/latest/references/phpdoc/tags/return.html) and [@throws](http://www.phpdoc.org/docs/latest/references/phpdoc/tags/throws.html) tags for documenting the return type, and any exceptions that could be throw respectively. + +The second and third methods are very similar and have a single [@param](http://www.phpdoc.org/docs/latest/references/phpdoc/tags/param.html) tag as did the first method. The import difference between the second and third method is doc block is the inclusion/exclusion of the [@return](http://www.phpdoc.org/docs/latest/references/phpdoc/tags/return.html) tag. `@return void` explicitly informs us that there is no return, historically omitting the `@return void` statement also results in the same (no return) action. \ No newline at end of file From bfc8c51123350806538d127cb98e440a11ebdfe9 Mon Sep 17 00:00:00 2001 From: Gareth Evans Date: Wed, 2 Jul 2014 13:21:44 +0100 Subject: [PATCH 275/843] Maximum number of contributors in a single request The Github api limits results to 30 per page by default. The maximum for a single result of contributors is 100. --- scripts/setup.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/setup.js b/scripts/setup.js index bab825153..819d71ff2 100644 --- a/scripts/setup.js +++ b/scripts/setup.js @@ -10,7 +10,7 @@ dataType: 'jsonp', timeout: 3000, type: 'GET', - url: 'https://api.github.com/repos/codeguy/php-the-right-way/contributors' + url: 'https://api.github.com/repos/codeguy/php-the-right-way/contributors?per_page=100' }).done(function (data) { if ( data.data && data.data.length ) { var $ul = $('
      '), dataLength = data.data.length; From 6f8793ebee35853e2391e5b634ead22917644bd0 Mon Sep 17 00:00:00 2001 From: Yannick Lyn Fatt Date: Wed, 9 Jul 2014 13:37:15 -0500 Subject: [PATCH 276/843] Fixed typo in PHPDoc.md Closes #405 --- _posts/15-01-01-PHPDoc.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_posts/15-01-01-PHPDoc.md b/_posts/15-01-01-PHPDoc.md index f0fec15d9..21f4dfaf6 100644 --- a/_posts/15-01-01-PHPDoc.md +++ b/_posts/15-01-01-PHPDoc.md @@ -56,8 +56,8 @@ class DateTimeHelper } {% endhighlight %} -The documentation for the class as a whole firstly has the [@author](http://www.phpdoc.org/docs/latest/references/phpdoc/tags/author.html) tag, this tag is used to document the author of the code and can be repeated for documenting several authors. Secondly is the [@link](http://www.phpdoc.org/docs/latest/references/phpdoc/tags/link.html) tag, used to link to a website indicating a relationship between the website and the code. Thirdly it has the [@pacakge](http://www.phpdoc.org/docs/latest/references/phpdoc/tags/package.html) tag, used to categorize the code. +The documentation for the class as a whole firstly has the [@author](http://www.phpdoc.org/docs/latest/references/phpdoc/tags/author.html) tag, this tag is used to document the author of the code and can be repeated for documenting several authors. Secondly is the [@link](http://www.phpdoc.org/docs/latest/references/phpdoc/tags/link.html) tag, used to link to a website indicating a relationship between the website and the code. Thirdly it has the [@package](http://www.phpdoc.org/docs/latest/references/phpdoc/tags/package.html) tag, used to categorize the code. Inside the class, the first method has an [@param](http://www.phpdoc.org/docs/latest/references/phpdoc/tags/param.html) tag documenting the type, name and description of the parameter being passed to the method. Additionally it has the [@return](http://www.phpdoc.org/docs/latest/references/phpdoc/tags/return.html) and [@throws](http://www.phpdoc.org/docs/latest/references/phpdoc/tags/throws.html) tags for documenting the return type, and any exceptions that could be throw respectively. -The second and third methods are very similar and have a single [@param](http://www.phpdoc.org/docs/latest/references/phpdoc/tags/param.html) tag as did the first method. The import difference between the second and third method is doc block is the inclusion/exclusion of the [@return](http://www.phpdoc.org/docs/latest/references/phpdoc/tags/return.html) tag. `@return void` explicitly informs us that there is no return, historically omitting the `@return void` statement also results in the same (no return) action. \ No newline at end of file +The second and third methods are very similar and have a single [@param](http://www.phpdoc.org/docs/latest/references/phpdoc/tags/param.html) tag as did the first method. The import difference between the second and third method is doc block is the inclusion/exclusion of the [@return](http://www.phpdoc.org/docs/latest/references/phpdoc/tags/return.html) tag. `@return void` explicitly informs us that there is no return, historically omitting the `@return void` statement also results in the same (no return) action. From 00f8879add222a0bfc0a1edc05af899fb7595068 Mon Sep 17 00:00:00 2001 From: Tyler Pearson Date: Thu, 10 Jul 2014 23:17:50 -0700 Subject: [PATCH 277/843] Fixed typo --- _posts/07-01-02-Interacting-via-Code.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_posts/07-01-02-Interacting-via-Code.md b/_posts/07-01-02-Interacting-via-Code.md index f595dc2c3..8b2807924 100644 --- a/_posts/07-01-02-Interacting-via-Code.md +++ b/_posts/07-01-02-Interacting-via-Code.md @@ -20,7 +20,7 @@ foreach ($db->query('SELECT * FROM table') as $row) { This is bad practice for all sorts of reasons, mainly that its hard to debug, hard to test, hard to read and it is going to output a lot of fields if you don't put a limit on there. -While there are many other solutions to doing this - depending on if you prefer [OOP](/#object-oriented-programming) or [functional programming](/#functional-programming) - there must be some element of seperation. +While there are many other solutions to doing this - depending on if you prefer [OOP](/#object-oriented-programming) or [functional programming](/#functional-programming) - there must be some element of separation. Consider the most basic step: @@ -35,7 +35,7 @@ foreach (getAllFoos() as $row) { } {% endhighlight %} -That is a good start. Put those two items in two different files and you've got some clean seperation. +That is a good start. Put those two items in two different files and you've got some clean separation. Create a class to place that method in and you have a "Model". Create a simple `.php` file to put the presentation logic in and you have a "View", which is very nearly [MVC] - a common OOP architecture for most [frameworks](/#frameworks_title). From 86f94fbfc2c7e4507c53d1be703127163f94a4aa Mon Sep 17 00:00:00 2001 From: Kunio Murasawa Date: Tue, 15 Jul 2014 00:14:45 +0900 Subject: [PATCH 278/843] fix a typo --- _posts/07-01-02-Interacting-via-Code.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_posts/07-01-02-Interacting-via-Code.md b/_posts/07-01-02-Interacting-via-Code.md index 8b2807924..9414247d6 100644 --- a/_posts/07-01-02-Interacting-via-Code.md +++ b/_posts/07-01-02-Interacting-via-Code.md @@ -26,7 +26,7 @@ Consider the most basic step: {% highlight php %} query('SELECT * FROM table'); } @@ -70,7 +70,7 @@ class Foo() $this->db = $db; } - public functon getAllFoos() { + public function getAllFoos() { return $this->db->query('SELECT * FROM table'); } } From ac548011c06a69a1a1e343e24d56154aada0d845 Mon Sep 17 00:00:00 2001 From: Phil Sturgeon Date: Tue, 15 Jul 2014 16:55:55 +0100 Subject: [PATCH 279/843] Add note about patchwork utf8 --- _posts/05-05-01-PHP-and-UTF8.md | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/_posts/05-05-01-PHP-and-UTF8.md b/_posts/05-05-01-PHP-and-UTF8.md index 96952e401..c0a979ccc 100644 --- a/_posts/05-05-01-PHP-and-UTF8.md +++ b/_posts/05-05-01-PHP-and-UTF8.md @@ -18,9 +18,8 @@ for a brief, practical summary. The basic string operations, like concatenating two strings and assigning strings to variables, don't need anything special for UTF-8. However most string functions, like `strpos()` and `strlen()`, do need special consideration. These -functions often have an `mb_*` counterpart: for example, `mb_strpos()` and `mb_strlen()`. Together, these counterpart -functions are called the Multibyte String Functions. The multibyte string functions are specifically designed to -operate on Unicode strings. +functions often have an `mb_*` counterpart: for example, `mb_strpos()` and `mb_strlen()`. These `mb_*` strings are made +available to you via the [Multibyte String Extension], and are specifically designed to operate on Unicode strings. You must use the `mb_*` functions whenever you operate on a Unicode string. For example, if you use `substr()` on a UTF-8 string, there's a good chance the result will include some garbled half-characters. The correct function to use @@ -32,17 +31,21 @@ string has a chance of being garbled during further processing. Not all string functions have an `mb_*` counterpart. If there isn't one for what you want to do, then you might be out of luck. -Additionally, you should use the `mb_internal_encoding()` function at the top of every PHP script you write (or at the +You should use the `mb_internal_encoding()` function at the top of every PHP script you write (or at the top of your global include script), and the `mb_http_output()` function right after it if your script is outputting to a browser. Explicitly defining the encoding of your strings in every script will save you a lot of headaches down the road. -Finally, many PHP functions that operate on strings have an optional parameter letting you specify the character +Additionally, many PHP functions that operate on strings have an optional parameter letting you specify the character encoding. You should always explicitly indicate UTF-8 when given the option. For example, `htmlentities()` has an -option for character encoding, and you should always specify UTF-8 if dealing with such strings. +option for character encoding, and you should always specify UTF-8 if dealing with such strings. Note that as of PHP 5.4.0, UTF-8 is the default encoding for `htmlentities()` and `htmlspecialchars()`. -Note that as of PHP 5.4.0, UTF-8 is the default encoding for `htmlentities()` and `htmlspecialchars()`. +Finally, If you are building an distributed application and cannot be certain that the `mbstring` extension will be +enabled, then consider using the [patchwork/utf8] Composer package. This +will use `mbstring` if it is available, and fall back to non UTF-8 functions if not. +[Multibyte String Extension]: http://php.net/manual/en/book.mbstring.php +[patchwork/utf8]: https://packagist.org/packages/patchwork/utf8 ### UTF-8 at the Database level From 3d7f2957d9ffc4125dc396dfe42d79ac2e783446 Mon Sep 17 00:00:00 2001 From: Phil Sturgeon Date: Tue, 15 Jul 2014 16:57:26 +0100 Subject: [PATCH 280/843] Working with UTF-8 --- _posts/05-05-01-PHP-and-UTF8.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/_posts/05-05-01-PHP-and-UTF8.md b/_posts/05-05-01-PHP-and-UTF8.md index c0a979ccc..801bfe2d1 100644 --- a/_posts/05-05-01-PHP-and-UTF8.md +++ b/_posts/05-05-01-PHP-and-UTF8.md @@ -1,9 +1,10 @@ --- +title: Working with UTF-8 isChild: true anchor: php_and_utf8 --- -## PHP and UTF-8 {#php_and_utf8_title} +## Working with UTF-8 {#php_and_utf8_title} _This section was originally written by [Alex Cabal](https://alexcabal.com/) over at [PHP Best Practices](https://phpbestpractices.org/#utf-8) and has now been shared here_. From 9a41f407f081a0cb31b1d484bda00b7b67fcb994 Mon Sep 17 00:00:00 2001 From: Phil Sturgeon Date: Tue, 15 Jul 2014 17:05:07 +0100 Subject: [PATCH 281/843] Charset in content-type --- _posts/05-05-01-PHP-and-UTF8.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/_posts/05-05-01-PHP-and-UTF8.md b/_posts/05-05-01-PHP-and-UTF8.md index 801bfe2d1..a4adcc7cf 100644 --- a/_posts/05-05-01-PHP-and-UTF8.md +++ b/_posts/05-05-01-PHP-and-UTF8.md @@ -7,7 +7,7 @@ anchor: php_and_utf8 ## Working with UTF-8 {#php_and_utf8_title} _This section was originally written by [Alex Cabal](https://alexcabal.com/) over at -[PHP Best Practices](https://phpbestpractices.org/#utf-8) and has now been shared here_. +[PHP Best Practices](https://phpbestpractices.org/#utf-8) and has been used as the basis for our own UTF-8 advice_. ### There's no one-liner. Be careful, detailed, and consistent. @@ -62,8 +62,9 @@ Further Reading for why. ### UTF-8 at the browser level -Use the `mb_http_output()` function to ensure that your PHP script outputs UTF-8 strings to your browser. In your HTML, -include the [charset `` tag](http://htmlpurifier.org/docs/enduser-utf8.html) in your page's `` tag. +Use the `mb_http_output()` function to ensure that your PHP script outputs UTF-8 strings to your browser. + +The browser will then need to be told by the HTTP response that this page should be considered as UTF-8. The historic approach to doing that was to include the [charset `` tag](http://htmlpurifier.org/docs/enduser-utf8.html) in your page's `` tag. This approach is perfectly valid, but setting the charset in the `Content-Type` header is actually [much faster](https://developers.google.com/speed/docs/best-practices/rendering#SpecifyCharsetEarly). {% highlight php %} execute(); // Store the result into an object that we'll output later in our HTML $result = $handle->fetchAll(\PDO::FETCH_OBJ); + +header('Content-Type: text/html; charset=utf-8'); ?> - UTF-8 test page From 40101b60bad28d686bd62175450b2903823fb0ce Mon Sep 17 00:00:00 2001 From: Kunio Murasawa Date: Wed, 16 Jul 2014 09:39:07 +0900 Subject: [PATCH 282/843] fix the indentation --- _posts/07-01-02-Interacting-via-Code.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/_posts/07-01-02-Interacting-via-Code.md b/_posts/07-01-02-Interacting-via-Code.md index 9414247d6..9f38be9af 100644 --- a/_posts/07-01-02-Interacting-via-Code.md +++ b/_posts/07-01-02-Interacting-via-Code.md @@ -27,7 +27,7 @@ Consider the most basic step: {% highlight php %} query('SELECT * FROM table'); + return $db->query('SELECT * FROM table'); } foreach (getAllFoos() as $row) { @@ -63,16 +63,16 @@ include 'views/foo-list.php'; db = $db; - } + public function __construct(PDO $db) + { + $this->db = $db; + } - public function getAllFoos() { - return $this->db->query('SELECT * FROM table'); - } + public function getAllFoos() { + return $this->db->query('SELECT * FROM table'); + } } {% endhighlight %} From b761690292e1fb72dbec95941ada58ff8f6b83e3 Mon Sep 17 00:00:00 2001 From: Jonathan Reinink Date: Fri, 25 Jul 2014 14:53:02 -0400 Subject: [PATCH 283/843] Add new Templating section. --- ...de.md => 07-02-01-Interacting-via-Code.md} | 2 +- ...yers.md => 07-03-01-Abstraction-Layers.md} | 2 +- _posts/08-01-01-Templating.md | 12 ++++++++ _posts/08-02-01-Benefits.md | 21 ++++++++++++++ _posts/08-03-01-Plain-PHP-Templates.md | 28 +++++++++++++++++++ _posts/08-04-01-Compiled-Templates.md | 28 +++++++++++++++++++ _posts/08-05-01-Further-Reading.md | 27 ++++++++++++++++++ ...s.md => 09-01-01-Errors-and-Exceptions.md} | 0 ...{08-02-01-Errors.md => 09-02-01-Errors.md} | 0 ...1-Exceptions.md => 09-03-01-Exceptions.md} | 0 ...01-01-Security.md => 10-01-01-Security.md} | 0 ...d => 10-02-01-Web-Application-Security.md} | 0 ...ashing.md => 10-03-01-Password-Hashing.md} | 0 ...iltering.md => 10-04-01-Data-Filtering.md} | 0 ...les.md => 10-05-01-Configuration-Files.md} | 0 ...lobals.md => 10-06-01-Register-Globals.md} | 0 ...porting.md => 10-07-01-Error-Reporting.md} | 0 ...0-01-01-Testing.md => 11-01-01-Testing.md} | 0 ...md => 11-02-01-Test-Driven-Development.md} | 0 ...> 11-03-01-Behavior-Driven-Development.md} | 0 ...> 11-04-01-Complementary-Testing-Tools.md} | 0 ....md => 12-01-01-Servers-and-Deployment.md} | 0 ...e.md => 12-02-01-Platform-as-a-Service.md} | 0 ... 12-03-01-Virtual-or-Dedicated-Servers.md} | 0 ...-Servers.md => 12-04-01-Shared-Servers.md} | 0 ... => 12-05-01-Building-your-Application.md} | 0 ...2-01-01-Caching.md => 13-01-01-Caching.md} | 0 ...de-Cache.md => 13-02-01-Bytecode-Cache.md} | 0 ...-Caching.md => 13-03-01-Object-Caching.md} | 0 ...-01-Resources.md => 14-01-01-Resources.md} | 0 ...1-Frameworks.md => 14-02-01-Frameworks.md} | 0 ...1-Components.md => 14-03-01-Components.md} | 0 .../{13-04-01-Books.md => 14-04-01-Books.md} | 0 ...-01-Community.md => 15-01-01-Community.md} | 0 ...{15-01-01-PHPDoc.md => 16-01-01-PHPDoc.md} | 0 35 files changed, 118 insertions(+), 2 deletions(-) rename _posts/{07-01-02-Interacting-via-Code.md => 07-02-01-Interacting-via-Code.md} (97%) rename _posts/{07-01-03-Abstraction-Layers.md => 07-03-01-Abstraction-Layers.md} (95%) create mode 100644 _posts/08-01-01-Templating.md create mode 100644 _posts/08-02-01-Benefits.md create mode 100644 _posts/08-03-01-Plain-PHP-Templates.md create mode 100644 _posts/08-04-01-Compiled-Templates.md create mode 100644 _posts/08-05-01-Further-Reading.md rename _posts/{08-01-01-Errors-and-Exceptions.md => 09-01-01-Errors-and-Exceptions.md} (100%) rename _posts/{08-02-01-Errors.md => 09-02-01-Errors.md} (100%) rename _posts/{08-03-01-Exceptions.md => 09-03-01-Exceptions.md} (100%) rename _posts/{09-01-01-Security.md => 10-01-01-Security.md} (100%) rename _posts/{09-02-01-Web-Application-Security.md => 10-02-01-Web-Application-Security.md} (100%) rename _posts/{09-03-01-Password-Hashing.md => 10-03-01-Password-Hashing.md} (100%) rename _posts/{09-04-01-Data-Filtering.md => 10-04-01-Data-Filtering.md} (100%) rename _posts/{09-05-01-Configuration-Files.md => 10-05-01-Configuration-Files.md} (100%) rename _posts/{09-06-01-Register-Globals.md => 10-06-01-Register-Globals.md} (100%) rename _posts/{09-07-01-Error-Reporting.md => 10-07-01-Error-Reporting.md} (100%) rename _posts/{10-01-01-Testing.md => 11-01-01-Testing.md} (100%) rename _posts/{10-02-01-Test-Driven-Development.md => 11-02-01-Test-Driven-Development.md} (100%) rename _posts/{10-03-01-Behavior-Driven-Development.md => 11-03-01-Behavior-Driven-Development.md} (100%) rename _posts/{10-04-01-Complementary-Testing-Tools.md => 11-04-01-Complementary-Testing-Tools.md} (100%) rename _posts/{11-01-01-Servers-and-Deployment.md => 12-01-01-Servers-and-Deployment.md} (100%) rename _posts/{11-02-01-Platform-as-a-Service.md => 12-02-01-Platform-as-a-Service.md} (100%) rename _posts/{11-03-01-Virtual-or-Dedicated-Servers.md => 12-03-01-Virtual-or-Dedicated-Servers.md} (100%) rename _posts/{11-04-01-Shared-Servers.md => 12-04-01-Shared-Servers.md} (100%) rename _posts/{11-05-01-Building-your-Application.md => 12-05-01-Building-your-Application.md} (100%) rename _posts/{12-01-01-Caching.md => 13-01-01-Caching.md} (100%) rename _posts/{12-02-01-Bytecode-Cache.md => 13-02-01-Bytecode-Cache.md} (100%) rename _posts/{12-03-01-Object-Caching.md => 13-03-01-Object-Caching.md} (100%) rename _posts/{13-01-01-Resources.md => 14-01-01-Resources.md} (100%) rename _posts/{13-02-01-Frameworks.md => 14-02-01-Frameworks.md} (100%) rename _posts/{13-03-01-Components.md => 14-03-01-Components.md} (100%) rename _posts/{13-04-01-Books.md => 14-04-01-Books.md} (100%) rename _posts/{14-01-01-Community.md => 15-01-01-Community.md} (100%) rename _posts/{15-01-01-PHPDoc.md => 16-01-01-PHPDoc.md} (100%) diff --git a/_posts/07-01-02-Interacting-via-Code.md b/_posts/07-02-01-Interacting-via-Code.md similarity index 97% rename from _posts/07-01-02-Interacting-via-Code.md rename to _posts/07-02-01-Interacting-via-Code.md index 9f38be9af..c3364e468 100644 --- a/_posts/07-01-02-Interacting-via-Code.md +++ b/_posts/07-02-01-Interacting-via-Code.md @@ -4,7 +4,7 @@ title: Interacting with Databases anchor: databases_interacting --- -## Interacting with Databases +## Interacting with Databases {#databases_interacting_title} When developers first start to learn PHP, they often end up mixing their database interaction up with their presentation logic, using code that might look like this: diff --git a/_posts/07-01-03-Abstraction-Layers.md b/_posts/07-03-01-Abstraction-Layers.md similarity index 95% rename from _posts/07-01-03-Abstraction-Layers.md rename to _posts/07-03-01-Abstraction-Layers.md index f2bcfc4e3..ee61b63a0 100644 --- a/_posts/07-01-03-Abstraction-Layers.md +++ b/_posts/07-03-01-Abstraction-Layers.md @@ -4,7 +4,7 @@ title: Abstraction Layers anchor: databases_abstraction_layers --- -## Abstraction Layers +## Abstraction Layers {#databases_abstraction_layers_title} Many frameworks provide their own abstraction layer which may or may not sit on top of PDO. These will often emulate features for one database system that is missing from another by wrapping your queries in PHP methods, giving you actual database abstraction instead of just the connection abstraction that PDO provides. diff --git a/_posts/08-01-01-Templating.md b/_posts/08-01-01-Templating.md new file mode 100644 index 000000000..8957e2f73 --- /dev/null +++ b/_posts/08-01-01-Templating.md @@ -0,0 +1,12 @@ +--- +title: Templating +anchor: templating +--- + +# Templating {#templating_title} + +Templates provide a convenient way of separating your controller and domain logic from your presentation logic. +Templates typically contain the HTML of your application, but may also be used for other formats, such as XML. +Templates are often referred to as "views", the second component of the +[model–view–controller](http://www.phptherightway.com/pages/Design-Patterns.html#model-view-controller) (MVC) +software architecture pattern. \ No newline at end of file diff --git a/_posts/08-02-01-Benefits.md b/_posts/08-02-01-Benefits.md new file mode 100644 index 000000000..1da94d68c --- /dev/null +++ b/_posts/08-02-01-Benefits.md @@ -0,0 +1,21 @@ +--- +isChild: true +anchor: templating_benefits +--- + +## Benefits {#templating_benefits_title} + +The main benefit to using templates is the clear separation they create between the presentation logic and the rest of +your application. Templates have the sole responsibility of displaying formatted content. They are not responsible for +data lookup, persistence or other more complex tasks. This leads to cleaner, more readable code which is especially +helpful in a team environment where developers work on the server-side code (controllers, models) and designers work on +the client-side code (markup). + +Templates also improve the organization of presentation code. Templates are typically placed in a "views" folder, each +defined within a single file. This approach encourages code reuse where larger blocks of code are broken into smaller, +reusable pieces. For example, your site header and footer can each be defined as templates, which are then included +before and after each page template. + +Finally, depending on the library you use, templates can offer more security by automatically escaping user-generated +content. Some libraries even offer sand-boxing, where template designers are only given access to white-listed +variables and functions. \ No newline at end of file diff --git a/_posts/08-03-01-Plain-PHP-Templates.md b/_posts/08-03-01-Plain-PHP-Templates.md new file mode 100644 index 000000000..137d6e40d --- /dev/null +++ b/_posts/08-03-01-Plain-PHP-Templates.md @@ -0,0 +1,28 @@ +--- +isChild: true +anchor: plain_php_templates +--- + +## Plain PHP Templates {#plain_php_templates_title} + +Plain PHP templates are simply templates that use native PHP code. They are a natural choice since PHP is actually a +template language itself. That simply means that you can combine PHP code within other code, like HTML. This is +beneficial to PHP developers as there is no new syntax to learn, they know the functions available to them, and their +code editors already have PHP syntax highlighting and auto-completion built-in. Further, plain PHP templates tend to be +very fast as no compiling stage is required. + +Every modern PHP framework employs some kind of template system, most of which use plain PHP by default. Outside of +frameworks, libraries like [Plates](http://platesphp.com/) or [Aura.View](https://github.com/auraphp/Aura.View) make +working with plain PHP templates easier by offering modern template functionality such as inheritance, layouts and +extensions. + +Example of a plain PHP template (using the [Plates](http://platesphp.com/) library): + +{% highlight php %} +insert('header', ['title' => 'User Profile']) ?> + +

      User Profile

      +

      Hello, escape($name)?>

      + +insert('footer') ?> +{% endhighlight %} \ No newline at end of file diff --git a/_posts/08-04-01-Compiled-Templates.md b/_posts/08-04-01-Compiled-Templates.md new file mode 100644 index 000000000..d46cd70b9 --- /dev/null +++ b/_posts/08-04-01-Compiled-Templates.md @@ -0,0 +1,28 @@ +--- +isChild: true +anchor: compiled_templates +--- + +## Compiled Templates {#compiled_templates} + +While PHP has evolved into a mature, object oriented language, it +[hasn't improved much](http://fabien.potencier.org/article/34/templating-engines-in-php) as a templating language. +Compiled templates, like [Twig](http://twig.sensiolabs.org/) or [Smarty](http://www.smarty.net/), fill this void by +offering a new syntax that has been geared specifically to templating. From automatic escaping, to inheritance and +simplified control structures, compiled templates are designed to be easier to write, cleaner to read and safer to use. +Compiled templates can even be shared across different languages, [Mustache](http://mustache.github.io/) being a good +example of this. Since these templates must be compiled there is a slight performance hit, however this is very minimal +when proper caching is used. + +Example of a compiled template (using the [Twig](http://twig.sensiolabs.org/) library): + +{% highlight text %} +{% raw %} +{% include 'header.html' with {'title': 'User Profile'} %} + +

      User Profile

      +

      Hello, {{ name }}

      + +{% include 'footer.html' %} +{% endraw %} +{% endhighlight %} \ No newline at end of file diff --git a/_posts/08-05-01-Further-Reading.md b/_posts/08-05-01-Further-Reading.md new file mode 100644 index 000000000..fd8c1600d --- /dev/null +++ b/_posts/08-05-01-Further-Reading.md @@ -0,0 +1,27 @@ +--- +isChild: true +anchor: templating_further_reading +--- + +## Further Reading {#templating_further_reading_title} + +### Articles & Tutorials + +- [Templating Engines in PHP](http://fabien.potencier.org/article/34/templating-engines-in-php) +- [An Introduction to Views & Templating in CodeIgniter](http://code.tutsplus.com/tutorials/an-introduction-to-views-templating-in-codeigniter--net-25648) +- [Getting Started With PHP Templating](http://www.smashingmagazine.com/2011/10/17/getting-started-with-php-templating/) +- [Roll Your Own Templating System in PHP](http://code.tutsplus.com/tutorials/roll-your-own-templating-system-in-php--net-16596) +- [Master Pages](https://laracasts.com/series/laravel-from-scratch/episodes/7) +- [Working With Templates in Symfony 2](http://code.tutsplus.com/tutorials/working-with-templates-in-symfony-2--cms-21172) + +### Libraries + +- [Aura.View](https://github.com/auraphp/Aura.View) *(native)* +- [Blade](http://laravel.com/docs/templates) *(compiled, framework specific)* +- [Dwoo](http://dwoo.org/) *(compiled)* +- [Mustache](https://github.com/bobthecow/mustache.php) *(compiled)* +- [PHPTAL](http://phptal.org/) *(compiled)* +- [Plates](http://platesphp.com/) *(native)* +- [Smarty](http://www.smarty.net/) *(compiled)* +- [Twig](http://twig.sensiolabs.org/) *(compiled)* +- [Zend\View](http://framework.zend.com/manual/2.3/en/modules/zend.view.quick-start.html) *(native, framework specific)* \ No newline at end of file diff --git a/_posts/08-01-01-Errors-and-Exceptions.md b/_posts/09-01-01-Errors-and-Exceptions.md similarity index 100% rename from _posts/08-01-01-Errors-and-Exceptions.md rename to _posts/09-01-01-Errors-and-Exceptions.md diff --git a/_posts/08-02-01-Errors.md b/_posts/09-02-01-Errors.md similarity index 100% rename from _posts/08-02-01-Errors.md rename to _posts/09-02-01-Errors.md diff --git a/_posts/08-03-01-Exceptions.md b/_posts/09-03-01-Exceptions.md similarity index 100% rename from _posts/08-03-01-Exceptions.md rename to _posts/09-03-01-Exceptions.md diff --git a/_posts/09-01-01-Security.md b/_posts/10-01-01-Security.md similarity index 100% rename from _posts/09-01-01-Security.md rename to _posts/10-01-01-Security.md diff --git a/_posts/09-02-01-Web-Application-Security.md b/_posts/10-02-01-Web-Application-Security.md similarity index 100% rename from _posts/09-02-01-Web-Application-Security.md rename to _posts/10-02-01-Web-Application-Security.md diff --git a/_posts/09-03-01-Password-Hashing.md b/_posts/10-03-01-Password-Hashing.md similarity index 100% rename from _posts/09-03-01-Password-Hashing.md rename to _posts/10-03-01-Password-Hashing.md diff --git a/_posts/09-04-01-Data-Filtering.md b/_posts/10-04-01-Data-Filtering.md similarity index 100% rename from _posts/09-04-01-Data-Filtering.md rename to _posts/10-04-01-Data-Filtering.md diff --git a/_posts/09-05-01-Configuration-Files.md b/_posts/10-05-01-Configuration-Files.md similarity index 100% rename from _posts/09-05-01-Configuration-Files.md rename to _posts/10-05-01-Configuration-Files.md diff --git a/_posts/09-06-01-Register-Globals.md b/_posts/10-06-01-Register-Globals.md similarity index 100% rename from _posts/09-06-01-Register-Globals.md rename to _posts/10-06-01-Register-Globals.md diff --git a/_posts/09-07-01-Error-Reporting.md b/_posts/10-07-01-Error-Reporting.md similarity index 100% rename from _posts/09-07-01-Error-Reporting.md rename to _posts/10-07-01-Error-Reporting.md diff --git a/_posts/10-01-01-Testing.md b/_posts/11-01-01-Testing.md similarity index 100% rename from _posts/10-01-01-Testing.md rename to _posts/11-01-01-Testing.md diff --git a/_posts/10-02-01-Test-Driven-Development.md b/_posts/11-02-01-Test-Driven-Development.md similarity index 100% rename from _posts/10-02-01-Test-Driven-Development.md rename to _posts/11-02-01-Test-Driven-Development.md diff --git a/_posts/10-03-01-Behavior-Driven-Development.md b/_posts/11-03-01-Behavior-Driven-Development.md similarity index 100% rename from _posts/10-03-01-Behavior-Driven-Development.md rename to _posts/11-03-01-Behavior-Driven-Development.md diff --git a/_posts/10-04-01-Complementary-Testing-Tools.md b/_posts/11-04-01-Complementary-Testing-Tools.md similarity index 100% rename from _posts/10-04-01-Complementary-Testing-Tools.md rename to _posts/11-04-01-Complementary-Testing-Tools.md diff --git a/_posts/11-01-01-Servers-and-Deployment.md b/_posts/12-01-01-Servers-and-Deployment.md similarity index 100% rename from _posts/11-01-01-Servers-and-Deployment.md rename to _posts/12-01-01-Servers-and-Deployment.md diff --git a/_posts/11-02-01-Platform-as-a-Service.md b/_posts/12-02-01-Platform-as-a-Service.md similarity index 100% rename from _posts/11-02-01-Platform-as-a-Service.md rename to _posts/12-02-01-Platform-as-a-Service.md diff --git a/_posts/11-03-01-Virtual-or-Dedicated-Servers.md b/_posts/12-03-01-Virtual-or-Dedicated-Servers.md similarity index 100% rename from _posts/11-03-01-Virtual-or-Dedicated-Servers.md rename to _posts/12-03-01-Virtual-or-Dedicated-Servers.md diff --git a/_posts/11-04-01-Shared-Servers.md b/_posts/12-04-01-Shared-Servers.md similarity index 100% rename from _posts/11-04-01-Shared-Servers.md rename to _posts/12-04-01-Shared-Servers.md diff --git a/_posts/11-05-01-Building-your-Application.md b/_posts/12-05-01-Building-your-Application.md similarity index 100% rename from _posts/11-05-01-Building-your-Application.md rename to _posts/12-05-01-Building-your-Application.md diff --git a/_posts/12-01-01-Caching.md b/_posts/13-01-01-Caching.md similarity index 100% rename from _posts/12-01-01-Caching.md rename to _posts/13-01-01-Caching.md diff --git a/_posts/12-02-01-Bytecode-Cache.md b/_posts/13-02-01-Bytecode-Cache.md similarity index 100% rename from _posts/12-02-01-Bytecode-Cache.md rename to _posts/13-02-01-Bytecode-Cache.md diff --git a/_posts/12-03-01-Object-Caching.md b/_posts/13-03-01-Object-Caching.md similarity index 100% rename from _posts/12-03-01-Object-Caching.md rename to _posts/13-03-01-Object-Caching.md diff --git a/_posts/13-01-01-Resources.md b/_posts/14-01-01-Resources.md similarity index 100% rename from _posts/13-01-01-Resources.md rename to _posts/14-01-01-Resources.md diff --git a/_posts/13-02-01-Frameworks.md b/_posts/14-02-01-Frameworks.md similarity index 100% rename from _posts/13-02-01-Frameworks.md rename to _posts/14-02-01-Frameworks.md diff --git a/_posts/13-03-01-Components.md b/_posts/14-03-01-Components.md similarity index 100% rename from _posts/13-03-01-Components.md rename to _posts/14-03-01-Components.md diff --git a/_posts/13-04-01-Books.md b/_posts/14-04-01-Books.md similarity index 100% rename from _posts/13-04-01-Books.md rename to _posts/14-04-01-Books.md diff --git a/_posts/14-01-01-Community.md b/_posts/15-01-01-Community.md similarity index 100% rename from _posts/14-01-01-Community.md rename to _posts/15-01-01-Community.md diff --git a/_posts/15-01-01-PHPDoc.md b/_posts/16-01-01-PHPDoc.md similarity index 100% rename from _posts/15-01-01-PHPDoc.md rename to _posts/16-01-01-PHPDoc.md From 4cf1099ca074cb9e54f54f04f2610942e281bf55 Mon Sep 17 00:00:00 2001 From: David Matejka Date: Sun, 27 Jul 2014 01:36:00 +0200 Subject: [PATCH 284/843] Templating: added latte link --- _posts/08-05-01-Further-Reading.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/_posts/08-05-01-Further-Reading.md b/_posts/08-05-01-Further-Reading.md index fd8c1600d..02f3357af 100644 --- a/_posts/08-05-01-Further-Reading.md +++ b/_posts/08-05-01-Further-Reading.md @@ -19,9 +19,10 @@ anchor: templating_further_reading - [Aura.View](https://github.com/auraphp/Aura.View) *(native)* - [Blade](http://laravel.com/docs/templates) *(compiled, framework specific)* - [Dwoo](http://dwoo.org/) *(compiled)* +- [Latte](https://github.com/nette/latte) *(compiled)* - [Mustache](https://github.com/bobthecow/mustache.php) *(compiled)* - [PHPTAL](http://phptal.org/) *(compiled)* - [Plates](http://platesphp.com/) *(native)* - [Smarty](http://www.smarty.net/) *(compiled)* - [Twig](http://twig.sensiolabs.org/) *(compiled)* -- [Zend\View](http://framework.zend.com/manual/2.3/en/modules/zend.view.quick-start.html) *(native, framework specific)* \ No newline at end of file +- [Zend\View](http://framework.zend.com/manual/2.3/en/modules/zend.view.quick-start.html) *(native, framework specific)* From 39caad2fa62f7f3975b7e7e8591cb729c3b8b522 Mon Sep 17 00:00:00 2001 From: James Gill Date: Sun, 3 Aug 2014 20:14:02 -0700 Subject: [PATCH 285/843] Several grammatic edits to introductory topics to improve readability and flow. --- _posts/01-02-01-Use-the-Current-Stable-Version.md | 2 +- _posts/01-03-01-Built-in-Web-Server.md | 2 +- _posts/01-04-01-Mac-Setup.md | 7 +++---- _posts/03-05-01-Command-Line-Interface.md | 2 +- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/_posts/01-02-01-Use-the-Current-Stable-Version.md b/_posts/01-02-01-Use-the-Current-Stable-Version.md index 16d2f1d34..fa5f8f991 100644 --- a/_posts/01-02-01-Use-the-Current-Stable-Version.md +++ b/_posts/01-02-01-Use-the-Current-Stable-Version.md @@ -6,7 +6,7 @@ anchor: use_the_current_stable_version ## Use the Current Stable Version (5.5) {#use_the_current_stable_version_title} -If you are just getting started with PHP make sure to start with the current stable release of [PHP 5.5][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.5 fool you, it represents _major_ improvements. If you are looking for a function or its usage, the documentation on the [php.net][php-docs] website will have the answer. +If you are getting started with PHP, start with the current stable release of [PHP 5.5][php-release]. PHP has added powerful [new features](#language_highlights) over the last few years. Though the incremental version number difference between 5.2 and 5.5 is small, it represents _major_ improvements. If you are looking for a function or its usage, the documentation on the [php.net][php-docs] website will have the answer. [php-release]: http://www.php.net/downloads.php [php-docs]: http://www.php.net/manual/en/ diff --git a/_posts/01-03-01-Built-in-Web-Server.md b/_posts/01-03-01-Built-in-Web-Server.md index a7b9fffad..f33c00235 100644 --- a/_posts/01-03-01-Built-in-Web-Server.md +++ b/_posts/01-03-01-Built-in-Web-Server.md @@ -6,7 +6,7 @@ anchor: builtin_web_server ## Built-in web server {#builtin_web_server_title} -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: +With PHP 5.4 or newer, you can start learning PHP without installing and configuring a full-fledged web server. To start the server, run the following command from your terminal in your project's web root: > php -S localhost:8000 diff --git a/_posts/01-04-01-Mac-Setup.md b/_posts/01-04-01-Mac-Setup.md index 3aed1e638..bcdbb9eb4 100644 --- a/_posts/01-04-01-Mac-Setup.md +++ b/_posts/01-04-01-Mac-Setup.md @@ -11,11 +11,10 @@ Mountain Lion has 5.3.10, and Mavericks has 5.4.17. To update PHP on OSX you can get it installed through a number of Mac [package managers][mac-package-managers], with [php-osx by Liip][php-osx-downloads] being recommended. -The other option is to [compile it yourself][mac-compile], in that case be sure to have installed either Xcode or -Apple's substitute ["Command Line Tools for Xcode"][apple-developer] downloadable from Apple's Mac Developer Center. +You can also [compile it yourself][mac-compile]; if you do, be sure to have installed either Xcode or +Apple's substitute ["Command Line Tools for Xcode"][apple-developer], downloadable from Apple's Mac Developer Center. -For a complete "all-in-one" package including PHP, Apache web server and MySQL database, all this with a nice control -GUI, try [MAMP][mamp-downloads] or [XAMPP][xampp]. +For a complete "all-in-one" package that includes PHP, Apache web server and MySQL database, all with a nice graphical interface, try [MAMP][mamp-downloads] or [XAMPP][xampp]. [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 diff --git a/_posts/03-05-01-Command-Line-Interface.md b/_posts/03-05-01-Command-Line-Interface.md index bf40a8813..d5d9af482 100644 --- a/_posts/03-05-01-Command-Line-Interface.md +++ b/_posts/03-05-01-Command-Line-Interface.md @@ -5,7 +5,7 @@ anchor: command_line_interface ## Command Line Interface {#command_line_interface_title} -PHP was created primarily to write web applications, but it's also useful for scripting command line interface (CLI) programs. Command line PHP programs can help you automate common tasks like testing, deployment, and application administrivia. +PHP was created to write web applications, but is also useful for scripting command line interface (CLI) programs. Command line PHP programs can help automate common tasks like testing, deployment, and application administrivia. 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! From 3e660e37ed9a2389ec297672d89b361e0025fe09 Mon Sep 17 00:00:00 2001 From: Dave Hulbert Date: Fri, 8 Aug 2014 12:14:24 +0100 Subject: [PATCH 286/843] Tweak example code for PSR-1/PSR-2 coding standard --- pages/Design-Patterns.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/pages/Design-Patterns.md b/pages/Design-Patterns.md index 22d85a08f..a09e10903 100644 --- a/pages/Design-Patterns.md +++ b/pages/Design-Patterns.md @@ -21,18 +21,18 @@ the object you want to use. Consider the following example of the factory patter vehicle_make = $make; - $this->vehicle_model = $model; + $this->vehicleMake = $make; + $this->vehicleModel = $model; } - public function get_make_and_model() + public function getMakeAndModel() { - return $this->vehicle_make . ' ' . $this->vehicle_model; + return $this->vehicleMake . ' ' . $this->vehicleModel; } } @@ -47,7 +47,7 @@ class AutomobileFactory // have the factory create the Automobile object $veyron = AutomobileFactory::create('Bugatti', 'Veyron'); -print_r($veyron->get_make_and_model()); // outputs "Bugatti Veyron" +print_r($veyron->getMakeAndModel()); // outputs "Bugatti Veyron" {% endhighlight %} This code uses a factory to create the Automobile object. There are two possible benefits to building your code this From 8b794f84c4f2946e208ee9877d3a29288d5ebd4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ol=C5=A1ansk=C3=BD?= Date: Sat, 9 Aug 2014 22:00:25 +0200 Subject: [PATCH 287/843] Update 07-01-01-Databases.md --- _posts/07-01-01-Databases.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_posts/07-01-01-Databases.md b/_posts/07-01-01-Databases.md index a314cfa85..1ef02b1bf 100644 --- a/_posts/07-01-01-Databases.md +++ b/_posts/07-01-01-Databases.md @@ -21,14 +21,14 @@ versions of PHP. This means you will be faced with a rewrite at some point down replace mysql usage with [mysqli] or [PDO] in your applications within your own development schedules so you won't be rushed later on. -**If you are starting from scratch then absolutely do not use the [mysql] extension: use the [MySQLi extension][mysqli], or use PDO.** +**If you are starting from scratch then absolutely do not use the [mysql] extension: use the [MySQLi extension][mysqli], or use [PDO].** * [PHP: Choosing an API for MySQL](http://php.net/manual/en/mysqlinfo.api.choosing.php) * [PDO Tutorial for MySQL Developers](http://wiki.hashphp.org/PDO_Tutorial_for_MySQL_Developers) ## PDO Extension -PDO is a database connection abstraction library — built into PHP since 5.1.0 — that provides a common interface to talk with +[PDO] is a database connection abstraction library — built into PHP since 5.1.0 — that provides a common interface to talk with many different databases. For example, you can use basically identical code to interface with MySQL or SQLite: {% highlight php %} From d6f59a1ce01a8dd0a8f0a2f903e5622e8ec35f80 Mon Sep 17 00:00:00 2001 From: Jonathan Reinink Date: Fri, 15 Aug 2014 13:53:45 -0400 Subject: [PATCH 288/843] Improve to the templating section Add inheritance examples Add the word "partials" to better describe reusable pieces of code Clarify the role of templates (views) in the MVC pattern Add note of caution around Smarty auto escaping --- _posts/08-01-01-Templating.md | 2 +- _posts/08-02-01-Benefits.md | 4 +-- _posts/08-03-01-Plain-PHP-Templates.md | 36 ++++++++++++++++++++- _posts/08-04-01-Compiled-Templates.md | 45 ++++++++++++++++++++++++-- 4 files changed, 81 insertions(+), 6 deletions(-) diff --git a/_posts/08-01-01-Templating.md b/_posts/08-01-01-Templating.md index 8957e2f73..3bcc5b856 100644 --- a/_posts/08-01-01-Templating.md +++ b/_posts/08-01-01-Templating.md @@ -7,6 +7,6 @@ anchor: templating Templates provide a convenient way of separating your controller and domain logic from your presentation logic. Templates typically contain the HTML of your application, but may also be used for other formats, such as XML. -Templates are often referred to as "views", the second component of the +Templates are often referred to as “views”, which make up **part of** the second component of the [model–view–controller](http://www.phptherightway.com/pages/Design-Patterns.html#model-view-controller) (MVC) software architecture pattern. \ No newline at end of file diff --git a/_posts/08-02-01-Benefits.md b/_posts/08-02-01-Benefits.md index 1da94d68c..8e21de703 100644 --- a/_posts/08-02-01-Benefits.md +++ b/_posts/08-02-01-Benefits.md @@ -13,8 +13,8 @@ the client-side code (markup). Templates also improve the organization of presentation code. Templates are typically placed in a "views" folder, each defined within a single file. This approach encourages code reuse where larger blocks of code are broken into smaller, -reusable pieces. For example, your site header and footer can each be defined as templates, which are then included -before and after each page template. +reusable pieces, often called partials. For example, your site header and footer can each be defined as templates, +which are then included before and after each page template. Finally, depending on the library you use, templates can offer more security by automatically escaping user-generated content. Some libraries even offer sand-boxing, where template designers are only given access to white-listed diff --git a/_posts/08-03-01-Plain-PHP-Templates.md b/_posts/08-03-01-Plain-PHP-Templates.md index 137d6e40d..57a6a5371 100644 --- a/_posts/08-03-01-Plain-PHP-Templates.md +++ b/_posts/08-03-01-Plain-PHP-Templates.md @@ -16,13 +16,47 @@ frameworks, libraries like [Plates](http://platesphp.com/) or [Aura.View](https: working with plain PHP templates easier by offering modern template functionality such as inheritance, layouts and extensions. -Example of a plain PHP template (using the [Plates](http://platesphp.com/) library): +### Simple example of a plain PHP template + +Using the [Plates](http://platesphp.com/) library. {% highlight php %} + + insert('header', ['title' => 'User Profile']) ?>

      User Profile

      Hello, escape($name)?>

      insert('footer') ?> +{% endhighlight %} + +### Example of plain PHP templates using inheritance + +Using the [Plates](http://platesphp.com/) library. + +{% highlight php %} + + + + + <?=$title?> + + + +
      + section('content')?> +
      + + + +{% endhighlight %} + +{% highlight php %} + + +layout('template', ['title' => 'User Profile']) ?> + +

      User Profile

      +

      Hello, escape($name)?>

      {% endhighlight %} \ No newline at end of file diff --git a/_posts/08-04-01-Compiled-Templates.md b/_posts/08-04-01-Compiled-Templates.md index d46cd70b9..02aabee82 100644 --- a/_posts/08-04-01-Compiled-Templates.md +++ b/_posts/08-04-01-Compiled-Templates.md @@ -7,14 +7,18 @@ anchor: compiled_templates While PHP has evolved into a mature, object oriented language, it [hasn't improved much](http://fabien.potencier.org/article/34/templating-engines-in-php) as a templating language. -Compiled templates, like [Twig](http://twig.sensiolabs.org/) or [Smarty](http://www.smarty.net/), fill this void by +Compiled templates, like [Twig](http://twig.sensiolabs.org/) or [Smarty](http://www.smarty.net/)*, fill this void by offering a new syntax that has been geared specifically to templating. From automatic escaping, to inheritance and simplified control structures, compiled templates are designed to be easier to write, cleaner to read and safer to use. Compiled templates can even be shared across different languages, [Mustache](http://mustache.github.io/) being a good example of this. Since these templates must be compiled there is a slight performance hit, however this is very minimal when proper caching is used. -Example of a compiled template (using the [Twig](http://twig.sensiolabs.org/) library): +**While Smarty offers automatic escaping, this feature is NOT enabled by default.* + +### Simple example of a compiled template + +Using the [Twig](http://twig.sensiolabs.org/) library. {% highlight text %} {% raw %} @@ -25,4 +29,41 @@ Example of a compiled template (using the [Twig](http://twig.sensiolabs.org/) li {% include 'footer.html' %} {% endraw %} +{% endhighlight %} + +### Example of compiled templates using inheritance + +Using the [Twig](http://twig.sensiolabs.org/) library. + +{% highlight text %} +{% raw %} +// template.php + + + + {% block title %}{% endblock %} + + + +
      + {% block content %}{% endblock %} +
      + + + +{% endraw %} +{% endhighlight %} + +{% highlight text %} +{% raw %} +// user_profile.php + +{% extends "template.html" %} + +{% block title %}User Profile{% endblock %} +{% block content %} +

      User Profile

      +

      Hello, {{ name }}

      +{% endblock %} +{% endraw %} {% endhighlight %} \ No newline at end of file From cc9361f1e66f3170b485d877ec7317e52a3e63ea Mon Sep 17 00:00:00 2001 From: Jonathan Reinink Date: Fri, 15 Aug 2014 14:01:56 -0400 Subject: [PATCH 289/843] Remove magic quotes from templating section. --- _posts/08-01-01-Templating.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/08-01-01-Templating.md b/_posts/08-01-01-Templating.md index 3bcc5b856..a8d3b274b 100644 --- a/_posts/08-01-01-Templating.md +++ b/_posts/08-01-01-Templating.md @@ -7,6 +7,6 @@ anchor: templating Templates provide a convenient way of separating your controller and domain logic from your presentation logic. Templates typically contain the HTML of your application, but may also be used for other formats, such as XML. -Templates are often referred to as “views”, which make up **part of** the second component of the +Templates are often referred to as "views", which make up **part of** the second component of the [model–view–controller](http://www.phptherightway.com/pages/Design-Patterns.html#model-view-controller) (MVC) software architecture pattern. \ No newline at end of file From 9bb94659d88006c7b5889e992ee712cafc482b31 Mon Sep 17 00:00:00 2001 From: ISHIDA Akio Date: Tue, 19 Aug 2014 20:16:07 +0900 Subject: [PATCH 290/843] Heroku supports PHP. Fix link. Heroku PHP support is now GA. https://blog.heroku.com/archives/2014/7/15/the_new_php_on_heroku_now_generally_available --- _posts/14-01-01-Resources.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/_posts/14-01-01-Resources.md b/_posts/14-01-01-Resources.md index 0d3ac38a4..06c3b2edc 100644 --- a/_posts/14-01-01-Resources.md +++ b/_posts/14-01-01-Resources.md @@ -29,8 +29,7 @@ anchor: resources * [PagodaBox](https://pagodabox.com/) * [AppFog](https://appfog.com/) -* [Heroku](https://heroku.com) - (PHP support is undocumented but based on stable Facebook partnership [link](http://net.tutsplus.com/tutorials/php/quick-tip-deploy-php-to-heroku-in-seconds/)) +* [Heroku](https://devcenter.heroku.com/categories/php) * [fortrabbit](http://fortrabbit.com/) * [Engine Yard Cloud](https://www.engineyard.com/products/cloud) * [Red Hat OpenShift Platform](http://openshift.com) From cfe8916dfe7e2509e5921ef0462e17dbbd9b183b Mon Sep 17 00:00:00 2001 From: Peter Wiseman Date: Tue, 19 Aug 2014 23:30:59 +1000 Subject: [PATCH 291/843] Removed reference to maven The php-maven.org project has not been maintained for the last couple of years. It looked promising but doesn't work out of the box, and searching the web, I couldn't find anyone successfully getting it working recently. It looks like a lost cause for php. --- _posts/12-05-01-Building-your-Application.md | 1 - 1 file changed, 1 deletion(-) diff --git a/_posts/12-05-01-Building-your-Application.md b/_posts/12-05-01-Building-your-Application.md index 6a9e5bc10..ee6c557ba 100644 --- a/_posts/12-05-01-Building-your-Application.md +++ b/_posts/12-05-01-Building-your-Application.md @@ -53,7 +53,6 @@ Chef resources for PHP developers: Further reading: * [Automate your project with Apache Ant](http://net.tutsplus.com/tutorials/other/automate-your-projects-with-apache-ant/) -* [Maven](http://maven.apache.org/), a build framework based on Ant and [how to use it with PHP](http://www.php-maven.org/) ### Continuous Integration From 7e22b43451ef4d96a969953d42d08631cbdf33a7 Mon Sep 17 00:00:00 2001 From: Mohammad Javad Naderi Date: Wed, 20 Aug 2014 13:13:07 +0430 Subject: [PATCH 292/843] Use site.baseurl in stylesheet URLs --- _layouts/default.html | 8 ++++---- _layouts/page.html | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/_layouts/default.html b/_layouts/default.html index 8e09eee2e..ac2d6b75b 100644 --- a/_layouts/default.html +++ b/_layouts/default.html @@ -13,10 +13,10 @@ - - - - + + + + - + diff --git a/_layouts/page.html b/_layouts/page.html index ed25cc7cc..0396cb84c 100644 --- a/_layouts/page.html +++ b/_layouts/page.html @@ -12,7 +12,7 @@ - + @@ -42,7 +42,7 @@ Return to Main Page
      From 72f1ccedb6d29a3e45881e94f2934007d20f5c85 Mon Sep 17 00:00:00 2001 From: defenestrator Date: Wed, 7 Jan 2015 12:16:29 -0700 Subject: [PATCH 394/843] Fix typos and improve readability of one sentence in Section 3. --- _posts/03-02-01-Programming-Paradigms.md | 6 +++--- _posts/03-05-01-Command-Line-Interface.md | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/_posts/03-02-01-Programming-Paradigms.md b/_posts/03-02-01-Programming-Paradigms.md index 9271541ab..772f27c33 100644 --- a/_posts/03-02-01-Programming-Paradigms.md +++ b/_posts/03-02-01-Programming-Paradigms.md @@ -21,10 +21,10 @@ interfaces, inheritance, constructors, cloning, exceptions, and more. PHP supports first-class function, meaning that a function can be assigned to a variable. Both user-defined and built-in functions can be referenced by a variable and invoked dynamically. Functions can be passed as arguments to -other functions (feature called Higher-order functions) and function can return other functions. +other functions (a feature called _Higher-order Functions_) and function can return other functions. -Recursion, a feature that allows a function to call itself, is supported by the language, but most of the PHP code -focus on iteration. +Recursion, a feature that allows a function to call itself, is supported by the language, but most PHP code +is focused on iteration. New anonymous functions (with support for closures) are present since PHP 5.3 (2009). diff --git a/_posts/03-05-01-Command-Line-Interface.md b/_posts/03-05-01-Command-Line-Interface.md index beb5c3cae..825e1c315 100644 --- a/_posts/03-05-01-Command-Line-Interface.md +++ b/_posts/03-05-01-Command-Line-Interface.md @@ -6,7 +6,7 @@ anchor: command_line_interface ## Command Line Interface {#command_line_interface_title} PHP was created to write web applications, but is also useful for scripting command line interface (CLI) programs. -Command line PHP programs can help automate common tasks like testing, deployment, and application administrivia. +Command line PHP programs can help automate common tasks like testing, deployment, and application administration. 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! From 239fbe97650346657e4afeaa727a7fc007dacef6 Mon Sep 17 00:00:00 2001 From: Suraj Adhikari Date: Thu, 8 Jan 2015 11:01:22 +0545 Subject: [PATCH 395/843] Add Youtube Channels section for more free content YouTube has always been a great starting point for everyone to start learning new technologies. Some of the channels that I've listed frequently updates their content with modern information. So i think adding them will be a great help for new and experienced developers. --- _posts/16-09-01-Videos.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/_posts/16-09-01-Videos.md b/_posts/16-09-01-Videos.md index 66e1ec07f..d021b2ed1 100644 --- a/_posts/16-09-01-Videos.md +++ b/_posts/16-09-01-Videos.md @@ -4,7 +4,11 @@ anchor: videos title: Video Tutorials --- -## Video Tutorials {#videos_title} +### Youtube Channels +* [PHP Academy](https://www.youtube.com/user/phpacademy) +* [The New Boston](https://www.youtube.com/user/thenewboston) +* [Sherif Ramadan](https://www.youtube.com/user/businessgeek) +* [Level Up Tuts](https://www.youtube.com/user/LevelUpTuts) ### Paid Videos From bdd27c18c0dce2c720cdb6df1d365fa456a052d3 Mon Sep 17 00:00:00 2001 From: Donato Rotunno Date: Fri, 9 Jan 2015 11:23:51 +0100 Subject: [PATCH 396/843] Add Liip's popular installation method for OS X --- _posts/01-04-01-Mac-Setup.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/_posts/01-04-01-Mac-Setup.md b/_posts/01-04-01-Mac-Setup.md index 0dceb5e9a..853f4a5dc 100644 --- a/_posts/01-04-01-Mac-Setup.md +++ b/_posts/01-04-01-Mac-Setup.md @@ -23,6 +23,10 @@ between them by modifying your `PATH` variable. [phpbrew] is a tool for installing and managing multiple PHP versions. This can be really useful if two different applications/projects require different versions of PHP, and you are not using virtual machines. +### Install PHP via Liip's binary installer +Another popular option is [php-osx.liip.ch] which provides one liner installation method from version 5.3 to 5.6. +It doesn't overwrite the php binaries installed by Apple, but installs everything in a separate location (/usr/local/php5). + ### Compile from Source Another option that gives you control over the version of PHP you install, is to [compile it yourself][mac-compile]. @@ -39,6 +43,7 @@ you and tie them all together, but ease of setup comes with a trade-off of flexi [Homebrew]: http://brew.sh/ [Homebrew PHP]: https://github.com/Homebrew/homebrew-php#installation [phpbrew]: https://github.com/phpbrew/phpbrew +[php-osx.liip.ch]: http://php-osx.liip.ch/ [mac-compile]: http://php.net/install.macosx.compile [xcode-gcc-substitution]: https://github.com/kennethreitz/osx-gcc-installer ["Command Line Tools for XCode"]: https://developer.apple.com/downloads From af6ae2565c151964f942ceaaeecc0f7d671369ad Mon Sep 17 00:00:00 2001 From: Donato Rotunno Date: Fri, 9 Jan 2015 11:37:18 +0100 Subject: [PATCH 397/843] Improve wording --- _posts/01-04-01-Mac-Setup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/01-04-01-Mac-Setup.md b/_posts/01-04-01-Mac-Setup.md index 853f4a5dc..e2cb3b99d 100644 --- a/_posts/01-04-01-Mac-Setup.md +++ b/_posts/01-04-01-Mac-Setup.md @@ -24,7 +24,7 @@ between them by modifying your `PATH` variable. applications/projects require different versions of PHP, and you are not using virtual machines. ### Install PHP via Liip's binary installer -Another popular option is [php-osx.liip.ch] which provides one liner installation method from version 5.3 to 5.6. +Another popular option is [php-osx.liip.ch] which provides one liner installation methods for versions 5.3 through 5.6. It doesn't overwrite the php binaries installed by Apple, but installs everything in a separate location (/usr/local/php5). ### Compile from Source From f328d5fc1a8591e5e592846a07124c225b73c9c1 Mon Sep 17 00:00:00 2001 From: Chris Brown Date: Sat, 10 Jan 2015 17:15:05 -0500 Subject: [PATCH 398/843] Update 01-05-01-Windows-Setup.md Removed link to Zend Server CE, since that product is no longer available, and the new options are no longer free (unless you can confirm you're a contributor to an active Open Source project, or you want the headaches of dealing with expiring trial licenses). --- _posts/01-05-01-Windows-Setup.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/_posts/01-05-01-Windows-Setup.md b/_posts/01-05-01-Windows-Setup.md index 27fb89d0a..547f8c837 100644 --- a/_posts/01-05-01-Windows-Setup.md +++ b/_posts/01-05-01-Windows-Setup.md @@ -10,7 +10,7 @@ could use a '.msi' installer. The installer is no longer supported and stops at For learning and local development you can use the built in webserver with PHP 5.4+ so you don't need to worry about configuring it. If you would like an "all-in-one" which includes a full-blown webserver and MySQL too then tools such -as the [Web Platform Installer][wpi], [Zend Server CE][zsce], [XAMPP][xampp], [EasyPHP][easyphp] and [WAMP][wamp] will +as the [Web Platform Installer][wpi], [XAMPP][xampp], [EasyPHP][easyphp] and [WAMP][wamp] will help get a Windows development environment up and running fast. That said, these tools will be a little different from production so be careful of environment differences if you are working on Windows and deploying to Linux. @@ -22,7 +22,6 @@ there is a [dedicated area on iis.net][php-iis] for PHP. [php-downloads]: http://windows.php.net [wpi]: http://www.microsoft.com/web/downloads/platform.aspx -[zsce]: http://www.zend.com/en/products/server-ce/ [xampp]: http://www.apachefriends.org/en/xampp.html [easyphp]: http://www.easyphp.org/ [wamp]: http://www.wampserver.com/en/ From 84de9271d2891224fd287fb7086810632da36c5e Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Sun, 11 Jan 2015 23:56:23 +0100 Subject: [PATCH 399/843] contributing minor fixings --- CONTRIBUTING.md | 2 +- README.md | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a795ab9eb..3c69b8480 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -62,7 +62,7 @@ included in the project: git checkout -b ``` -4. Install the [Jekyll](https://github.com/mojombo/jekyll/) gem to preview locally. +4. Install the [Jekyll](https://github.com/jekyll/jekyll/) gem to preview locally. 5. Commit your changes in logical chunks. Please adhere to these [git commit message guidelines](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html) diff --git a/README.md b/README.md index f4ab5dcf2..2c0dcf574 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,8 @@ To avoid fragmentation and reader confusion, please choose one of these options: If you use a subdomain, enter the subdomain into the `CNAME` file, and ask us to setup DNS for you. If you do not use a subdomain, remove the `CNAME` file entirely else your fork will not build when pushed. +Add information about your translation in the [wiki page](https://github.com/codeguy/php-the-right-way/wiki/Translations). + When your translation is ready, open an issue on the Issue Tracker to let us know. ## Why From 42bf67238c68a1eca2c946d2c4dd9ba67dbe6fd3 Mon Sep 17 00:00:00 2001 From: Graham Campbell Date: Tue, 13 Jan 2015 23:03:47 +0000 Subject: [PATCH 400/843] Updated phpdoc stuff --- _posts/15-02-01-PHPDoc.md | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/_posts/15-02-01-PHPDoc.md b/_posts/15-02-01-PHPDoc.md index cfbc75871..8ae1faa55 100644 --- a/_posts/15-02-01-PHPDoc.md +++ b/_posts/15-02-01-PHPDoc.md @@ -16,15 +16,15 @@ Below is an example of how you might document a class with a few methods; /** * @author A Name * @link http://www.phpdoc.org/docs/latest/index.html - * @package helper */ class DateTimeHelper { /** * @param mixed $anything Anything that we can convert to a \DateTime object * - * @return \DateTime * @throws \InvalidArgumentException + * + * @return \DateTime */ public function dateTimeFromAnything($anything) { @@ -59,10 +59,9 @@ class DateTimeHelper } {% endhighlight %} -The documentation for the class as a whole firstly has the [@author] tag, this tag is used to document the author of -the code and can be repeated for documenting several authors. Secondly is the [@link] tag, used to link to a website -indicating a relationship between the website and the code. Thirdly it has the [@package] tag, used to categorize the -code. +The documentation for the class as a whole has the [@author] tag and a [@link] tag. The [@author] tag is used to +document the author of the code and can be repeated for documenting several authors. The [@link] tag is used to link to +a website indicating a relationship between the website and the code. Inside the class, the first method has an [@param] tag documenting the type, name and description of the parameter being passed to the method. Additionally it has the [@return] and [@throws] tags for documenting the return type, and @@ -78,7 +77,6 @@ results in the same (no return) action. [PHPDoc manual]: http://www.phpdoc.org/docs/latest/index.html [@author]: http://www.phpdoc.org/docs/latest/references/phpdoc/tags/author.html [@link]: http://www.phpdoc.org/docs/latest/references/phpdoc/tags/link.html -[@package]: http://www.phpdoc.org/docs/latest/references/phpdoc/tags/package.html [@param]: http://www.phpdoc.org/docs/latest/references/phpdoc/tags/param.html [@return]: http://www.phpdoc.org/docs/latest/references/phpdoc/tags/return.html [@throws]: http://www.phpdoc.org/docs/latest/references/phpdoc/tags/throws.html From 4e94aad9b1d44d41a86aea772e0721cb78996cb7 Mon Sep 17 00:00:00 2001 From: Anton Date: Mon, 19 Jan 2015 13:20:36 +0300 Subject: [PATCH 401/843] Update 12-05-01-Building-your-Application.md --- _posts/12-05-01-Building-your-Application.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_posts/12-05-01-Building-your-Application.md b/_posts/12-05-01-Building-your-Application.md index a994958b0..0e009d333 100644 --- a/_posts/12-05-01-Building-your-Application.md +++ b/_posts/12-05-01-Building-your-Application.md @@ -44,7 +44,7 @@ developers interested in Capistrano. [Chef] is more than a deployment framework, it is a very powerful Ruby based system integration framework that doesn't just deploy your app but can build your whole server environment or virtual boxes. -[Deployer] is a deployment tool written in PHP, it's simple and functional. Deploy your code to all servers you want, it supports deploy via copy, or via VCS (like git), or via rsync. Run your tasks on all your servers, or use our recipes of common tasks for Symfony, Laravel, Zend Framework and Yii. +[Deployer] is a deployment tool written in PHP, it's simple and functional. Run tasks in parallel, atomic deployment, keep servers in consistency. Recipes of common tasks for Symfony, Laravel, Zend Framework and Yii. #### Chef resources for PHP developers: @@ -91,4 +91,4 @@ PHP. [Jenkins]: http://jenkins-ci.org/ [PHPCI]: http://www.phptesting.org/ [Teamcity]: http://www.jetbrains.com/teamcity/ -[Deployer]: http://deployer.in/ \ No newline at end of file +[Deployer]: http://deployer.org/ From 91e959b563650c4cd75d19809e3dc5ec93307162 Mon Sep 17 00:00:00 2001 From: Anton Medvedev Date: Wed, 21 Jan 2015 12:06:40 +0300 Subject: [PATCH 402/843] Update 12-05-01-Building-your-Application.md --- _posts/12-05-01-Building-your-Application.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/12-05-01-Building-your-Application.md b/_posts/12-05-01-Building-your-Application.md index 0e009d333..919c5434c 100644 --- a/_posts/12-05-01-Building-your-Application.md +++ b/_posts/12-05-01-Building-your-Application.md @@ -44,7 +44,7 @@ developers interested in Capistrano. [Chef] is more than a deployment framework, it is a very powerful Ruby based system integration framework that doesn't just deploy your app but can build your whole server environment or virtual boxes. -[Deployer] is a deployment tool written in PHP, it's simple and functional. Run tasks in parallel, atomic deployment, keep servers in consistency. Recipes of common tasks for Symfony, Laravel, Zend Framework and Yii. +[Deployer] is a deployment tool written in PHP, it's simple and functional. Runs tasks in parallel, atomic deployment, keeps consistency between servers. Recipes of common tasks for Symfony, Laravel, Zend Framework and Yii. #### Chef resources for PHP developers: From 0a78e24f3d88e60ffa4ab2cd88c6046da002483b Mon Sep 17 00:00:00 2001 From: Aykut Farsak Date: Thu, 22 Jan 2015 12:00:32 +0200 Subject: [PATCH 403/843] Update 07-03-01-Databases_PDO.md http://php.net/manual/en/function.filter-input.php --- _posts/07-03-01-Databases_PDO.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/07-03-01-Databases_PDO.md b/_posts/07-03-01-Databases_PDO.md index d49e57de0..da20237c1 100644 --- a/_posts/07-03-01-Databases_PDO.md +++ b/_posts/07-03-01-Databases_PDO.md @@ -50,7 +50,7 @@ FROM users` which will delete all of your users! Instead, you should sanitize th prepare('SELECT name FROM users WHERE id = :id'); -$id = filter_input(FILTER_GET, 'id', FILTER_SANITIZE_NUMBER_INT); // <-- filter your data first (see [Data Filtering](#data_filtering)), especially important for INSERT, UPDATE, etc. +$id = filter_input(INPUT_GET, 'id', FILTER_SANITIZE_NUMBER_INT); // <-- filter your data first (see [Data Filtering](#data_filtering)), especially important for INSERT, UPDATE, etc. $stmt->bindParam(':id', $id, PDO::PARAM_INT); // <-- Automatically sanitized for SQL by PDO $stmt->execute(); {% endhighlight %} From a0b56d6c37be391d9bb7163a0a2eb8d242e90d74 Mon Sep 17 00:00:00 2001 From: Phil Sturgeon Date: Thu, 22 Jan 2015 15:01:59 -0500 Subject: [PATCH 404/843] noticable -> noticeable --- pages/The-Basics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/The-Basics.md b/pages/The-Basics.md index 782a734aa..9628b602d 100644 --- a/pages/The-Basics.md +++ b/pages/The-Basics.md @@ -297,7 +297,7 @@ If you are concatenating multiple strings of any type, or interpolate values int results can vary. If you are working with a small number of values, concatenation is minutely faster. With a lot of values, interpolating is minutely faster. -Regardless of what you are doing with strings, none of the types will ever have any noticable impact on your +Regardless of what you are doing with strings, none of the types will ever have any noticeable impact on your application. Trying to rewrite code to use one or the other is always an exercise in futility, so avoid this micro- optimization unless you really understand the meaning and impact of the differences. From d7cca904ea7e49f3aab42c42a7dad268d5e0b063 Mon Sep 17 00:00:00 2001 From: david Date: Sat, 24 Jan 2015 09:49:04 -0800 Subject: [PATCH 405/843] Add DOMDocument UTF-8 stackoverflow link. --- _posts/05-05-01-PHP-and-UTF8.md | 1 + 1 file changed, 1 insertion(+) diff --git a/_posts/05-05-01-PHP-and-UTF8.md b/_posts/05-05-01-PHP-and-UTF8.md index 467e0dfcb..66845106f 100644 --- a/_posts/05-05-01-PHP-and-UTF8.md +++ b/_posts/05-05-01-PHP-and-UTF8.md @@ -150,3 +150,4 @@ header('Content-Type: text/html; charset=UTF-8'); * [Stack Overflow: Best practices in PHP and MySQL with international strings](http://stackoverflow.com/questions/140728/best-practices-in-php-and-mysql-with-international-strings) * [How to support full Unicode in MySQL databases](http://mathiasbynens.be/notes/mysql-utf8mb4) * [Bringing Unicode to PHP with Portable UTF-8](http://www.sitepoint.com/bringing-unicode-to-php-with-portable-utf8/) +* [Stack Overflow: DOMDocument loadHTML does not encode UTF-8 correctly](http://stackoverflow.com/questions/8218230/php-domdocument-loadhtml-not-encoding-utf-8-correctly) From 1aa7d4de8a9ad4b2a0c1817f52a9599136231af1 Mon Sep 17 00:00:00 2001 From: Artem Gordinsky Date: Mon, 26 Jan 2015 09:00:07 +0200 Subject: [PATCH 406/843] Remove a line break inside a PHP version number --- _posts/05-05-01-PHP-and-UTF8.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/_posts/05-05-01-PHP-and-UTF8.md b/_posts/05-05-01-PHP-and-UTF8.md index 66845106f..578656ba4 100644 --- a/_posts/05-05-01-PHP-and-UTF8.md +++ b/_posts/05-05-01-PHP-and-UTF8.md @@ -38,8 +38,7 @@ Explicitly defining the encoding of your strings in every script will save you a Additionally, many PHP functions that operate on strings have an optional parameter letting you specify the character encoding. You should always explicitly indicate UTF-8 when given the option. For example, `htmlentities()` has an -option for character encoding, and you should always specify UTF-8 if dealing with such strings. Note that as of PHP 5. -4.0, UTF-8 is the default encoding for `htmlentities()` and `htmlspecialchars()`. +option for character encoding, and you should always specify UTF-8 if dealing with such strings. Note that as of PHP 5.4.0, UTF-8 is the default encoding for `htmlentities()` and `htmlspecialchars()`. Finally, If you are building an distributed application and cannot be certain that the `mbstring` extension will be enabled, then consider using the [patchwork/utf8] Composer package. This will use `mbstring` if it is available, and From 35069640b8c4d0dae6ddffb220c07725ac616ed0 Mon Sep 17 00:00:00 2001 From: c9s Date: Mon, 26 Jan 2015 23:48:45 +0800 Subject: [PATCH 407/843] Add section for MacPorts --- _posts/01-04-01-Mac-Setup.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/_posts/01-04-01-Mac-Setup.md b/_posts/01-04-01-Mac-Setup.md index 0dceb5e9a..f437efa67 100644 --- a/_posts/01-04-01-Mac-Setup.md +++ b/_posts/01-04-01-Mac-Setup.md @@ -18,6 +18,26 @@ There are multiple ways to install PHP on OS X. At this point, you can install `php53`, `php54`, `php55` or `php56` using the `brew install` command, and switch between them by modifying your `PATH` variable. +### Install PHP via Macports + +The [MacPorts] Project is an open-source community initiative to design an +easy-to-use system for compiling, installing, and upgrading either +command-line, X11 or Aqua based open-source software on the OS X operating +system. + +MacPorts supports pre-compiled binaries, so you don't need to recompile every +dependencies from the source tarball files, it saves your life if you don't +have any package installed on your system. + +At this point, you can install `php53`, `php54`, `php55` or `php56` using the `port install` command, for example: + + sudo port install php54 + sudo port install php55 + +And you can run `select` command to switch your active php: + + sudo port select --set php php55 + ### Install PHP via phpbrew [phpbrew] is a tool for installing and managing multiple PHP versions. This can be really useful if two different @@ -38,6 +58,7 @@ you and tie them all together, but ease of setup comes with a trade-off of flexi [Homebrew]: http://brew.sh/ [Homebrew PHP]: https://github.com/Homebrew/homebrew-php#installation +[MacPorts]: https://www.macports.org/install.php [phpbrew]: https://github.com/phpbrew/phpbrew [mac-compile]: http://php.net/install.macosx.compile [xcode-gcc-substitution]: https://github.com/kennethreitz/osx-gcc-installer From ff3f22a1474b617cfe14a547d024ea2b4b60e814 Mon Sep 17 00:00:00 2001 From: Josh Lockhart Date: Tue, 27 Jan 2015 14:53:01 -0500 Subject: [PATCH 408/843] Update translation list --- _includes/welcome.md | 1 + 1 file changed, 1 insertion(+) diff --git a/_includes/welcome.md b/_includes/welcome.md index 6f9829188..be648d838 100644 --- a/_includes/welcome.md +++ b/_includes/welcome.md @@ -29,6 +29,7 @@ _PHP: The Right Way_ is (or soon will be) translated into many different languag * [Italian](http://it.phptherightway.com/) * [Japanese](http://ja.phptherightway.com) * [Korean](http://wafe.github.io/php-the-right-way/) +* [Persian](http://novid.github.io/php-the-right-way/) * [Polish](http://pl.phptherightway.com/) * [Portuguese](http://br.phptherightway.com/) * [Romanian](https://bgui.github.io/php-the-right-way/) From c2d6b91dc3661e6fe9503ec5e0a4bd0ef8179137 Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Wed, 28 Jan 2015 11:36:40 +0100 Subject: [PATCH 409/843] Add Persian translation to the README --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 2c0dcf574..85dcb279a 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,7 @@ developers know where to find good information! * [Italian](http://it.phptherightway.com) * [Japanese](http://ja.phptherightway.com) * [Korean](http://wafe.github.io/php-the-right-way) +* [Persian](http://novid.github.io/php-the-right-way/) * [Polish](http://pl.phptherightway.com) * [Portuguese](http://br.phptherightway.com) * [Romanian](https://bgui.github.io/php-the-right-way/) From df1174b74c3e936305922f64364ecd3864aed3fa Mon Sep 17 00:00:00 2001 From: Justinas Date: Sat, 31 Jan 2015 14:41:36 +0200 Subject: [PATCH 410/843] Zend standards url fixed. --- _posts/02-01-01-Code-Style-Guide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/02-01-01-Code-Style-Guide.md b/_posts/02-01-01-Code-Style-Guide.md index dbd7a498f..27d165711 100644 --- a/_posts/02-01-01-Code-Style-Guide.md +++ b/_posts/02-01-01-Code-Style-Guide.md @@ -46,7 +46,7 @@ readable by all current and future parties who may be working on the codebase. [psr2]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md [psr4]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader.md [pear-cs]: http://pear.php.net/manual/en/standards.php -[zend-cs]: http://framework.zend.com/wiki/display/ZFDEV2/Coding+Standards +[zend-cs]: http://framework.zend.com/manual/1.12/en/coding-standard.html [symfony-cs]: http://symfony.com/doc/current/contributing/code/standards.html [phpcs]: http://pear.php.net/package/PHP_CodeSniffer/ [st-cs]: https://github.com/benmatselby/sublime-phpcs From c31603c7e5eab1e38a1a1555e2aae7fc5b466d1f Mon Sep 17 00:00:00 2001 From: Ryan Nickel Date: Sun, 1 Feb 2015 14:28:32 -0500 Subject: [PATCH 411/843] typo fixed --- pages/Design-Patterns.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/Design-Patterns.md b/pages/Design-Patterns.md index 231eccc11..1e0e42468 100644 --- a/pages/Design-Patterns.md +++ b/pages/Design-Patterns.md @@ -249,7 +249,7 @@ $data = $client->loadOutput(); ## Front Controller -The front controller pattern is where you have a single entrance point for you web application (e.g. index.php) that +The front controller pattern is where you have a single entrance point for your web application (e.g. index.php) that handles all of the requests. This code is responsible for loading all of the dependencies, processing the request and sending the response to the browser. The front controller pattern can be beneficial because it encourages modular code and gives you a central place to hook in code that should be run for every request (such as input sanitization). From 04af8249b64981dcb8acab5c5aaeccb2fcc2365b Mon Sep 17 00:00:00 2001 From: Phil Sturgeon Date: Tue, 3 Feb 2015 13:06:03 -0500 Subject: [PATCH 412/843] Update 06-05-01-Further-Reading.md --- _posts/06-05-01-Further-Reading.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/06-05-01-Further-Reading.md b/_posts/06-05-01-Further-Reading.md index 6a8aee36b..dd18d1c9f 100644 --- a/_posts/06-05-01-Further-Reading.md +++ b/_posts/06-05-01-Further-Reading.md @@ -7,6 +7,6 @@ anchor: further_reading * [Learning about Dependency Injection and PHP](http://ralphschindler.com/2011/05/18/learning-about-dependency-injection-and-php) * [What is Dependency Injection?](http://fabien.potencier.org/article/11/what-is-dependency-injection) -* [Dependency Injection: An analogy](http://mwop.net/blog/260-Dependency-Injection-An-analogy.html) +* [Dependency Injection: An analogy](https://mwop.net/blog/260-Dependency-Injection-An-analogy.html) * [Dependency Injection: Huh?](http://net.tutsplus.com/tutorials/php/dependency-injection-huh/) * [Dependency Injection as a tool for testing](http://philipobenito.github.io/dependency-injection-as-a-tool-for-testing/) From 5fb45d0c22d2f59205901ff36101f6efec5d51c8 Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Fri, 6 Feb 2015 08:24:05 +0100 Subject: [PATCH 413/843] Update Korean translations links --- README.md | 2 +- _includes/welcome.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 85dcb279a..75423180c 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ developers know where to find good information! * [Indonesian](http://id.phptherightway.com) * [Italian](http://it.phptherightway.com) * [Japanese](http://ja.phptherightway.com) -* [Korean](http://wafe.github.io/php-the-right-way) +* [Korean](http://modernpug.github.io/php-the-right-way) * [Persian](http://novid.github.io/php-the-right-way/) * [Polish](http://pl.phptherightway.com) * [Portuguese](http://br.phptherightway.com) diff --git a/_includes/welcome.md b/_includes/welcome.md index 8828773a9..5f047f4f8 100644 --- a/_includes/welcome.md +++ b/_includes/welcome.md @@ -29,7 +29,7 @@ _PHP: The Right Way_ is translated into many different languages: * [Indonesian](http://id.phptherightway.com/) * [Italian](http://it.phptherightway.com/) * [Japanese](http://ja.phptherightway.com) -* [Korean](http://wafe.github.io/php-the-right-way/) +* [Korean](http://modernpug.github.io/php-the-right-way/) * [Persian](http://novid.github.io/php-the-right-way/) * [Polish](http://pl.phptherightway.com/) * [Portuguese](http://br.phptherightway.com/) From 8752d37f937ac8c02229fa72862e2157c405521c Mon Sep 17 00:00:00 2001 From: Alexandru Guzinschi Date: Mon, 9 Feb 2015 11:06:34 +0200 Subject: [PATCH 414/843] Changed Deployer link to Github repo Deployer link now points to their Github repository. --- _posts/12-05-01-Building-your-Application.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/12-05-01-Building-your-Application.md b/_posts/12-05-01-Building-your-Application.md index 919c5434c..f15737137 100644 --- a/_posts/12-05-01-Building-your-Application.md +++ b/_posts/12-05-01-Building-your-Application.md @@ -91,4 +91,4 @@ PHP. [Jenkins]: http://jenkins-ci.org/ [PHPCI]: http://www.phptesting.org/ [Teamcity]: http://www.jetbrains.com/teamcity/ -[Deployer]: http://deployer.org/ +[Deployer]: https://github.com/deployphp/deployer From 59ca83053fffafeeedb5f1f55115ecae8e0e7e96 Mon Sep 17 00:00:00 2001 From: Vladimir Kovpak Date: Wed, 11 Feb 2015 08:00:01 +0200 Subject: [PATCH 415/843] Add example how run phpcs manually from shell. --- _posts/02-01-01-Code-Style-Guide.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/_posts/02-01-01-Code-Style-Guide.md b/_posts/02-01-01-Code-Style-Guide.md index 27d165711..ceab589d4 100644 --- a/_posts/02-01-01-Code-Style-Guide.md +++ b/_posts/02-01-01-Code-Style-Guide.md @@ -36,6 +36,14 @@ stable and used by some huge projects like Magento and Symfony. Another option i popular by the [sublime-phpfmt][sublime-phpfmt] editor plugin. While being newer, it makes great improvements in performance, meaning real-time editor fixing is more fluid. +And you can run phpcs manually from shell: + + phpcs -sw --standard=PSR2 file.php + +It will show errors and descriptions how to fix them. +And it can be very helpful to build own git hook, that will be avoid push branches into your repo that +violate standards. + English is preferred for all symbol names and code infrastructure. Comments may be written in any language easily readable by all current and future parties who may be working on the codebase. From 1b31eeb62608ab718e313b838fbe71784d005953 Mon Sep 17 00:00:00 2001 From: Vladimir Kovpak Date: Wed, 11 Feb 2015 16:01:21 +0200 Subject: [PATCH 416/843] Rephrased example how run phpcs manually from shell. --- _posts/02-01-01-Code-Style-Guide.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/_posts/02-01-01-Code-Style-Guide.md b/_posts/02-01-01-Code-Style-Guide.md index ceab589d4..a3180f59e 100644 --- a/_posts/02-01-01-Code-Style-Guide.md +++ b/_posts/02-01-01-Code-Style-Guide.md @@ -41,8 +41,9 @@ And you can run phpcs manually from shell: phpcs -sw --standard=PSR2 file.php It will show errors and descriptions how to fix them. -And it can be very helpful to build own git hook, that will be avoid push branches into your repo that -violate standards. +It can also be helpful to include this command in a git hook. +That way branches which contain violations against the chosen standard cannot enter the repository +until those violations have been fixed. English is preferred for all symbol names and code infrastructure. Comments may be written in any language easily readable by all current and future parties who may be working on the codebase. From c0d1ca08e7dc8cb3648dc30984975c67a20f4c84 Mon Sep 17 00:00:00 2001 From: Josh Lockhart Date: Thu, 12 Feb 2015 09:45:20 -0500 Subject: [PATCH 417/843] Add Serbian translation link --- README.md | 1 + _includes/welcome.md | 1 + 2 files changed, 2 insertions(+) diff --git a/README.md b/README.md index 75423180c..1e87da0e9 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,7 @@ developers know where to find good information! * [Portuguese](http://br.phptherightway.com) * [Romanian](https://bgui.github.io/php-the-right-way/) * [Russian](http://getjump.github.io/ru-php-the-right-way) +* [Serbian](http://smatejic.github.io/php-the-right-way/) * [Slovenian](http://sl.phptherightway.com) * [Spanish](http://phpdevenezuela.github.io/php-the-right-way) * [Thai](https://apzentral.github.io/php-the-right-way/) diff --git a/_includes/welcome.md b/_includes/welcome.md index 5f047f4f8..36e604784 100644 --- a/_includes/welcome.md +++ b/_includes/welcome.md @@ -35,6 +35,7 @@ _PHP: The Right Way_ is translated into many different languages: * [Portuguese](http://br.phptherightway.com/) * [Romanian](https://bgui.github.io/php-the-right-way/) * [Russian](http://getjump.github.io/ru-php-the-right-way) +* [Serbian](http://smatejic.github.io/php-the-right-way/) * [Slovenian](http://sl.phptherightway.com) * [Spanish](http://phpdevenezuela.github.io/php-the-right-way/) * [Thai](https://apzentral.github.io/php-the-right-way/) From 2a6000a646de34e015e4820ed9d236a6c7f7b413 Mon Sep 17 00:00:00 2001 From: Martin Keckeis Date: Tue, 17 Feb 2015 12:57:38 +0100 Subject: [PATCH 418/843] Some update (see comment) - remove ZF1 cs (since ZF2using now psr) - php-cs-fixer is not "owned" by fabpot anymore --- _posts/02-01-01-Code-Style-Guide.md | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/_posts/02-01-01-Code-Style-Guide.md b/_posts/02-01-01-Code-Style-Guide.md index 27d165711..da559333d 100644 --- a/_posts/02-01-01-Code-Style-Guide.md +++ b/_posts/02-01-01-Code-Style-Guide.md @@ -24,17 +24,13 @@ applications that implement the components can have consistency even when workin * [Read about PSR-2][psr2] * [Read about PSR-4][psr4] * [Read about PEAR Coding Standards][pear-cs] -* [Read about Zend Coding Standards][zend-cs] * [Read about Symfony Coding Standards][symfony-cs] You can use [PHP_CodeSniffer][phpcs] to check code against any one of these recommendations, and plugins for text editors like [Sublime Text 2][st-cs] to be given real time feedback. -You can fix the code layout automatically by using one of the two possible tools. One is Fabien Potencier's -[PHP Coding Standards Fixer][phpcsfixer] which has a very well tested codebase. It is bigger and slower, but very -stable and used by some huge projects like Magento and Symfony. Another option is [php.tools][phptools], which is made -popular by the [sublime-phpfmt][sublime-phpfmt] editor plugin. While being newer, it makes great improvements in -performance, meaning real-time editor fixing is more fluid. +You can fix the code layout automatically by using one of the two following tools. One is the [PHP Coding Standards Fixer][phpcsfixer] which has a very well tested codebase. +Another option is [php.tools][phptools], which is made popular by the [sublime-phpfmt][sublime-phpfmt] editor plugin. While being newer, it makes great improvements in performance, meaning real-time editor fixing is more fluid. English is preferred for all symbol names and code infrastructure. Comments may be written in any language easily readable by all current and future parties who may be working on the codebase. @@ -46,7 +42,6 @@ readable by all current and future parties who may be working on the codebase. [psr2]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md [psr4]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader.md [pear-cs]: http://pear.php.net/manual/en/standards.php -[zend-cs]: http://framework.zend.com/manual/1.12/en/coding-standard.html [symfony-cs]: http://symfony.com/doc/current/contributing/code/standards.html [phpcs]: http://pear.php.net/package/PHP_CodeSniffer/ [st-cs]: https://github.com/benmatselby/sublime-phpcs From 304bbe851c61d95ea11a3ac34e247ad3b227ce6a Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Mon, 2 Mar 2015 18:33:25 +0100 Subject: [PATCH 419/843] Add book Build APIs You Won't Hate and order paid books alphabetically --- _posts/16-10-01-Books.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/_posts/16-10-01-Books.md b/_posts/16-10-01-Books.md index b946a422e..dcc41009a 100644 --- a/_posts/16-10-01-Books.md +++ b/_posts/16-10-01-Books.md @@ -18,14 +18,16 @@ book to be added, send a PR and it will be reviewed for relevancy. ### Paid Books -* [Modernizing Legacy Applications In PHP](https://leanpub.com/mlaphp) - Get your code under control in a series of -small, specific steps +* [Build APIs You Won't Hate](https://leanpub.com/build-apis-you-wont-hate) - Everyone and their dog wants an API, +so you should probably learn how to build them. * [Building Secure PHP Apps](https://leanpub.com/buildingsecurephpapps) - Learn the security basics that a senior developer usually acquires over years of experience, all condensed down into one quick and easy handbook -* [The Grumpy Programmer's Guide To Building Testable PHP Applications](https://leanpub.com/grumpy-testing) - Learning -to write testable doesn't have to suck +* [Modernizing Legacy Applications In PHP](https://leanpub.com/mlaphp) - Get your code under control in a series of +small, specific steps * [Securing PHP: Core Concepts](https://leanpub.com/securingphp-coreconcepts) - A guide to some of the most common security terms and provides some examples of them in every day PHP * [Scaling PHP]( https://leanpub.com/scalingphp) - Stop playing sysadmin and get back to coding * [Signaling PHP]( https://leanpub.com/signalingphp) - PCNLT signals are a great help when writing PHP scripts that run from the command line. +* [The Grumpy Programmer's Guide To Building Testable PHP Applications](https://leanpub.com/grumpy-testing) - Learning +to write testable doesn't have to suck \ No newline at end of file From b52e05c2f804585ece2ede29cda4cca4388b5008 Mon Sep 17 00:00:00 2001 From: Jayin Ton <273942569@qq.com> Date: Tue, 10 Mar 2015 14:35:54 +0800 Subject: [PATCH 420/843] add virtualization_title --- _posts/13-01-01-Virtualization.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/13-01-01-Virtualization.md b/_posts/13-01-01-Virtualization.md index 1c9706f10..f3db51e04 100644 --- a/_posts/13-01-01-Virtualization.md +++ b/_posts/13-01-01-Virtualization.md @@ -2,7 +2,7 @@ anchor: virtualization --- -# Virtualization +# Virtualization {#virtualization_title} Running your application on different environments in development and production can lead to strange bugs popping up when you go live. It's also tricky to keep different development environments up to date with the same version for all From 65d51468dd14584b98af416de0b58560c07e2944 Mon Sep 17 00:00:00 2001 From: Jayin Ton <273942569@qq.com> Date: Tue, 10 Mar 2015 21:20:08 +0800 Subject: [PATCH 421/843] add Video Tutorials anchor --- _posts/16-09-01-Videos.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/_posts/16-09-01-Videos.md b/_posts/16-09-01-Videos.md index d021b2ed1..6d9634137 100644 --- a/_posts/16-09-01-Videos.md +++ b/_posts/16-09-01-Videos.md @@ -4,6 +4,8 @@ anchor: videos title: Video Tutorials --- +## Video Tutorials {#videos} + ### Youtube Channels * [PHP Academy](https://www.youtube.com/user/phpacademy) * [The New Boston](https://www.youtube.com/user/thenewboston) From f054643d170d38c6e60051852323c642ba3939cd Mon Sep 17 00:00:00 2001 From: Ryan Szrama Date: Fri, 13 Mar 2015 10:52:25 +0800 Subject: [PATCH 422/843] Typo fixes in the Programming Paradigms post. --- _posts/03-02-01-Programming-Paradigms.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_posts/03-02-01-Programming-Paradigms.md b/_posts/03-02-01-Programming-Paradigms.md index 772f27c33..f971f3741 100644 --- a/_posts/03-02-01-Programming-Paradigms.md +++ b/_posts/03-02-01-Programming-Paradigms.md @@ -19,9 +19,9 @@ interfaces, inheritance, constructors, cloning, exceptions, and more. ### Functional Programming -PHP supports first-class function, meaning that a function can be assigned to a variable. Both user-defined and +PHP supports first-class functions, meaning that a function can be assigned to a variable. Both user-defined and built-in functions can be referenced by a variable and invoked dynamically. Functions can be passed as arguments to -other functions (a feature called _Higher-order Functions_) and function can return other functions. +other functions (a feature called _Higher-order Functions_) and functions can return other functions. Recursion, a feature that allows a function to call itself, is supported by the language, but most PHP code is focused on iteration. From 6ffa3013994a19f715973c63d7f71b55837bb43b Mon Sep 17 00:00:00 2001 From: Vladimir Kovpak Date: Sun, 15 Mar 2015 01:31:17 +0200 Subject: [PATCH 423/843] Add information about SOLID. --- _posts/06-03-01-Complex-Problem.md | 32 ++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/_posts/06-03-01-Complex-Problem.md b/_posts/06-03-01-Complex-Problem.md index 0d6f9077d..1ab6c1213 100644 --- a/_posts/06-03-01-Complex-Problem.md +++ b/_posts/06-03-01-Complex-Problem.md @@ -22,9 +22,37 @@ instead of loosening dependencies, this method simply moved them. Dependency Injection allows us to more elegantly solve this problem by only injecting the dependencies we need, when we need them, without the need for any hard coded dependencies at all. -### Dependency Inversion Principle +### SOLID -Dependency Inversion Principle is the "D" in the S.O.L.I.D set of object oriented design principles that states one +#### Single responsibility principle + +It's very helpful principle because it improve code reusability and +states that every class should have responsibility over a single part of the functionality provided by the software. +Your class should do just one thing and no more. And you can use it in any place of program without changing it. + +#### Open/closed principle + +States that classes should be open for extension, but closed for modification. +it's very important and helpful especially in production, +because it provides ability to change program behaviour without changing source code. + +#### Liskov substitution principle + +This principle extends previous principle, and states +if S is a subtype of T, then objects of type T in a program may be replaced with objects of type S +without altering any class of the program. +That's amazing principle provides ability to build very flexible and easily configurable programs +because when you change one object to another you don't need to change anything in your program. + +#### Interface segregation principle + +Splits interfaces which are very large into smaller and more specific ones. +It provides to work in each time only with methods that interesting for client, +and facilitate conceptual explanation of the code. + +#### Dependency Inversion Principle + +Dependency Inversion Principle set of object oriented design principles that states one should *"Depend on Abstractions. Do not depend on concretions."*. Put simply, this means our dependencies should be interfaces/contracts or abstract classes rather than concrete implementations. We can easily refactor the above example to follow this principle. From 0171ce6efaa7cc4402baccb1da58576855826088 Mon Sep 17 00:00:00 2001 From: Radek Benkel Date: Sun, 22 Mar 2015 18:53:07 +0100 Subject: [PATCH 424/843] Add Laracasts to Paid Videos It has a a lot of non-Laravel content. --- _posts/16-09-01-Videos.md | 1 + 1 file changed, 1 insertion(+) diff --git a/_posts/16-09-01-Videos.md b/_posts/16-09-01-Videos.md index 6d9634137..35e961b99 100644 --- a/_posts/16-09-01-Videos.md +++ b/_posts/16-09-01-Videos.md @@ -18,3 +18,4 @@ title: Video Tutorials * [PHP Training on Pluralsight](http://www.pluralsight.com/search/?searchTerm=php) * [PHP Training on Lynda.com](http://www.lynda.com/search?q=php) * [PHP Training on Tutsplus](http://code.tutsplus.com/categories/php/courses) +* [Laracasts](https://laracasts.com/) From 8cc828d15eec3a4053fd4175f62e4d5532d4e498 Mon Sep 17 00:00:00 2001 From: Phil Cook Date: Tue, 31 Mar 2015 13:53:58 +0100 Subject: [PATCH 425/843] Add copy and link to brew php switcher Alternative to editing PATH variable and instead use brew php switcher --- _posts/01-04-01-Mac-Setup.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/_posts/01-04-01-Mac-Setup.md b/_posts/01-04-01-Mac-Setup.md index f437efa67..148898e74 100644 --- a/_posts/01-04-01-Mac-Setup.md +++ b/_posts/01-04-01-Mac-Setup.md @@ -16,7 +16,7 @@ There are multiple ways to install PHP on OS X. [Homebrew PHP] is a repository that contains PHP-related "formulae" for Homebrew, and will let you install PHP. At this point, you can install `php53`, `php54`, `php55` or `php56` using the `brew install` command, and switch -between them by modifying your `PATH` variable. +between them by modifying your `PATH` variable. Alternatively you can use [brew-php-switcher][brew-php-switcher] which will switch automatically for you. ### Install PHP via Macports @@ -65,3 +65,4 @@ you and tie them all together, but ease of setup comes with a trade-off of flexi ["Command Line Tools for XCode"]: https://developer.apple.com/downloads [mamp-downloads]: http://www.mamp.info/en/downloads/ [xampp]: http://www.apachefriends.org/en/xampp.html +[brew-php-switcher]: https://github.com/philcook/brew-php-switcher From 1d509e736f6fa38f145b8102230d94a76c4e85fe Mon Sep 17 00:00:00 2001 From: Quim Calpe Date: Fri, 3 Apr 2015 18:45:56 +0200 Subject: [PATCH 426/843] Missing piece Add call to getAllFoos() for clarity --- _posts/07-04-01-Interacting-via-Code.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/_posts/07-04-01-Interacting-via-Code.md b/_posts/07-04-01-Interacting-via-Code.md index 8f2131135..8e3df3de6 100644 --- a/_posts/07-04-01-Interacting-via-Code.md +++ b/_posts/07-04-01-Interacting-via-Code.md @@ -54,7 +54,9 @@ $db = new PDO('mysql:host=localhost;dbname=testdb;charset=utf8', 'username', 'pa include 'models/FooModel.php'; // Create an instance -$fooList = new FooModel($db); +$fooModel = new FooModel($db); +// Get the list of Foos +$fooList = $fooModel->getAllFoos(); // Show the view include 'views/foo-list.php'; From a75e572e5530e2dde8497f44526dd126d303a406 Mon Sep 17 00:00:00 2001 From: Brad Estey Date: Wed, 8 Apr 2015 13:25:53 -0400 Subject: [PATCH 427/843] Fixed class definition typo. --- _posts/07-04-01-Interacting-via-Code.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/07-04-01-Interacting-via-Code.md b/_posts/07-04-01-Interacting-via-Code.md index 8e3df3de6..15bebe975 100644 --- a/_posts/07-04-01-Interacting-via-Code.md +++ b/_posts/07-04-01-Interacting-via-Code.md @@ -67,7 +67,7 @@ include 'views/foo-list.php'; {% highlight php %} Date: Thu, 23 Apr 2015 11:12:44 +0800 Subject: [PATCH 428/843] Update Chinese Simplified translations links --- README.md | 2 +- _includes/welcome.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1e87da0e9..58812d712 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ developers know where to find good information! * [English](http://www.phptherightway.com) * [Bulgarian](http://bg.phptherightway.com) -* [Chinese (Simplified)](http://wulijun.github.com/php-the-right-way) +* [Chinese (Simplified)](http://laravel-china.github.io/php-the-right-way/) * [Chinese (Traditional)](http://laravel-taiwan.github.io/php-the-right-way) * [French](http://eilgin.github.io/php-the-right-way/) * [German](http://rwetzlmayr.github.io/php-the-right-way) diff --git a/_includes/welcome.md b/_includes/welcome.md index 36e604784..7bf439845 100644 --- a/_includes/welcome.md +++ b/_includes/welcome.md @@ -22,7 +22,7 @@ _PHP: The Right Way_ is translated into many different languages: * [English](http://www.phptherightway.com) * [Bulgarian](http://bg.phptherightway.com/) -* [Chinese (Simplified)](http://wulijun.github.com/php-the-right-way) +* [Chinese (Simplified)](http://laravel-china.github.io/php-the-right-way/) * [Chinese (Traditional)](http://laravel-taiwan.github.io/php-the-right-way) * [French](http://eilgin.github.io/php-the-right-way/) * [German](http://rwetzlmayr.github.io/php-the-right-way/) From 063b151a36b8516962ae02167be5ba9ffb98b50f Mon Sep 17 00:00:00 2001 From: Matt Basta Date: Thu, 23 Apr 2015 14:50:22 -0700 Subject: [PATCH 429/843] Add links to Brainy on the Compiled Templates page Brainy is a fork of Smarty that is focused on enhancing Smarty's security and performance. By default, it includes safer security defaults while also bundling features that make it less susceptible to XSS and other types of attacks. --- _posts/08-04-01-Compiled-Templates.md | 3 ++- _posts/08-05-01-Further-Reading.md | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/_posts/08-04-01-Compiled-Templates.md b/_posts/08-04-01-Compiled-Templates.md index d8ed5dc76..5abba92cf 100644 --- a/_posts/08-04-01-Compiled-Templates.md +++ b/_posts/08-04-01-Compiled-Templates.md @@ -6,7 +6,7 @@ anchor: compiled_templates ## Compiled Templates {#compiled_templates_title} While PHP has evolved into a mature, object oriented language, it [hasn't improved much][article_templating_engines] as -a templating language. Compiled templates, like [Twig] or [Smarty]*, fill this void by offering a new syntax that has +a templating language. Compiled templates, like [Twig], [Brainy], or [Smarty]*, fill this void by offering a new syntax that has been geared specifically to templating. From automatic escaping, to inheritance and simplified control structures, compiled templates are designed to be easier to write, cleaner to read and safer to use. Compiled templates can even be shared across different languages, [Mustache] being a good example of this. Since these templates must be compiled @@ -69,5 +69,6 @@ Using the [Twig] library. [article_templating_engines]: http://fabien.potencier.org/article/34/templating-engines-in-php [Twig]: http://twig.sensiolabs.org/ +[Brainy]: https://github.com/box/brainy [Smarty]: http://www.smarty.net/ [Mustache]: http://mustache.github.io/ diff --git a/_posts/08-05-01-Further-Reading.md b/_posts/08-05-01-Further-Reading.md index f042cabeb..7a3a75304 100644 --- a/_posts/08-05-01-Further-Reading.md +++ b/_posts/08-05-01-Further-Reading.md @@ -13,11 +13,13 @@ anchor: templating_further_reading * [Roll Your Own Templating System in PHP](http://code.tutsplus.com/tutorials/roll-your-own-templating-system-in-php--net-16596) * [Master Pages](https://laracasts.com/series/laravel-from-scratch/episodes/7) * [Working With Templates in Symfony 2](http://code.tutsplus.com/tutorials/working-with-templates-in-symfony-2--cms-21172) +* [Writing Safer Templates](https://github.com/box/brainy/wiki/Writing-Safe-Templates) ### Libraries * [Aura.View](https://github.com/auraphp/Aura.View) *(native)* * [Blade](http://laravel.com/docs/templates) *(compiled, framework specific)* +* [Brainy](https://github.com/box/brainy) *(compiled)* * [Dwoo](http://dwoo.org/) *(compiled)* * [Latte](https://github.com/nette/latte) *(compiled)* * [Mustache](https://github.com/bobthecow/mustache.php) *(compiled)* From 12dc0188e14338957d0e024ade299657a6a7b1c6 Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Tue, 2 Jun 2015 18:17:24 +0200 Subject: [PATCH 430/843] elePHPants information added --- _posts/17-04-01-Elephpants.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 _posts/17-04-01-Elephpants.md diff --git a/_posts/17-04-01-Elephpants.md b/_posts/17-04-01-Elephpants.md new file mode 100644 index 000000000..c38883393 --- /dev/null +++ b/_posts/17-04-01-Elephpants.md @@ -0,0 +1,15 @@ +--- +isChild: true +anchor: elephpants +--- + +## ElePHPants {#elephpants_title} + +[ElePHPant][elephpant] is that beautiful mascot of the PHP project with elephant in their design. It was originally designed for the PHP project in 1998 by [Vincent Pontier][vincent-pontier] - spiritual father of thousands of elePHPants around the world and 10 years later adorable plush elephant toy came to birth as well. Now elePHPants are present at many PHP conferences and with many PHP developers at their computers for fun and inspiration. + +[Interview with Vincent Pontier][vincent-pontier-interview] + + +[elephpant]: http://php.net/elephpant.php +[vincent-pontier-interview]: http://7php.com/elephpant/ +[vincent-pontier]: http://www.elroubio.net/ From 790ad2c8aeb44234934c4add2ee2e15b157bc2a9 Mon Sep 17 00:00:00 2001 From: Martin Keckeis Date: Wed, 3 Jun 2015 14:27:34 +0200 Subject: [PATCH 431/843] remove old recommended way of MSI (pre 5.3) --- _posts/01-05-01-Windows-Setup.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/_posts/01-05-01-Windows-Setup.md b/_posts/01-05-01-Windows-Setup.md index 547f8c837..90c81c143 100644 --- a/_posts/01-05-01-Windows-Setup.md +++ b/_posts/01-05-01-Windows-Setup.md @@ -5,8 +5,7 @@ anchor: windows_setup ## Windows Setup {#windows_setup_title} -PHP is available in several ways for Windows. You can [download the binaries][php-downloads] and until recently you -could use a '.msi' installer. The installer is no longer supported and stops at PHP 5.3.0. +You can download the binaries from [windows.php.net/download][php-downloads]. After the extraction of PHP, it is recommended to set the [PATH][windows-path] to the root of your PHP folder (where php.exe is located) so you can execute PHP from anywhere. For learning and local development you can use the built in webserver with PHP 5.4+ so you don't need to worry about configuring it. If you would like an "all-in-one" which includes a full-blown webserver and MySQL too then tools such @@ -20,7 +19,8 @@ FastCGI built in and ready to go, you just need to configure PHP as a handler. F there is a [dedicated area on iis.net][php-iis] for PHP. -[php-downloads]: http://windows.php.net +[php-downloads]: http://windows.php.net/download/ +[windows-path]: http://www.windows-commandline.com/set-path-command-line/ [wpi]: http://www.microsoft.com/web/downloads/platform.aspx [xampp]: http://www.apachefriends.org/en/xampp.html [easyphp]: http://www.easyphp.org/ From c21e464118e0e6f3a092f8c26cbf2a60c2e821fc Mon Sep 17 00:00:00 2001 From: David Lim Date: Tue, 9 Jun 2015 12:26:46 -0700 Subject: [PATCH 432/843] Added missing word Added a missing word to the description about The Grumpy Programmer's Guide To Building Testable PHP Applications --- _posts/16-10-01-Books.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/16-10-01-Books.md b/_posts/16-10-01-Books.md index dcc41009a..6ad76a622 100644 --- a/_posts/16-10-01-Books.md +++ b/_posts/16-10-01-Books.md @@ -30,4 +30,4 @@ security terms and provides some examples of them in every day PHP * [Signaling PHP]( https://leanpub.com/signalingphp) - PCNLT signals are a great help when writing PHP scripts that run from the command line. * [The Grumpy Programmer's Guide To Building Testable PHP Applications](https://leanpub.com/grumpy-testing) - Learning -to write testable doesn't have to suck \ No newline at end of file +to write testable code doesn't have to suck From d7eac31fa7b1242c3965ade1ed475876849946e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Mo=CC=88ller?= Date: Sat, 4 Jul 2015 19:30:09 -0400 Subject: [PATCH 433/843] Fix: Zero is zero, unit doesn't matter --- styles/base/spacing.less | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/styles/base/spacing.less b/styles/base/spacing.less index 9ebff3cef..59c164e6c 100644 --- a/styles/base/spacing.less +++ b/styles/base/spacing.less @@ -22,7 +22,7 @@ */ .ptn, .pvn, .pan{ - padding-top: 0px !important + padding-top: 0 !important } .pth, .pvh, .pah{ padding-top: @baseline / 2 !important @@ -34,7 +34,7 @@ padding-top: @baseline * 2 !important } .prn, .phn, .pan{ - padding-right: 0px !important + padding-right: 0 !important } .prh, .phh, .pah{ padding-right: @baseline / 2 !important @@ -46,7 +46,7 @@ padding-right: @baseline * 2 !important } .pbn, .pvn, .pan{ - padding-bottom: 0px !important + padding-bottom: 0 !important } .pbh, .pvh, .pah{ padding-bottom: @baseline / 2 !important @@ -58,7 +58,7 @@ padding-bottom: @baseline * 2 !important } .pln, .phn, .pan{ - padding-left: 0px !important + padding-left: 0 !important } .plh, .phh, .pah{ padding-left: @baseline / 2 !important @@ -70,7 +70,7 @@ padding-left: @baseline * 2 !important } .mtn, .mvn, .man{ - margin-top: 0px !important + margin-top: 0 !important } .mth, .mvh, .mah{ margin-top: @baseline / 2 !important @@ -82,7 +82,7 @@ margin-top: @baseline * 2 !important } .mrn, .mhn, .man{ - margin-right: 0px !important + margin-right: 0 !important } .mrh, .mhh, .mah{ margin-right: @baseline / 2 !important @@ -94,7 +94,7 @@ margin-right: @baseline * 2 !important } .mbn, .mvn, .man{ - margin-bottom: 0px !important + margin-bottom: 0 !important } .mbh, .mvh, .mah{ margin-bottom: @baseline / 2 !important @@ -106,7 +106,7 @@ margin-bottom: @baseline * 2 !important } .mln, .mhn, .man{ - margin-left: 0px !important + margin-left: 0 !important } .mlh, .mhh, .mah{ margin-left: @baseline / 2 !important @@ -127,5 +127,5 @@ line-height: @baseline * 2 !important; } .lhn { - line-height: 0px !important; -} \ No newline at end of file + line-height: 0 !important; +} From 7c6cb1653b8516f1cdacee09fec2a1324c7f035d Mon Sep 17 00:00:00 2001 From: Phil Sturgeon Date: Mon, 20 Jul 2015 13:36:42 +0100 Subject: [PATCH 434/843] Updated Zend Optimizer+ link (Zend Server moved) --- _posts/14-02-01-Opcode-Cache.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_posts/14-02-01-Opcode-Cache.md b/_posts/14-02-01-Opcode-Cache.md index c4be0b191..063d54bd8 100644 --- a/_posts/14-02-01-Opcode-Cache.md +++ b/_posts/14-02-01-Opcode-Cache.md @@ -29,6 +29,6 @@ Read more about opcode caches: [opcache-book]: http://php.net/book.opcache [APC]: http://php.net/book.apc [XCache]: http://xcache.lighttpd.net/ -[Zend Optimizer+]: http://www.zend.com/products/server/ +[Zend Optimizer+]: http://www.zend.com/en/products/zend_server [WinCache]: http://www.iis.net/download/wincacheforphp -[PHP_accelerators]: http://en.wikipedia.org/wiki/List_of_PHP_accelerators \ No newline at end of file +[PHP_accelerators]: http://en.wikipedia.org/wiki/List_of_PHP_accelerators From 9733ef45ee22a4cf7dff72fdcb0fe8ee6e4f9298 Mon Sep 17 00:00:00 2001 From: Claudio Galdiolo Date: Thu, 20 Aug 2015 23:06:09 -0400 Subject: [PATCH 435/843] mysql extension removed as of PHP 7.0.0 --- _posts/07-02-01-Databases_MySQL.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/_posts/07-02-01-Databases_MySQL.md b/_posts/07-02-01-Databases_MySQL.md index 362cd88cd..e451a691e 100644 --- a/_posts/07-02-01-Databases_MySQL.md +++ b/_posts/07-02-01-Databases_MySQL.md @@ -6,10 +6,10 @@ anchor: mysql_extension ## MySQL Extension {#mysql_extension_title} -The [mysql] extension for PHP is no longer in active development, and is [officially deprecated as of PHP 5.5.0] -[mysql_deprecated], meaning that it will be removed within the next few releases. If you are using any functions that +The [mysql] extension for PHP is no longer in active development, is [deprecated as of PHP 5.5.0] +[mysql_deprecated], and has been [officially removed as of PHP 7.0.0][mysql_removed]. If you are using any functions that start with `mysql_*` such as `mysql_connect()` and `mysql_query()` in your applications then these will simply not be -available in later versions of PHP. This means you will be faced with a rewrite at some point down the line, so the +available in PHP 7.0.0. This means you will be faced with a rewrite at some point down the line, so the best option is to replace mysql usage with [mysqli] or [PDO] in your applications within your own development schedules so you won't be rushed later on. @@ -22,6 +22,7 @@ or use [PDO].** [mysql]: http://php.net/mysql [mysql_deprecated]: http://php.net/migration55.deprecated +[mysql_removed]: http://php.net/manual/en/migration70.removed-exts-sapis.php [mysqli]: http://php.net/mysqli [pdo]: http://php.net/pdo [mysql_api]: http://php.net/mysqlinfo.api.choosing From fb6c170374867a71d4be0f129a72347b0e143a34 Mon Sep 17 00:00:00 2001 From: Claudio Galdiolo Date: Tue, 25 Aug 2015 12:37:10 -0400 Subject: [PATCH 436/843] fix grammatical error --- _posts/07-02-01-Databases_MySQL.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/07-02-01-Databases_MySQL.md b/_posts/07-02-01-Databases_MySQL.md index e451a691e..4ef50c68e 100644 --- a/_posts/07-02-01-Databases_MySQL.md +++ b/_posts/07-02-01-Databases_MySQL.md @@ -6,7 +6,7 @@ anchor: mysql_extension ## MySQL Extension {#mysql_extension_title} -The [mysql] extension for PHP is no longer in active development, is [deprecated as of PHP 5.5.0] +The [mysql] extension for PHP is no longer in active development, was [deprecated as of PHP 5.5.0] [mysql_deprecated], and has been [officially removed as of PHP 7.0.0][mysql_removed]. If you are using any functions that start with `mysql_*` such as `mysql_connect()` and `mysql_query()` in your applications then these will simply not be available in PHP 7.0.0. This means you will be faced with a rewrite at some point down the line, so the From 199a6b60837beb35ae0c862718cce3e45f375bbb Mon Sep 17 00:00:00 2001 From: Alina Mackenzie Date: Sun, 30 Aug 2015 15:59:39 -0500 Subject: [PATCH 437/843] Clarify local vs. global Composer installation Since global installion is assumed in later sections, show commands for global installation of Composer. Include note about using `sudo`, if needed. --- _posts/04-02-01-Composer-and-Packagist.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/_posts/04-02-01-Composer-and-Packagist.md b/_posts/04-02-01-Composer-and-Packagist.md index f1f2e4f20..14bb2b2da 100644 --- a/_posts/04-02-01-Composer-and-Packagist.md +++ b/_posts/04-02-01-Composer-and-Packagist.md @@ -14,13 +14,16 @@ 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; 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: +You can install Composer locally (in your current working directory) or globally (e.g. /usr/local/bin, recommended). +Let's assume you want to install Composer globally: {% highlight console %} -curl -s https://getcomposer.org/installer | php +curl -sS https://getcomposer.org/installer | php +mv composer.phar /usr/local/bin/composer {% endhighlight %} +Note: If the above fails due to permissions, run the `mv` line again with `sudo`. + 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 From e0c85f6b2495f2695206c4094295f97c2edf6b4b Mon Sep 17 00:00:00 2001 From: Josh Foskett Date: Thu, 3 Sep 2015 19:01:14 -0500 Subject: [PATCH 438/843] Update link to Blade. --- _posts/08-05-01-Further-Reading.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/08-05-01-Further-Reading.md b/_posts/08-05-01-Further-Reading.md index 7a3a75304..fe805344e 100644 --- a/_posts/08-05-01-Further-Reading.md +++ b/_posts/08-05-01-Further-Reading.md @@ -18,7 +18,7 @@ anchor: templating_further_reading ### Libraries * [Aura.View](https://github.com/auraphp/Aura.View) *(native)* -* [Blade](http://laravel.com/docs/templates) *(compiled, framework specific)* +* [Blade](http://laravel.com/docs/blade) *(compiled, framework specific)* * [Brainy](https://github.com/box/brainy) *(compiled)* * [Dwoo](http://dwoo.org/) *(compiled)* * [Latte](https://github.com/nette/latte) *(compiled)* From 78bd1a7f3d3ec1c995a9741dd4d7fc271940ab84 Mon Sep 17 00:00:00 2001 From: David Stockton Date: Mon, 7 Sep 2015 13:03:00 -0600 Subject: [PATCH 439/843] Grammar fix for PHPBridge mention --- _posts/07-04-01-Interacting-via-Code.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/07-04-01-Interacting-via-Code.md b/_posts/07-04-01-Interacting-via-Code.md index 15bebe975..78d4f4bfb 100644 --- a/_posts/07-04-01-Interacting-via-Code.md +++ b/_posts/07-04-01-Interacting-via-Code.md @@ -94,7 +94,7 @@ This is essentially the same as what most modern frameworks are doing, albeit a need to do all of that every time, but mixing together too much presentation logic and database interaction can be a real problem if you ever want to [unit-test](/#unit-testing) your application. -[PHPBridge] have a great resource called [Creating a Data Class] which covers a very similar topic, and is great for +[PHPBridge] has a great resource called [Creating a Data Class] which covers a very similar topic, and is great for developers just getting used to the concept of interacting with databases. From bbb047ad2d8c72967ca8ce97bf5d76b00a124892 Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Fri, 11 Sep 2015 18:47:25 +0200 Subject: [PATCH 440/843] Add Using Libsodium for PHP Projects book --- _posts/16-10-01-Books.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/_posts/16-10-01-Books.md b/_posts/16-10-01-Books.md index 6ad76a622..6277ddcaf 100644 --- a/_posts/16-10-01-Books.md +++ b/_posts/16-10-01-Books.md @@ -15,6 +15,8 @@ book to be added, send a PR and it will be reviewed for relevancy. ### Free Books * [PHP The Right Way](https://leanpub.com/phptherightway/) - This website is available as a book completely for free. +* [Using Libsodium in PHP Projects](https://paragonie.com/book/pecl-libsodium) - Guide to using Libsodium PHP extension +for modern, secure, and fast cryptography. ### Paid Books From 5808c0f8d470430a153eba2ee494a86371674182 Mon Sep 17 00:00:00 2001 From: Rotimi Ade Date: Thu, 24 Sep 2015 18:48:08 -0600 Subject: [PATCH 441/843] Update 10-02-01-Web-Application-Security.md Added http://phpsecurity.readthedocs.org/en/latest/index.html to the Web Application Security section. --- _posts/10-02-01-Web-Application-Security.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/_posts/10-02-01-Web-Application-Security.md b/_posts/10-02-01-Web-Application-Security.md index 61050dc54..662b3c7f1 100644 --- a/_posts/10-02-01-Web-Application-Security.md +++ b/_posts/10-02-01-Web-Application-Security.md @@ -8,10 +8,11 @@ anchor: 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. +methods to protect yourself against them. This is a must read for the security-conscious developer. [Survive The Deep End: PHP Security][3] by Padraic Brady is also another good web application security guide for PHP. * [Read the OWASP Security Guide][2] [1]: https://www.owasp.org/ [2]: https://www.owasp.org/index.php/Guide_Table_of_Contents +[3]: http://phpsecurity.readthedocs.org/en/latest/index.html From a7e08ea53ae18c405198df90c4f55dea6bdbbae2 Mon Sep 17 00:00:00 2001 From: Josh Lockhart Date: Sun, 27 Sep 2015 19:29:22 -0400 Subject: [PATCH 442/843] Implement redesign first stage --- .gitignore | 1 + Gruntfile.js | 47 +++++ _layouts/default.html | 74 ++++---- _layouts/page.html | 47 +++-- banners.md | 2 +- css/all.css | 354 ++++++++++++++++++++++++++++++++++++++ index.html | 13 +- less/all.less | 389 ++++++++++++++++++++++++++++++++++++++++++ package.json | 10 ++ 9 files changed, 869 insertions(+), 68 deletions(-) create mode 100644 Gruntfile.js create mode 100644 css/all.css create mode 100644 less/all.less create mode 100644 package.json diff --git a/.gitignore b/.gitignore index 460916ba8..0b09c012c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /_site/ *.DS_Store +node_modules diff --git a/Gruntfile.js b/Gruntfile.js new file mode 100644 index 000000000..5953168a1 --- /dev/null +++ b/Gruntfile.js @@ -0,0 +1,47 @@ +module.exports = function(grunt) { + // Project configuration + grunt.initConfig({ + pkg: grunt.file.readJSON('package.json'), + less: { + dist: { + options: { + cleancss: true, + ieCompat: true + }, + files: { + "css/all.css": "less/all.less" + } + } + }, + postcss: { + options: { + map: true, + processors: [ + require('autoprefixer')({ + browsers: ['last 2 versions', 'ie 9'] + }) + ] + }, + dist: { + src: 'css/all.css' + } + }, + watch: { + less: { + files: ['less/**/*.less'], + tasks: ['less:dist', 'postcss:dist'], + options: { + spawn: false + } + } + } + }); + + // Load plugins + grunt.loadNpmTasks('grunt-contrib-less'); + grunt.loadNpmTasks('grunt-contrib-watch'); + grunt.loadNpmTasks('grunt-postcss'); + + // Default task(s) + grunt.registerTask('default', ['less', 'postcss:dist']); +}; diff --git a/_layouts/default.html b/_layouts/default.html index 55a6527cd..391375496 100644 --- a/_layouts/default.html +++ b/_layouts/default.html @@ -12,10 +12,7 @@ - - - - + - From e009ab27d6e09a56064182aed5da6904d9629237 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wilsen=20Hern=C3=A1ndez?= Date: Thu, 30 May 2024 20:23:15 -0400 Subject: [PATCH 800/843] fix: change baseurl --- _config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_config.yml b/_config.yml index f88108076..f4683feeb 100644 --- a/_config.yml +++ b/_config.yml @@ -1,5 +1,5 @@ host: wilsenhc.github.io -baseurl: php-the-right-way +baseurl: /php-the-right-way timezone: America/Caracas highlighter: rouge markdown: kramdown From 4d2d2c27de440129bf9d2eaf68dddc33bac8389b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wilsen=20Hern=C3=A1ndez?= Date: Thu, 30 May 2024 20:36:38 -0400 Subject: [PATCH 801/843] first translations --- _layouts/default.html | 28 ++++++++++++++-------------- _layouts/page.html | 20 ++++++++++---------- index.html | 2 +- 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/_layouts/default.html b/_layouts/default.html index 4bee49169..ddc542754 100644 --- a/_layouts/default.html +++ b/_layouts/default.html @@ -2,16 +2,16 @@ - {% if page.title %}{{ page.title }} - {% endif %}PHP: The Right Way + {% if page.title %}{{ page.title }} - {% endif %}PHP: La Manera Correcta - - + + - + @@ -22,22 +22,22 @@ @@ -69,11 +69,11 @@

      PHP The Right Way