A general introduction into a compilation of tools, good practices and what to do (or not) regarding good quality coding, while also looking at some of the most popular coding standards available today in the PHP world
Legibility (Better) 7 /** * Checks what to print depending on output * * Prints constant ONE, TWO or another string * depending on the input $number * * @param int $number The number to check * @return boolean Returns always true */ function checkNumber($number) { switch ($number) { case 1: echo ONE; break; case 4: echo TWO; break; default: echo 'not ONE nor TWO'; break; } return true; } // Human readable representation of constants define('ONE', 1); define('TWO', 2); define('FOUR', 9); // CAUTION! Due to BC this one is different! define('FIVE', 5); // Assign and check the number $myNumber = FOUR; checkNumber($myNumber); echo PHP_EOL; code-quality/10-legible-code.php
Testable & flexible code (Better) 10 /* * Another thanks to @jaytaph for your excellent * example of reusable code */ $it = new \DirectoryIterator('.'); // Filter php files $it2 = new \RegexIterator($it, '/\.php$/'); foreach ($it2 as $file) { printf("File: %s".PHP_EOL, $file->getFilename()); } ‣Iterators are testable ‣Also reusable ‣Easy to maintain code-quality/20-testable.php
Compliancy (Bad example) 12 /* * Task: Build an iterator that goes * from 0 to 10 and prints out * the value of the NEXT * iterator */ for ($i = 0; $i < 15; $i++) { printf('Current value: %d'.PHP_EOL, $i); } ‣Prints from 1 to 15 ‣Prints current value instead of next code-quality/30-uncompliant.php
Compliancy (Better) 13 /* * Task: Build an iterator that goes * from 0 to 10 and prints out * the value of the NEXT * iterator */ for ($i = 0; $i < 10; $i++) { printf('Next value: %d'.PHP_EOL, ($i + 1)); } ‣Prints from 1 to 10 ‣Prints next value ‣Everybody happy! code-quality/30-compliant.php
Notes on efficiency ‣ Mr. Eugene Lewis Fordsworthe: "Assumptions is the mother of all screw ups" ‣ Not entirely true, sometimes good stuff comes out from assumptions ‣ Does not apply in the IT sector ‣ Do you want efficient running code? Profile. Period. 16
Comparing both scripts 22 unreal4u-MBP:code-quality$ time php 40-non-efficient.php real 0m0.194s user 0m0.145s sys 0m0.023s unreal4u-MBP:code-quality$ time php 40-efficient.php real 0m0.168s user 0m0.143s sys 0m0.017s
So… what is good code quality? Good definition I stumbled upon: ‣ Legible ‣ Testable ‣ Flexible ‣ Compliant ‣ Economical (Efficient) 25 http://stackoverflow.com/questions/405243/how-do-we-define-code-quality
Code Quality: Documentation Most used documentation system in PHP: PHPDocumentor ‣ Is able to generate technical documentation right from the PHP code ‣ Is also used by almost all IDE's to enable code- and semantic autocompletion ‣ More information: http://www.phpdoc.org 26
Code Quality: Good practices ‣ OOP vs Procedural programming? Go for OOP ‣ Always try to program in English ‣ Don't reinvent the wheel, check packagist.org or search for a native function ‣ Documentation (PHPDocumentor) should be precise and concise 27
Code Quality: Good practices ‣ Use UTF-8 everywhere ‣ Don't hash passwords yourself, use built-in functions! ‣ Adhere to the coding standards ‣ Think ahead before writing code 28
Code quality: Good practices Much more information than I could possibly talk about: ‣ http://www.phptherightway.com/ ‣ https://phpbestpractices.org/ ‣ http://www.php-fig.org ‣ Google "PHP best practices" for more, but trust those that are current 31
Prehistory: ~1997 till 2004 ‣ No really good support for classes ‣ Not very reusable ‣ No coding standards ‣ Frameworks of that time: ‣ NupeCode (2000) ‣ PEAR (1999) ‣ PECL (2003) 33
Medieval: 2004 till 2012≈2013 The golden era of the frameworks ‣ osCommerce (2003, previously known as "The Exchange Project" [2000]) ‣ WordPress (2003) ‣ CakePHP (2005), Symphony (2005) ‣ Zend Framework (2008) ‣ PHPUnit! (15 march 2004) 34
Renaissance: 2012+ ‣ Rebirth of PHP as a language ‣ 2 mayor changes: PHP-Fig and Composer ‣ PHP-Fig (2009): Ground for rules and conventions ‣ Composer (2012): Good quality packages 35 Image credits: Luc Viatour / www.Lucnix.be
To infinity and beyond: ∞+ ‣ In PHP, strict type checking, scalar type hints? ‣ On userland: more PSR standards ‣ WIP: Cache ‣ WIP: Security ‣ WIP: HTTP message interface 36
PHP-Fig ‣ Stands for PHP Framework Interoperability Group ‣ Ways of mayor framework players to play together ‣ Creation of PSR's: PHP Standard Recommendation 38 http://www.php-fig.org
PSR-1 and PSR-2 ‣ Basic Coding Standard and Coding Style Guide, respectively ‣ PSR-2 extends PSR-1: ‣ PSR-1: PHP opening tags, camel-casing, intention of files, etc. ‣ PSR-2: Tabs or spaces, line length, positioning of opening braces, etc. 39
Close look to PSR-1 ‣ Use only ‣ Only UTF-8 without BOM ‣ Files should declare symbols or cause side-effects ‣ Namespaces and classes must follow PSR-0 or PSR-4 40
Close look to PSR-2: General ‣ Code must follow PSR-1 ‣ Code must use 4 spaces for indenting, no tabs ‣ Lines should be 80 characters or less, soft limit on 120, no hard limit 42
Close look to PSR-2: Visibility Visibility must be always declared ‣ abstract and final before visibility ‣ static after 43 abstract class Visibility { /** * Returns a nice greeting */ final protected static function hello() { return 'Hello'; } /** * Returns the world */ public function world() { return 'world'; } } coding-standards/20-visibility.php
Close look to PSR-2: spacing ‣ One blank line after namespace and use statements ‣ Opening and closing braces for methods and classes must go on next line ‣ Control structure keywords must have one space after them ‣ Method and function calls not 44
Example 46 namespace Vendor\Package; use FooInterface; use BarClass as Bar; use OtherVendor\OtherPackage\BazClass; class Foo extends Bar implements FooInterface { public function sampleFunction($a, $b = null) { if ($a === $b) { bar(); } elseif ($a > $b) { $foo->bar($arg1); } else { BazClass::bar($arg2, $arg3); } } final public static function bar() { // method body } } coding-standards/10-psr.php
PSR-0 and PSR-4 ‣ All about autoloading ‣ PSR-4 (Improved Autoloading) replaces PSR-0 (Autoloading Standard) ‣ Was the key to let composer gain momentum 47
Composer ‣ Dependency manager for PHP ‣ Nice little feature: mostly only good quality code can be found ‣ Infinitely better than www.phpclasses.org 48 https://getcomposer.org
Packagist ‣ Simply a web interface for composer ‣ Useful for listing information about a package ‣ Only bad thing? No search by popularity yet :( ‣ https://github.com/composer/packagist/issues/365 49 https://packagist.org
Semantic versioning ‣ Packages will have a common versioning system ‣ Given MAJOR.MINOR.PATCH (v1.2.3), increment: ‣ MAJOR when causing BC ‣ MINOR when adding functionality in backwards-compatible manner ‣ PATCH for bug fixes only ‣ More information: http://semver.org/ 50
Semver example 51 class HelloWorld { public $name; public $age = 0; public function returnString($name, $age = 0) { $this->name = $name; if ($age > 0) { $this->age = $age; } return sprintf('Hello %s, your age is %d', $this->name, $this->age); } } semver/10-semver.php
PHPUnit ‣ Used to avoid BC ‣ Quick and easy ‣ Unit tests must test real specific parts of the application ‣ More about Unit Testing next month! 55 PHPUnit (No logo, sorry)
Other analyzers ‣ PHPLoc: Measures the size and structure of a PHP project ‣ PHP Copy/Paste Detector: Scans for duplicated code ‣ PHP Dead Code Detector: Scans for code no longer in use 56
Scrutinizer ‣ Executes almost all previous seen programs ‣ Integrates with Travis-CI ‣ Very good at explaining things ‣ Nice little badges for you to use! 59 https://scrutinizer-ci.com/
Jenkins ‣ Self-hosted continuous integration server ‣ Very similar to Travis-CI, except that you have to do all the setup and configuration ‣ Lot of options, lots of plugins to do stuff as well 61
Finally: Who am I? ‣ Blog: http://blog.unreal4u.com/ (Spanish) ‣ Rate the talk and comment at: https://joind.in/talk/view/13713 ‣ Please, it's the only way this talk (and others) can be improved ‣ Slides are ready to be downloaded: ‣ http://unreal4u.com/talks/ ‣ https://speakerdeck.com/unreal4u ‣ Code examples: https://github.com/unreal4u/code-quality-talk/ 64