Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

PHPcon Poland - Static Analysis of PHP Code – How the Heck did I write so many Bugs?

631 views

Published on

My talk about Static Analysis from PHPcon Poland 2016.

Published in: Software
  • Login to see the comments

PHPcon Poland - Static Analysis of PHP Code – How the Heck did I write so many Bugs?

  1. 1. Static Analysis of PHP Code How the Heck did I write so many Bugs? PHPCon Poland, September 2016 By Rouven Weßling ( ) Ecosystem Developer / Developer Evangelist, Contentful @RouvenWessling photo credit: byWarsaw Kamil Porembiński (license)
  2. 2. A content management developer platform with an API at its core.
  3. 3. What is Static Analysis?
  4. 4. Analysing software without executing it.
  5. 5. Dynamic Analysis xdebug xhprof PHP Analyzer PHP Vulnerability Hunter Assertions
  6. 6. Why use Static Analysis?
  7. 7. Spend less time on unit tests...
  8. 8. ...and code review
  9. 9. class ClientTest extends PHPUnit_Framework_TestCase { public function testGetSynchronizationManager() { $client = new Client('b4c0n73n7fu1', 'cfexampleapi'); $this->assertInstanceOf(Manager::class, $client->getSynchronizationManager()); } }
  10. 10. Easy to integrate in Continuous Integration
  11. 11. Find issues that can not be found through unit tests
  12. 12. PHP 7 Abstract Syntax Tree Scalar Types Strict Types
  13. 13. PHP is dynamic Reflection Variable variables Referencing classes/functions/properties by string
  14. 14. The more static your code is, the easier it's to reason about.
  15. 15. Some tools
  16. 16. phpmd phan phpcs phpunit phploc phpcpd phpsa php7c Coupling Detector Mondrian PHP Assumption PhpCodeAnalyzer PHPCodeFixer php7mar PH Semantic Versioning Checker PHP Inspection PHP lint PHP Depend PhpMetrics PHPCheckstyle PHP Reaper PHP vuln hunter RIPS Parse SonarQube Side Channel Analyzer TaintPHP Deptrac PhpDependencyAnalysis PHP semver checker
  17. 17. phpmd phan phpcs phpunit phploc phpcpd phpsa php7c Coupling Detector Mondrian PHP Assumption PhpCodeAnalyzer PHPCodeFixer php7mar PH Semantic Versioning Checker PHP Inspection PHP lint PHP Depend PhpMetrics PHPCheckstyle PHP Reaper PHP vuln hunter RIPS Parse SonarQube Side Channel Analyzer TaintPHP Deptrac PhpDependencyAnalysis PHP semver checker
  18. 18. phpmd phan phpcs phpunit phploc phpcpd phpsa php7c Coupling Detector Mondrian PHP Assumption PhpCodeAnalyzer PHPCodeFixer php7mar PH Semantic Versioning Checker PHP Inspection PHP lint PHP Depend PhpMetrics PHPCheckstyle PHP Reaper PHP vuln hunter RIPS Parse SonarQube Side Channel Analyzer TaintPHP Deptrac PhpDependencyAnalysis PHP semver checker
  19. 19. phpmd phan phpcs phpunit phploc phpcpd phpsa php7c Coupling Detector Mondrian PHP Assumption PhpCodeAnalyzer PHPCodeFixer php7mar PH Semantic Versioning Checker PHP Inspection PHP lint PHP Depend PhpMetrics PHPCheckstyle PHP Reaper PHP vuln hunter RIPS Parse SonarQube Side Channel Analyzer TaintPHP Deptrac PhpDependencyAnalysis PHP semver checker
  20. 20. phpmd phan phpcs phpunit phploc phpcpd phpsa php7c Coupling Detector Mondrian PHP Assumption PhpCodeAnalyzer PHPCodeFixer php7mar PH Semantic Versioning Checker PHP Inspection PHP lint PHP Depend PhpMetrics PHPCheckstyle PHP Reaper PHP vuln hunter RIPS Parse SonarQube Side Channel Analyzer TaintPHP Deptrac PhpDependencyAnalysis PHP semver checker
  21. 21. phpmd phan phpcs phpunit phploc phpcpd phpsa php7c Coupling Detector Mondrian PHP Assumption PhpCodeAnalyzer PHPCodeFixer php7mar PH Semantic Versioning Checker PHP Inspection PHP lint PHP Depend PhpMetrics PHPCheckstyle PHP Reaper PHP vuln hunter Parse SonarQube Side Channel Analyzer TaintPHP Deptrac PhpDependencyAnalysis PHP semver checker
  22. 22. phpmd phan phpcs phpunit phploc phpcpd phpsa php7c Coupling Detector Mondrian PHP Assumption PhpCodeAnalyzer PHPCodeFixer php7mar PH Semantic Versioning Checker PHP Inspection PHP lint PHP Depend PhpMetrics PHPCheckstyle PHP Reaper PHP vuln hunter Parse SonarQube Side Channel Analyzer TaintPHP Deptrac PhpDependencyAnalysis PHP semver checker
  23. 23. phpmd phan phpcs phpunit phploc phpcpd phpsa PHP Coupling Detector Mondrian PHP Assumption PhpCodeAnalyzer PHPCodeFixer php7mar PH Semantic Versioning Checker PHP Inspection PHP lint PHP Depend PhpMetrics PHPCheckstyle PHP Reaper PHP vuln hunter Parse SonarQube Side Channel Analyzer TaintPHP Deptrac PhpDependencyAnalysis PHP semver checker
  24. 24. PHP lint php -l
  25. 25. Compiles PHP script with the actual PHP compiler It's already installed on your computer Can be used to test compatibility with multiple PHP versions
  26. 26. <?php namespace ContentfulLog use PsrHttpMessageRequestInterface; use PsrHttpMessageResponseInterface; class NullLogger implements LoggerInterface { public function getTimer() { return new NullTimer; } public function log($api, RequestInterface $request, StandardTimer $timer, Respons { } }
  27. 27. PHP 7.0.3 | 10 parallel jobs .................................X...... 40/40 (100 %) Checked 40 files in 0.5 seconds Syntax error found in 1 file ------------------------------------------------------------ Parse error: src/Log/NullLogger.php:9 7| namespace ContentfulLog 8| > 9| use PsrHttpMessageRequestInterface; 10| use PsrHttpMessageResponseInterface; 11| Unexpected 'use' (T_USE), expecting '{'
  28. 28. Make your life easier Use PHP-Parallel-Lint
  29. 29. phploc
  30. 30. Gather stats about your projects Get an idea of the complexity See long term trends
  31. 31. phploc 3.0.1 by Sebastian Bergmann. Directories 6 Files 40 Size Lines of Code (LOC) 5683 Comment Lines of Code (CLOC) 2562 (45.08%) Non-Comment Lines of Code (NCLOC) 3121 (54.92%) Logical Lines of Code (LLOC) 951 (16.73%) Classes 868 (91.27%) Average Class Length 21 Minimum Class Length 0 Maximum Class Length 190 Average Method Length 2 Minimum Method Length 0 Maximum Method Length 25 Functions 0 (0.00%) Average Function Length 0 Not in classes or functions 83 (8.73%)
  32. 32. Cyclomatic Complexity Average Complexity per LLOC 0.28 Average Complexity per Class 7.65 Minimum Class Complexity 1.00 Maximum Class Complexity 62.00 Average Complexity per Method 1.82 Minimum Method Complexity 1.00 Maximum Method Complexity 11.00
  33. 33. If you're getting serious about Cyclomatic Complexity, use phpmd.
  34. 34. Dependencies Global Accesses 0 Global Constants 0 (0.00%) Global Variables 0 (0.00%) Super-Global Variables 0 (0.00%) Attribute Accesses 536 Non-Static 535 (99.81%) Static 1 (0.19%) Method Calls 319 Non-Static 308 (96.55%) Static 11 (3.45%)
  35. 35. Structure Namespaces 7 Interfaces 3 Traits 0 Classes 37 Abstract Classes 3 (8.11%) Concrete Classes 34 (91.89%) Methods 272 Scope Non-Static Methods 272 (100.00%) Static Methods 0 (0.00%) Visibility Public Methods 221 (81.25%) Non-Public Methods 51 (18.75%) Functions 6 Named Functions 0 (0.00%) Anonymous Functions 6 (100.00%) Constants 2 Global Constants 0 (0.00%) Class Constants 2 (100.00%)
  36. 36. Deptrac
  37. 37. Software has layers There should be rules about those layers Rules are easily broken
  38. 38. 1. Define the layers of your architecture 2. Define what layers another layer can access 3. Profit!!!
  39. 39. layers: - name: Controller collectors: - type: className regex: .*Controller.* - name: Entity collectors: - type: className regex: AstaRwthVorkursticketBundleEntity.*
  40. 40. ruleset: Controller: - Service - Entity - Form Service: - Repository Command: - Entity Entity: - Validator
  41. 41. How it works Parses all files in your code Stores which classes access which others classes Checks the graph for rule violations
  42. 42. deptrac is alpha, not production ready. please help us and report feedback / bugs. Start to create an AstMap for 24 Files. ........................ AstMap created. start emitting dependencies "InheritanceDependencyEmitter" start emitting dependencies "BasicDependencyEmitter" end emitting dependencies start flatten dependencies end flatten dependencies collecting violations. formatting dependencies. [...]ServicesPdfOrder::5 must not depend on [...]EntityVorkursticket (Service on Enti [...]ServicesPdfOrder::23 must not depend on [...]EntityVorkursticket (Service on Ent Found 2 Violations
  43. 43. phan
  44. 44. Type safety for PHP Checks docblocks Signature mismatches Unused code
  45. 45. How it works Makes 2 passes over the codebase 1. Build a list of all classes, functions, methods, etc. 2. Go trough each function and follow the type of each variable
  46. 46. /** * @param Locale|string|null $locale * * @return string */ public function getDescription($locale = null) { $localeCode = $this->getLocaleFromInput($locale); // This checks happens after the call to getLocaleFromInput to make sure // the Exception for invalid locales is still thrown. if ($this->description === null) { return null; } return $this->description->$localeCode; } src/Delivery/Asset.php:74 PhanTypeMismatchReturn Returning type null but getDescription() is declared to return string
  47. 47. class ContentType { /** * The fields, keyed by ID. * * @var object */ private $fields = []; } src/Delivery/ContentType.php:34 PhanTypeMismatchProperty Assigning array to property but contentfuldeliverycontenttype::fields is object
  48. 48. public function __call($name, $arguments) { // Lots of code here if ($result instanceof Link) { return $client->resolveLink($result); } return array_map(function ($value) use ($client) { if ($value instanceof Link) { return $client->resolveLink($value); } return $value; }, $result); } src/Delivery/DynamicEntry.php:126 PhanTypeMismatchArgumentInternal Argument 2 (input1) is contentfuldeliverylink but array_map() takes array Not a bug
  49. 49. Don't trust blindly
  50. 50. Bad news? Requires php-ast Not easy to deal with library code Noisy - not easily integrated in CI.
  51. 51. The future
  52. 52. phan is using brute force for type checking Roughly as good as the compiler for a statically typed language Works, but a Control Flow Graph could give even deeper insight
  53. 53. int foo(int length) { int x = 0; for (int i = 0; i < length; i++) x += 1 return length/x; }
  54. 54. Bottom line There are dozens of tools - pick what's necessary for you Make them part of your Continuous Integration setup Never trust. Make sure you understand where the error is coming from.
  55. 55. Slides available on Slideshare: http://www.slideshare.net/rwessling Please leave feedback on joind.in ( ) or tweet me ( ) https://joind.in/talk/8f19b @RouvenWessling

×