diff --git a/_includes/welcome.md b/_includes/welcome.md index 8e73e69..2e759ae 100644 --- a/_includes/welcome.md +++ b/_includes/welcome.md @@ -1,19 +1,19 @@ # Welcome -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 +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. +_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 +This is a living document and will continue to be updated with more helpful information and examples as they become available. ## Translations @@ -21,15 +21,14 @@ and examples as they become available. _PHP: The Right Way_ is (or soon will be) translated into many different languages: * [English](http://www.phptherightway.com) -* Catalan (Link broken... we're looking into it) -* [Chinese](http://wulijun.github.com/php-the-right-way) +* [Chinese (Simplified)](http://wulijun.github.com/php-the-right-way) * [Japanese](http://ja.phptherightway.com) * [Korean](http://wafe.github.io/php-the-right-way/) -* Italian (Link broken... we're looking into it) +* [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 (Link broken... we're looking into it) +* [Spanish](http://lamaneracorrecta.php.org.ve) * [Ukrainian](http://iflista.github.com/php-the-right-way/) * [Bulgarian](http://bg.phptherightway.com/) * [German](http://rwetzlmayr.github.io/php-the-right-way/) diff --git a/_layouts/default.html b/_layouts/default.html index aeb97c5..863dfa8 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 a3556b9..9c22aab 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); })(); diff --git a/_posts/01-04-01-Mac-Setup.md b/_posts/01-04-01-Mac-Setup.md index c394dea..aa2fa29 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. diff --git a/_posts/01-06-01-Vagrant.md b/_posts/01-06-01-Vagrant.md index c3768a5..4d64f1f 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/ diff --git a/_posts/02-01-01-Code-Style-Guide.md b/_posts/02-01-01-Code-Style-Guide.md index 3cd3fbb..099d09b 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,8 +17,10 @@ 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] 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. @@ -33,9 +35,10 @@ 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 +[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 [phpcs]: http://pear.php.net/package/PHP_CodeSniffer/ [st-cs]: https://github.com/benmatselby/sublime-phpcs [phpcsfixer]: http://cs.sensiolabs.org/ diff --git a/_posts/03-03-01-Namespaces.md b/_posts/03-03-01-Namespaces.md index bc6eed8..23c7280 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 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. * [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/03-06-01-XDebug.md b/_posts/03-06-01-XDebug.md index be511f3..8334b5c 100644 --- a/_posts/03-06-01-XDebug.md +++ b/_posts/03-06-01-XDebug.md @@ -1,4 +1,5 @@ --- +title: XDebug isChild: true --- @@ -30,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] diff --git a/_posts/04-02-01-Composer-and-Packagist.md b/_posts/04-02-01-Composer-and-Packagist.md index fc67e0b..0d45435 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 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. + ### 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 diff --git a/_posts/06-01-01-Dependency-Injection.md b/_posts/06-01-01-Dependency-Injection.md new file mode 100644 index 0000000..e69c4a2 --- /dev/null +++ b/_posts/06-01-01-Dependency-Injection.md @@ -0,0 +1,13 @@ +--- +title: Dependency Injection +--- + +# Dependency Injection {#dependency_injection_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. diff --git a/_posts/06-02-01-Basic-Concept.md b/_posts/06-02-01-Basic-Concept.md new file mode 100644 index 0000000..fb9954b --- /dev/null +++ b/_posts/06-02-01-Basic-Concept.md @@ -0,0 +1,51 @@ +--- +isChild: true +--- + +## Basic Concept {#basic_concept_title} + +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 %} +adapter = new MySqlAdapter; + } +} + +class MysqlAdapter {} +{% endhighlight %} + +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 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. diff --git a/_posts/06-03-01-Complex-Problem.md b/_posts/06-03-01-Complex-Problem.md new file mode 100644 index 0000000..9fd0f21 --- /dev/null +++ b/_posts/06-03-01-Complex-Problem.md @@ -0,0 +1,56 @@ +--- +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. + +### 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. +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 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, +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 +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 0000000..f0e5466 --- /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. 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. +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 0000000..e1d3645 --- /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/) diff --git a/_posts/06-01-01-Databases.md b/_posts/07-01-01-Databases.md similarity index 91% rename from _posts/06-01-01-Databases.md rename to _posts/07-01-01-Databases.md index 5f024fa..17c5e51 100644 --- a/_posts/06-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 %} @@ -69,10 +69,11 @@ 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] +* [Propel][7] * [ZF2 Db][4] * [ZF1 Db][3] @@ -82,7 +83,10 @@ 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 [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 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 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 96% rename from _posts/07-03-01-Exceptions.md rename to _posts/08-03-01-Exceptions.md index f5d68c3..13b3a8d 100644 --- a/_posts/07-03-01-Exceptions.md +++ b/_posts/08-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 %} 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 81% rename from _posts/08-03-01-Password-Hashing.md rename to _posts/09-03-01-Password-Hashing.md index 0bc6bc5..ad82acd 100644 --- a/_posts/08-03-01-Password-Hashing.md +++ b/_posts/09-03-01-Password-Hashing.md @@ -14,16 +14,17 @@ 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 %} -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 %} diff --git a/pages/Design-Patterns.md b/pages/Design-Patterns.md index 4a3fe45..64618c2 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). diff --git a/pages/Functional-Programming.md b/pages/Functional-Programming.md index f9dc9a0..f5eb792 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`