SlideShare uma empresa Scribd logo
1 de 48
Baixar para ler offline
Comment relire du code
pourri sans se fatiguer
AFUP, Paris, 2016
Agenda
Comment appréhender du code
L'analyse statique pour PHP
La session dont vous êtes le héros
Un projet à relire
On ne sait pas ce que ca fait
On ne l'a jamais vu
On ne l'execute pas
On ne connait pas ses auteurs
Peut-on se former une opinion ?
Comment relire du code?
Relire est humainement possible et artisanal
Les tests unitaires sont peu adaptés à la relecture
L'analyse dynamique est peu adaptée à la relecture
Il faut explorer le code
ne pas se contenter des situations actuelles
Conférencier
Damien Seguy
Exakat CTO
Ik ben een boterham
Analyse statique de code PHP : SCAP
Le code est structuré
Le code est une base de données structurée
Les outils pour l'analyser sont l'analyse statique
Migration PHP 7.0->7.1
IncompatibleNouveautés
PHP LINT
php -l <fichier.php>
Execution parallele :
jakub-onderka/php-paralell-lint
Différentes versions de PHP : 7.0, 7.1, 7.2, 5.6, 5.5
Checked 5982 files in 28.4 seconds
Syntax error found in 4 files
------------------------------------------------------------
Parse error: /vendor2/symfony/symfony/src/Symfony/Component/Validator/Constraints/False.php:22
20| * @api
21| */
> 22| class False extends IsFalse
23| {
24| }
Fatal error: Cannot use 'False' as class name as it is reserved
------------------------------------------------------------
Parse error: /vendor2/symfony/symfony/src/Symfony/Component/Validator/Constraints/Null.php:22
20| * @api
21| */
> 22| class Null extends IsNull
23| {
24| }
Fatal error: Cannot use 'Null' as class name as it is reserved
------------------------------------------------------------
Parse error: /vendor2/symfony/symfony/src/Symfony/Component/Validator/Constraints/True.php:22
20| * @api
21| */
> 22| class True extends IsTrue
23| {
24| }
Fatal error: Cannot use 'True' as class name as it is reserved
------------------------------------------------------------
Parse error: /vendor_user/windid_client/src/windid/service/base/WindidUtility.php:93
91| $imageInfo = @getimagesize($file);
92| $exts = array('1'=>'gif', '2'=>'jpg', '3'=>'png');
> 93| if (!isset($exts[$imageInfo[2]])) continue;
94| $ext = $exts[$imageInfo[2]];
95| $filename = rand(1000,9999). '.'.$ext;
Fatal error: 'continue' not
PHP LINT - 7.0/1/2
Checked 5982 files in 29.7 seconds
Syntax error found in 1 file
------------------------------------------------------------
Parse error: /vendor2/mockery/mockery/tests/Mockery/MockingVariadicArgumentsTest.php
50| abstract class TestWithVariadicArguments
51| {
> 52| public function foo(...$bar)
53| {
54| return $bar;
Unexpected '.', expecting '&' or variable (T_VARIABLE)
PHP LINT - 5.5
PHP LINT - 5.6
Checked 5982 files in 31 seconds
No syntax error found
PHP LINT
Pas compatible avec PHP 7.0 +
Pas compatible avec PHP 5.5-
Utilise Symfony
@getimagesize ? vendor2 ?
5982 fichiers
Calcul de métriques
PHPloc, PHPmetrics, PHP MD
Donne des notes d'ensemble au code
Complexité cyclomatique, nombre de LOC…
PHPLOCDirectories 1143
Files 5982
Size
Lines of Code (LOC) 835199
Comment Lines of Code (CLOC) 252075 (30.18%)
Non-Comment Lines of Code (NCLOC) 583124 (69.82%)
Logical Lines of Code (LLOC) 195283 (23.38%)
Classes 178062 (91.18%)
Average Class Length 29
Minimum Class Length 0
Maximum Class Length 3141
Average Method Length 4
Minimum Method Length 0
Maximum Method Length 879
Functions 1477 (0.76%)
Average Function Length 1
Not in classes or functions 15744 (8.06%)
Cyclomatic Complexity
Average Complexity per LLOC 0.30
Average Complexity per Class 10.82
Minimum Class Complexity 1.00
Maximum Class Complexity 1177.00
Average Complexity per Method 2.65
Minimum Method Complexity 1.00
Maximum Method Complexity 387.00
[...]
PHPLOCDependencies
Global Accesses 2158
Global Constants 1738 (80.54%)
Global Variables 31 (1.44%)
Super-Global Variables 389 (18.03%)
Attribute Accesses 50986
Non-Static 49206 (96.51%)
Static 1780 (3.49%)
Method Calls 113735
Non-Static 103683 (91.16%)
Static 10052 (8.84%)
Structure
Namespaces 851
Interfaces 693
Traits 11
Classes 5245
Abstract Classes 301 (5.74%)
Concrete Classes 4944 (94.26%)
Methods 39581
Scope
Non-Static Methods 37468 (94.66%)
Static Methods 2113 (5.34%)
Visibility
Public Methods 31500 (79.58%)
Non-Public Methods 8081 (20.42%)
Functions 1185
Named Functions 306 (25.82%)
Anonymous Functions 879 (74.18%)
Constants 2658
Global Constants 361 (13.58%)
Class Constants 2297 (86.42%)
PHPMetrics
PHPMetrics
Revue de code automatisée
Relecture du code par une application
regex relit PHP
Extraction de points intéressants
Fonctionnement par mots clé
PHP7cc
php7cc
File: /vendor_user/windid_client/wind/convert/WindGeneralConverter.php
> Line 33: PHP 4 constructors are now deprecated
public function WindGeneralConverter($sourceLang = '', $targetLang = '', $forceTable = false)
{
}
File: /vendor2/symfony/symfony/src/Symfony/Component/Validator/Constraints/Null.php
> Line 22: Reserved name "null" used as a class, interface or trait name
class Null extends SymfonyComponentValidatorConstraintsIsNull
{
}
File: /vendor_user/windid_client/wind/filter/WindHandlerInterceptorChain.php
> Line 61: Function argument(s) returned by "func_get_args" might have been modified
func_get_args();
File: /vendor_user/windid_client/wind/http/session/handler/WindSessionHandler.php
> Line 156: Check that callbacks that are passed to "session_set_save_handler" and return false or -1 (if any) operate
correctly
session_set_save_handler(array($this, 'open'), array($this, 'close'), array($this, 'read'), array($this, 'write'),
array($this, 'destroy'), array($this, 'gc'));
File: /vendor_user/windid_client/wind/security/WindMcryptCbc.php
> Line 31: Removed function "mcrypt_cbc" called
mcrypt_cbc(MCRYPT_DES, $key, $string, MCRYPT_ENCRYPT, $iv);
> Line 49: Removed function "mcrypt_cbc" called
mcrypt_cbc(MCRYPT_DES, $key, $string, MCRYPT_DECRYPT, $iv);
Total : 83 rapports
php7cc
composer require sstale/php7cc
Fonctionne avec des regex et des mots clés
Migration PHP 7
5982 fichiers en 69.275 secondes
Revue de code automatisée
Relecture du code
Extraction de points intéressants
Fonctionnement par AST
PHP7mar, Phan, exakat
Revue de code automatisée
PHP 5 / 7
Calisthenics
ClearPHP
Performance
 
 

AST
<?php
class Foo {
function bar($arg) {
return StrToUpper($arg + 2);
}
}
$foo = new Foo();
$foo->bar(__FILE__);
?>
Sémantique et définitions
PHP7mar : nikic/php5-ast
PHAN : ext/ast (PHP 7 only)
Exakat : AST en base de données
SonarQube : AST maison
PHPstorm : AST interne à l'IDE
Sémantique et définitions
Suppression espaces, commentaires, documentations
Suppression des délimiteurs
( ) { } [ ] " ' ` ; :
Capacité à relier définitions et usage
PHAN
src/Org/OrgBundle/Controller/OrgController.php:12
PhanTypeMismatchArgument Argument 1 (data) is bool but OrgOrgBundleControllerOrgController::createJsonResponse() takes
array defined at src/Topxia/WebBundle/Controller/BaseController.php:120
Total : 13315 résultats
1235 issues
vendor_user/windid_client/wind/mail/protocol/WindPop3.php:186
PhanUndeclaredTypeParameter Parameter of undeclared type baoolean
276 issues
vendor_user/windid_client/wind/base/WindFactory.php:325 

PhanTypeArraySuspicious Suspicious array access to bool
184 issues
vendor2/imagine/imagine/lib/Imagine/Image/AbstractLayers.php:49 

PhanParamSignatureMismatch Declaration of function get($offset) should be compatible with function get(int $offset) :
ImagineImageImageInterface defined in vendor2/imagine/imagine/lib/Imagine/Image/LayersInterface.php:97
src/Classroom/ClassroomBundle/Controller/ClassroomAdminController.php:84 

PhanUndeclaredMethod Call to undeclared method ClassroomClassroomBundleController
ClassroomAdminController::createErrorResponse
1919 issues
808 issues
PHAN
[PhanRedefineFunction] => 31
[PhanTypeMismatchForeach] => 31
[PhanUndeclaredClassInstanceof] => 32
[PhanDeprecatedFunction] => 43
[PhanUndeclaredClassConstant] => 49
[PhanUndeclaredTypeProperty] => 60
[PhanParamSignatureMismatchInternal] => 79
[PhanUndeclaredClassCatch] => 94
[PhanParamTooMany] => 101
[PhanUndeclaredFunction] => 102
[PhanTypeMissingReturn] => 126
[PhanStaticCallToNonStatic] => 164
[PhanTypeArraySuspicious] => 184
[PhanTypeMismatchDefault] => 194
[PhanNonClassMethodCall] => 202
[PhanUndeclaredTypeParameter] => 276
[PhanUndeclaredConstant] => 417
[PhanUndeclaredVariable] => 432
[PhanTypeMismatchProperty] => 530
[PhanUndeclaredMethod] => 808
[PhanTypeMismatchArgumentInternal] => 854
[PhanUndeclaredClassMethod] => 1082
[PhanTypeMismatchReturn] => 1236
[PhanTypeMismatchArgument] => 1716
[PhanParamSignatureMismatch] => 1840
[PhanUndeclaredProperty] => 2485
53 analyses
PHAN
src/Classroom/Service/Classroom/Tests/ClassroomReviewServiceTest.php:227
PhanDeprecatedFunction Call to deprecated function
ClassroomServiceClassroomTestsClassroomReviewServiceTest::setExpectedException()
defined at vendor/phpunit/phpunit/src/Framework/TestCase.php:466
43 issues
Avantages PHP 7
Type hint, return type hint, scalaires
Phan comprend les annotations PHPDOC
Le code dynamique reste difficile à analyser
Flow Control diagram
Diagramme de flux de contrôle
Basé sur l'AST, inclut le suivi de la séquence
Outil de base pour RIPS
<?php
    $x = source();
    
    if ($x < 10) {
        $y = $x + 1;
        $x = corrige($y);
    } else {
        $y = $x;
    }
Flow Control Graph
$x = source();
if ($x < 10) 
$y = $x + 1;
$x = corrige($y);
$y = $x;
PHP
Exit
Else
Then
<?php
    $x = source();
    
    if ($x < 10) {
        $y = $x + 1;
        $x = corrige($y);
    } else {
        $y = $x;
    }
Program Dependency Graph
$x = source();
if ($x < 10) 
$y = $x + 1;
$x = corrige($y);
$y = $x;
Depend de $x
Depend de $x
Depend de $y
Depend de $x
Depend de $x
Depend de $x
<?php
    $x = source();
    
    if ($x < 10) {
        $y = $x + 1;
        $x = corrige($y);
    } else {
        $y = $x;
    }
Et PHP dans tout ça?
La majorité des analyses portent sur des concepts
informatiques
Il existe des analyses qui portent sur PHP lui-même
Les pratiques courantes
Les spécificités du langage
Analyses Exakat
function __destruct() { throw …} : 0,5%
substr($a, 2, 4) == 'abc' : 1 %
function foo($a, $a, $a) {} : 1%
!!(expression) : 7%
$a ? $b ? $c : $d : $e ; 20%
foreach($a as &$b) {} : 21%
if (strpos($a, $b)) {} : 51 %
include('file.php') : 51%
Guide de code propre
Bonnes pratiques
maison, PSR, calisthenics, d'autres techno
Les mantras de code
Le manuel
Les guides de migration
PHP
Liste de

fonctionnalités

utilisées
PHP
Liste d'

extensions

utilisées
Et mon application ?
Découvrez les inventaires
Liste des valeurs utilisées dans le code
Liste des entiers, décimaux, chaines, tableaux
Liste de noms de classes, interfaces, variables,
méthodes
Les erreurs
Chaines utilisées

dans les die, exit

et new Exception
Les variables
$orderBy 685
$token 690
$response 721
$paginator 752
$temp 828
$params 891
$value 925
$type 955
$thread 968
$order 982
$member 1042
$classroom 1115
$limit 1222
$start 1320
$currentUser 1334
$userId 1352
$file 1391
$data 1408
$i 1494
$lesson 1504
$sql 1528
$courseId 1626
$key 1716
$fields 2214
$result 2600
$course 2742
$request 3219
$id 3529
$conditions 3870
$user 4505
271 variables utilisées 1 fois
Les classes
OrderServiceTest 2
FileController 2
ClassroomDataTag 2
LiveCourseController 2
UploadFileController 2
NoteController 2
BlockController 2
OrderLogDaoImpl 2
OpenCourseController 2
FileFilter 2
CourseOrderController 2
Member 2
CoinController 2
ThreadServiceTest 3
BaseProcessor 3
MobileController 3
UserController 3
CategoryDaoImpl 3
CourseReviewController 3
TeacherController 3
AlipaySubmit 3
ThreadServiceImpl 3
ThreadPostDaoImpl 3
AlipayNotify 3
ThreadDaoImpl 3
CourseController 5
DefaultController 5
DefaultControllerTest 5
Configuration 6
Les comparaisons
none 9
vip 10
.. 10
yes 10
material 11
coin 11
created 11
teacher 12
closed 12
error 13
1 14
RMB 15
0 16
paid 16
lesson 18
liveOpen 19
trend 19
cloud 19
ok 20
Coin 21
classroom 22
video 25
self 25
testpaper 27
success 32
live 32
course 39
published 43
_empty_ 71
POST 237
Chaines utilisées dans une 

comparaison

$a == 'ok'
On compte juste les b
Pour aller plus loin
Deptrac
Vérifie que les classes restent bien dans leurs
couches
Deptrac traque les dépendances entre classes qui
doivent rester indépendantes
Configuré manuellement
Pour aller plus loin
Le code dynamique
40% du code est en fait statique
Transpilage : https://github.com/jaytaph/Transphpile
PHP inspections : Intégrées à l'éditeur phpStorm
sensio labs insight : SCA pour le framework
Intégrer l'analyse statique dans son IC
Liste des SCAP cités
Deptrac
Exakat
PHP7mar
Phan
PHP Inspections
Phploc
PHPMD
PHP 7 cc
PHPmetrics
RIPS
Transphpile
Edusoho
Merci! https://joind.in/talk/dd616
http://exakat.io/ - @exakat

Mais conteúdo relacionado

Semelhante a Comment relire du code pourri sans se fatiguer

Qualité logicielle
Qualité logicielleQualité logicielle
Qualité logiciellecyrilgandon
 
php2 : formulaire-session-PDO
php2 : formulaire-session-PDOphp2 : formulaire-session-PDO
php2 : formulaire-session-PDOAbdoulaye Dieng
 
Conférence #nwx2014 - Maxime Mauchaussée - Partager du code maintenable et év...
Conférence #nwx2014 - Maxime Mauchaussée - Partager du code maintenable et év...Conférence #nwx2014 - Maxime Mauchaussée - Partager du code maintenable et év...
Conférence #nwx2014 - Maxime Mauchaussée - Partager du code maintenable et év...Normandie Web Xperts
 
Node.js, le pavé dans la mare
Node.js, le pavé dans la mareNode.js, le pavé dans la mare
Node.js, le pavé dans la mareValtech
 
Aspect avec AspectJ
Aspect avec AspectJAspect avec AspectJ
Aspect avec AspectJsimeon
 
Laravel yet another framework
Laravel  yet another frameworkLaravel  yet another framework
Laravel yet another frameworkLAHAXE Arnaud
 
2013 01-08-php-maturite
2013 01-08-php-maturite2013 01-08-php-maturite
2013 01-08-php-maturiteRémi Alvado
 
Cours php & Mysql - 5éme partie
Cours php & Mysql - 5éme partieCours php & Mysql - 5éme partie
Cours php & Mysql - 5éme partiekadzaki
 
La Tooling API, est-ce pour moi ? Bien sûr, viens voir pourquoi !
La Tooling API, est-ce pour moi ? Bien sûr, viens voir pourquoi !La Tooling API, est-ce pour moi ? Bien sûr, viens voir pourquoi !
La Tooling API, est-ce pour moi ? Bien sûr, viens voir pourquoi !Paris Salesforce Developer Group
 
Ecrire et déployer une appli PHP maintenable
Ecrire et déployer une appli PHP maintenableEcrire et déployer une appli PHP maintenable
Ecrire et déployer une appli PHP maintenableChristophe Villeneuve
 
Présentation Javascript à l'ESI (Alger)
Présentation Javascript à l'ESI (Alger)Présentation Javascript à l'ESI (Alger)
Présentation Javascript à l'ESI (Alger)Dr Samir A. ROUABHI
 
Sécurité et Quaité de code PHP
Sécurité et Quaité de code PHPSécurité et Quaité de code PHP
Sécurité et Quaité de code PHPJean-Marie Renouard
 
Soutenance Zend Framework vs Symfony
Soutenance Zend Framework vs SymfonySoutenance Zend Framework vs Symfony
Soutenance Zend Framework vs SymfonyVincent Composieux
 
PHP 7 et Symfony 3
PHP 7 et Symfony 3PHP 7 et Symfony 3
PHP 7 et Symfony 3Eddy RICHARD
 
Mardi gras du 2 juin 2010 : CSIM2
Mardi gras du 2 juin 2010 : CSIM2Mardi gras du 2 juin 2010 : CSIM2
Mardi gras du 2 juin 2010 : CSIM2hortis
 
#J2Code2018 - Mettez du feu à vos applications avec CodeIgniter
#J2Code2018 - Mettez du feu à vos applications avec CodeIgniter#J2Code2018 - Mettez du feu à vos applications avec CodeIgniter
#J2Code2018 - Mettez du feu à vos applications avec CodeIgniterAtsé François-Xavier KOBON
 

Semelhante a Comment relire du code pourri sans se fatiguer (20)

Des tests modernes pour Drupal
Des tests modernes pour DrupalDes tests modernes pour Drupal
Des tests modernes pour Drupal
 
Qualité logicielle
Qualité logicielleQualité logicielle
Qualité logicielle
 
php2 : formulaire-session-PDO
php2 : formulaire-session-PDOphp2 : formulaire-session-PDO
php2 : formulaire-session-PDO
 
Conférence #nwx2014 - Maxime Mauchaussée - Partager du code maintenable et év...
Conférence #nwx2014 - Maxime Mauchaussée - Partager du code maintenable et év...Conférence #nwx2014 - Maxime Mauchaussée - Partager du code maintenable et év...
Conférence #nwx2014 - Maxime Mauchaussée - Partager du code maintenable et év...
 
Node.js, le pavé dans la mare
Node.js, le pavé dans la mareNode.js, le pavé dans la mare
Node.js, le pavé dans la mare
 
Aspect avec AspectJ
Aspect avec AspectJAspect avec AspectJ
Aspect avec AspectJ
 
Laravel yet another framework
Laravel  yet another frameworkLaravel  yet another framework
Laravel yet another framework
 
Paris RailsCamp 2009
Paris RailsCamp 2009Paris RailsCamp 2009
Paris RailsCamp 2009
 
sfPot aop
sfPot aopsfPot aop
sfPot aop
 
2013 01-08-php-maturite
2013 01-08-php-maturite2013 01-08-php-maturite
2013 01-08-php-maturite
 
Cours php & Mysql - 5éme partie
Cours php & Mysql - 5éme partieCours php & Mysql - 5éme partie
Cours php & Mysql - 5éme partie
 
Wygday 2008
Wygday 2008Wygday 2008
Wygday 2008
 
La Tooling API, est-ce pour moi ? Bien sûr, viens voir pourquoi !
La Tooling API, est-ce pour moi ? Bien sûr, viens voir pourquoi !La Tooling API, est-ce pour moi ? Bien sûr, viens voir pourquoi !
La Tooling API, est-ce pour moi ? Bien sûr, viens voir pourquoi !
 
Ecrire et déployer une appli PHP maintenable
Ecrire et déployer une appli PHP maintenableEcrire et déployer une appli PHP maintenable
Ecrire et déployer une appli PHP maintenable
 
Présentation Javascript à l'ESI (Alger)
Présentation Javascript à l'ESI (Alger)Présentation Javascript à l'ESI (Alger)
Présentation Javascript à l'ESI (Alger)
 
Sécurité et Quaité de code PHP
Sécurité et Quaité de code PHPSécurité et Quaité de code PHP
Sécurité et Quaité de code PHP
 
Soutenance Zend Framework vs Symfony
Soutenance Zend Framework vs SymfonySoutenance Zend Framework vs Symfony
Soutenance Zend Framework vs Symfony
 
PHP 7 et Symfony 3
PHP 7 et Symfony 3PHP 7 et Symfony 3
PHP 7 et Symfony 3
 
Mardi gras du 2 juin 2010 : CSIM2
Mardi gras du 2 juin 2010 : CSIM2Mardi gras du 2 juin 2010 : CSIM2
Mardi gras du 2 juin 2010 : CSIM2
 
#J2Code2018 - Mettez du feu à vos applications avec CodeIgniter
#J2Code2018 - Mettez du feu à vos applications avec CodeIgniter#J2Code2018 - Mettez du feu à vos applications avec CodeIgniter
#J2Code2018 - Mettez du feu à vos applications avec CodeIgniter
 

Mais de Damien Seguy

Strong typing @ php leeds
Strong typing  @ php leedsStrong typing  @ php leeds
Strong typing @ php leedsDamien Seguy
 
Strong typing : adoption, adaptation and organisation
Strong typing : adoption, adaptation and organisationStrong typing : adoption, adaptation and organisation
Strong typing : adoption, adaptation and organisationDamien Seguy
 
Top 10 pieges php afup limoges
Top 10 pieges php   afup limogesTop 10 pieges php   afup limoges
Top 10 pieges php afup limogesDamien Seguy
 
Top 10 php classic traps DPC 2020
Top 10 php classic traps DPC 2020Top 10 php classic traps DPC 2020
Top 10 php classic traps DPC 2020Damien Seguy
 
Meilleur du typage fort (AFUP Day, 2020)
Meilleur du typage fort (AFUP Day, 2020)Meilleur du typage fort (AFUP Day, 2020)
Meilleur du typage fort (AFUP Day, 2020)Damien Seguy
 
Top 10 php classic traps confoo
Top 10 php classic traps confooTop 10 php classic traps confoo
Top 10 php classic traps confooDamien Seguy
 
Tout pour se préparer à PHP 7.4
Tout pour se préparer à PHP 7.4Tout pour se préparer à PHP 7.4
Tout pour se préparer à PHP 7.4Damien Seguy
 
Top 10 php classic traps php serbia
Top 10 php classic traps php serbiaTop 10 php classic traps php serbia
Top 10 php classic traps php serbiaDamien Seguy
 
Top 10 php classic traps
Top 10 php classic trapsTop 10 php classic traps
Top 10 php classic trapsDamien Seguy
 
Top 10 chausse trappes
Top 10 chausse trappesTop 10 chausse trappes
Top 10 chausse trappesDamien Seguy
 
Code review workshop
Code review workshopCode review workshop
Code review workshopDamien Seguy
 
Understanding static analysis php amsterdam 2018
Understanding static analysis   php amsterdam 2018Understanding static analysis   php amsterdam 2018
Understanding static analysis php amsterdam 2018Damien Seguy
 
Review unknown code with static analysis php ce 2018
Review unknown code with static analysis   php ce 2018Review unknown code with static analysis   php ce 2018
Review unknown code with static analysis php ce 2018Damien Seguy
 
Everything new with PHP 7.3
Everything new with PHP 7.3Everything new with PHP 7.3
Everything new with PHP 7.3Damien Seguy
 
Php 7.3 et ses RFC (AFUP Toulouse)
Php 7.3 et ses RFC  (AFUP Toulouse)Php 7.3 et ses RFC  (AFUP Toulouse)
Php 7.3 et ses RFC (AFUP Toulouse)Damien Seguy
 
Tout sur PHP 7.3 et ses RFC
Tout sur PHP 7.3 et ses RFCTout sur PHP 7.3 et ses RFC
Tout sur PHP 7.3 et ses RFCDamien Seguy
 
Review unknown code with static analysis php ipc 2018
Review unknown code with static analysis   php ipc 2018Review unknown code with static analysis   php ipc 2018
Review unknown code with static analysis php ipc 2018Damien Seguy
 
Code review for busy people
Code review for busy peopleCode review for busy people
Code review for busy peopleDamien Seguy
 
Static analysis saved my code tonight
Static analysis saved my code tonightStatic analysis saved my code tonight
Static analysis saved my code tonightDamien Seguy
 
Machine learning in php las vegas
Machine learning in php   las vegasMachine learning in php   las vegas
Machine learning in php las vegasDamien Seguy
 

Mais de Damien Seguy (20)

Strong typing @ php leeds
Strong typing  @ php leedsStrong typing  @ php leeds
Strong typing @ php leeds
 
Strong typing : adoption, adaptation and organisation
Strong typing : adoption, adaptation and organisationStrong typing : adoption, adaptation and organisation
Strong typing : adoption, adaptation and organisation
 
Top 10 pieges php afup limoges
Top 10 pieges php   afup limogesTop 10 pieges php   afup limoges
Top 10 pieges php afup limoges
 
Top 10 php classic traps DPC 2020
Top 10 php classic traps DPC 2020Top 10 php classic traps DPC 2020
Top 10 php classic traps DPC 2020
 
Meilleur du typage fort (AFUP Day, 2020)
Meilleur du typage fort (AFUP Day, 2020)Meilleur du typage fort (AFUP Day, 2020)
Meilleur du typage fort (AFUP Day, 2020)
 
Top 10 php classic traps confoo
Top 10 php classic traps confooTop 10 php classic traps confoo
Top 10 php classic traps confoo
 
Tout pour se préparer à PHP 7.4
Tout pour se préparer à PHP 7.4Tout pour se préparer à PHP 7.4
Tout pour se préparer à PHP 7.4
 
Top 10 php classic traps php serbia
Top 10 php classic traps php serbiaTop 10 php classic traps php serbia
Top 10 php classic traps php serbia
 
Top 10 php classic traps
Top 10 php classic trapsTop 10 php classic traps
Top 10 php classic traps
 
Top 10 chausse trappes
Top 10 chausse trappesTop 10 chausse trappes
Top 10 chausse trappes
 
Code review workshop
Code review workshopCode review workshop
Code review workshop
 
Understanding static analysis php amsterdam 2018
Understanding static analysis   php amsterdam 2018Understanding static analysis   php amsterdam 2018
Understanding static analysis php amsterdam 2018
 
Review unknown code with static analysis php ce 2018
Review unknown code with static analysis   php ce 2018Review unknown code with static analysis   php ce 2018
Review unknown code with static analysis php ce 2018
 
Everything new with PHP 7.3
Everything new with PHP 7.3Everything new with PHP 7.3
Everything new with PHP 7.3
 
Php 7.3 et ses RFC (AFUP Toulouse)
Php 7.3 et ses RFC  (AFUP Toulouse)Php 7.3 et ses RFC  (AFUP Toulouse)
Php 7.3 et ses RFC (AFUP Toulouse)
 
Tout sur PHP 7.3 et ses RFC
Tout sur PHP 7.3 et ses RFCTout sur PHP 7.3 et ses RFC
Tout sur PHP 7.3 et ses RFC
 
Review unknown code with static analysis php ipc 2018
Review unknown code with static analysis   php ipc 2018Review unknown code with static analysis   php ipc 2018
Review unknown code with static analysis php ipc 2018
 
Code review for busy people
Code review for busy peopleCode review for busy people
Code review for busy people
 
Static analysis saved my code tonight
Static analysis saved my code tonightStatic analysis saved my code tonight
Static analysis saved my code tonight
 
Machine learning in php las vegas
Machine learning in php   las vegasMachine learning in php   las vegas
Machine learning in php las vegas
 

Comment relire du code pourri sans se fatiguer

  • 1. Comment relire du code pourri sans se fatiguer AFUP, Paris, 2016
  • 2. Agenda Comment appréhender du code L'analyse statique pour PHP La session dont vous êtes le héros
  • 3. Un projet à relire On ne sait pas ce que ca fait On ne l'a jamais vu On ne l'execute pas On ne connait pas ses auteurs Peut-on se former une opinion ?
  • 4. Comment relire du code? Relire est humainement possible et artisanal Les tests unitaires sont peu adaptés à la relecture L'analyse dynamique est peu adaptée à la relecture Il faut explorer le code ne pas se contenter des situations actuelles
  • 5. Conférencier Damien Seguy Exakat CTO Ik ben een boterham Analyse statique de code PHP : SCAP
  • 6. Le code est structuré Le code est une base de données structurée Les outils pour l'analyser sont l'analyse statique
  • 8. PHP LINT php -l <fichier.php> Execution parallele : jakub-onderka/php-paralell-lint Différentes versions de PHP : 7.0, 7.1, 7.2, 5.6, 5.5
  • 9. Checked 5982 files in 28.4 seconds Syntax error found in 4 files ------------------------------------------------------------ Parse error: /vendor2/symfony/symfony/src/Symfony/Component/Validator/Constraints/False.php:22 20| * @api 21| */ > 22| class False extends IsFalse 23| { 24| } Fatal error: Cannot use 'False' as class name as it is reserved ------------------------------------------------------------ Parse error: /vendor2/symfony/symfony/src/Symfony/Component/Validator/Constraints/Null.php:22 20| * @api 21| */ > 22| class Null extends IsNull 23| { 24| } Fatal error: Cannot use 'Null' as class name as it is reserved ------------------------------------------------------------ Parse error: /vendor2/symfony/symfony/src/Symfony/Component/Validator/Constraints/True.php:22 20| * @api 21| */ > 22| class True extends IsTrue 23| { 24| } Fatal error: Cannot use 'True' as class name as it is reserved ------------------------------------------------------------ Parse error: /vendor_user/windid_client/src/windid/service/base/WindidUtility.php:93 91| $imageInfo = @getimagesize($file); 92| $exts = array('1'=>'gif', '2'=>'jpg', '3'=>'png'); > 93| if (!isset($exts[$imageInfo[2]])) continue; 94| $ext = $exts[$imageInfo[2]]; 95| $filename = rand(1000,9999). '.'.$ext; Fatal error: 'continue' not PHP LINT - 7.0/1/2
  • 10. Checked 5982 files in 29.7 seconds Syntax error found in 1 file ------------------------------------------------------------ Parse error: /vendor2/mockery/mockery/tests/Mockery/MockingVariadicArgumentsTest.php 50| abstract class TestWithVariadicArguments 51| { > 52| public function foo(...$bar) 53| { 54| return $bar; Unexpected '.', expecting '&' or variable (T_VARIABLE) PHP LINT - 5.5 PHP LINT - 5.6 Checked 5982 files in 31 seconds No syntax error found
  • 11. PHP LINT Pas compatible avec PHP 7.0 + Pas compatible avec PHP 5.5- Utilise Symfony @getimagesize ? vendor2 ? 5982 fichiers
  • 12. Calcul de métriques PHPloc, PHPmetrics, PHP MD Donne des notes d'ensemble au code Complexité cyclomatique, nombre de LOC…
  • 13. PHPLOCDirectories 1143 Files 5982 Size Lines of Code (LOC) 835199 Comment Lines of Code (CLOC) 252075 (30.18%) Non-Comment Lines of Code (NCLOC) 583124 (69.82%) Logical Lines of Code (LLOC) 195283 (23.38%) Classes 178062 (91.18%) Average Class Length 29 Minimum Class Length 0 Maximum Class Length 3141 Average Method Length 4 Minimum Method Length 0 Maximum Method Length 879 Functions 1477 (0.76%) Average Function Length 1 Not in classes or functions 15744 (8.06%) Cyclomatic Complexity Average Complexity per LLOC 0.30 Average Complexity per Class 10.82 Minimum Class Complexity 1.00 Maximum Class Complexity 1177.00 Average Complexity per Method 2.65 Minimum Method Complexity 1.00 Maximum Method Complexity 387.00 [...]
  • 14. PHPLOCDependencies Global Accesses 2158 Global Constants 1738 (80.54%) Global Variables 31 (1.44%) Super-Global Variables 389 (18.03%) Attribute Accesses 50986 Non-Static 49206 (96.51%) Static 1780 (3.49%) Method Calls 113735 Non-Static 103683 (91.16%) Static 10052 (8.84%) Structure Namespaces 851 Interfaces 693 Traits 11 Classes 5245 Abstract Classes 301 (5.74%) Concrete Classes 4944 (94.26%) Methods 39581 Scope Non-Static Methods 37468 (94.66%) Static Methods 2113 (5.34%) Visibility Public Methods 31500 (79.58%) Non-Public Methods 8081 (20.42%) Functions 1185 Named Functions 306 (25.82%) Anonymous Functions 879 (74.18%) Constants 2658 Global Constants 361 (13.58%) Class Constants 2297 (86.42%)
  • 17. Revue de code automatisée Relecture du code par une application regex relit PHP Extraction de points intéressants Fonctionnement par mots clé PHP7cc
  • 18. php7cc File: /vendor_user/windid_client/wind/convert/WindGeneralConverter.php > Line 33: PHP 4 constructors are now deprecated public function WindGeneralConverter($sourceLang = '', $targetLang = '', $forceTable = false) { } File: /vendor2/symfony/symfony/src/Symfony/Component/Validator/Constraints/Null.php > Line 22: Reserved name "null" used as a class, interface or trait name class Null extends SymfonyComponentValidatorConstraintsIsNull { } File: /vendor_user/windid_client/wind/filter/WindHandlerInterceptorChain.php > Line 61: Function argument(s) returned by "func_get_args" might have been modified func_get_args(); File: /vendor_user/windid_client/wind/http/session/handler/WindSessionHandler.php > Line 156: Check that callbacks that are passed to "session_set_save_handler" and return false or -1 (if any) operate correctly session_set_save_handler(array($this, 'open'), array($this, 'close'), array($this, 'read'), array($this, 'write'), array($this, 'destroy'), array($this, 'gc')); File: /vendor_user/windid_client/wind/security/WindMcryptCbc.php > Line 31: Removed function "mcrypt_cbc" called mcrypt_cbc(MCRYPT_DES, $key, $string, MCRYPT_ENCRYPT, $iv); > Line 49: Removed function "mcrypt_cbc" called mcrypt_cbc(MCRYPT_DES, $key, $string, MCRYPT_DECRYPT, $iv); Total : 83 rapports
  • 19. php7cc composer require sstale/php7cc Fonctionne avec des regex et des mots clés Migration PHP 7 5982 fichiers en 69.275 secondes
  • 20. Revue de code automatisée Relecture du code Extraction de points intéressants Fonctionnement par AST PHP7mar, Phan, exakat
  • 21. Revue de code automatisée PHP 5 / 7 Calisthenics ClearPHP Performance     
  • 22. AST <?php class Foo { function bar($arg) { return StrToUpper($arg + 2); } } $foo = new Foo(); $foo->bar(__FILE__); ?>
  • 23. Sémantique et définitions PHP7mar : nikic/php5-ast PHAN : ext/ast (PHP 7 only) Exakat : AST en base de données SonarQube : AST maison PHPstorm : AST interne à l'IDE
  • 24. Sémantique et définitions Suppression espaces, commentaires, documentations Suppression des délimiteurs ( ) { } [ ] " ' ` ; : Capacité à relier définitions et usage
  • 25. PHAN src/Org/OrgBundle/Controller/OrgController.php:12 PhanTypeMismatchArgument Argument 1 (data) is bool but OrgOrgBundleControllerOrgController::createJsonResponse() takes array defined at src/Topxia/WebBundle/Controller/BaseController.php:120 Total : 13315 résultats 1235 issues vendor_user/windid_client/wind/mail/protocol/WindPop3.php:186 PhanUndeclaredTypeParameter Parameter of undeclared type baoolean 276 issues vendor_user/windid_client/wind/base/WindFactory.php:325 
 PhanTypeArraySuspicious Suspicious array access to bool 184 issues vendor2/imagine/imagine/lib/Imagine/Image/AbstractLayers.php:49 
 PhanParamSignatureMismatch Declaration of function get($offset) should be compatible with function get(int $offset) : ImagineImageImageInterface defined in vendor2/imagine/imagine/lib/Imagine/Image/LayersInterface.php:97 src/Classroom/ClassroomBundle/Controller/ClassroomAdminController.php:84 
 PhanUndeclaredMethod Call to undeclared method ClassroomClassroomBundleController ClassroomAdminController::createErrorResponse 1919 issues 808 issues
  • 26. PHAN [PhanRedefineFunction] => 31 [PhanTypeMismatchForeach] => 31 [PhanUndeclaredClassInstanceof] => 32 [PhanDeprecatedFunction] => 43 [PhanUndeclaredClassConstant] => 49 [PhanUndeclaredTypeProperty] => 60 [PhanParamSignatureMismatchInternal] => 79 [PhanUndeclaredClassCatch] => 94 [PhanParamTooMany] => 101 [PhanUndeclaredFunction] => 102 [PhanTypeMissingReturn] => 126 [PhanStaticCallToNonStatic] => 164 [PhanTypeArraySuspicious] => 184 [PhanTypeMismatchDefault] => 194 [PhanNonClassMethodCall] => 202 [PhanUndeclaredTypeParameter] => 276 [PhanUndeclaredConstant] => 417 [PhanUndeclaredVariable] => 432 [PhanTypeMismatchProperty] => 530 [PhanUndeclaredMethod] => 808 [PhanTypeMismatchArgumentInternal] => 854 [PhanUndeclaredClassMethod] => 1082 [PhanTypeMismatchReturn] => 1236 [PhanTypeMismatchArgument] => 1716 [PhanParamSignatureMismatch] => 1840 [PhanUndeclaredProperty] => 2485 53 analyses
  • 27. PHAN src/Classroom/Service/Classroom/Tests/ClassroomReviewServiceTest.php:227 PhanDeprecatedFunction Call to deprecated function ClassroomServiceClassroomTestsClassroomReviewServiceTest::setExpectedException() defined at vendor/phpunit/phpunit/src/Framework/TestCase.php:466 43 issues
  • 28. Avantages PHP 7 Type hint, return type hint, scalaires Phan comprend les annotations PHPDOC Le code dynamique reste difficile à analyser
  • 29. Flow Control diagram Diagramme de flux de contrôle Basé sur l'AST, inclut le suivi de la séquence Outil de base pour RIPS
  • 32. Program Dependency Graph $x = source(); if ($x < 10)  $y = $x + 1; $x = corrige($y); $y = $x; Depend de $x Depend de $x Depend de $y Depend de $x Depend de $x Depend de $x <?php     $x = source();          if ($x < 10) {         $y = $x + 1;         $x = corrige($y);     } else {         $y = $x;     }
  • 33.
  • 34. Et PHP dans tout ça? La majorité des analyses portent sur des concepts informatiques Il existe des analyses qui portent sur PHP lui-même Les pratiques courantes Les spécificités du langage
  • 35. Analyses Exakat function __destruct() { throw …} : 0,5% substr($a, 2, 4) == 'abc' : 1 % function foo($a, $a, $a) {} : 1% !!(expression) : 7% $a ? $b ? $c : $d : $e ; 20% foreach($a as &$b) {} : 21% if (strpos($a, $b)) {} : 51 % include('file.php') : 51%
  • 36. Guide de code propre Bonnes pratiques maison, PSR, calisthenics, d'autres techno Les mantras de code Le manuel Les guides de migration
  • 39. Et mon application ? Découvrez les inventaires Liste des valeurs utilisées dans le code Liste des entiers, décimaux, chaines, tableaux Liste de noms de classes, interfaces, variables, méthodes
  • 40. Les erreurs Chaines utilisées
 dans les die, exit
 et new Exception
  • 41. Les variables $orderBy 685 $token 690 $response 721 $paginator 752 $temp 828 $params 891 $value 925 $type 955 $thread 968 $order 982 $member 1042 $classroom 1115 $limit 1222 $start 1320 $currentUser 1334 $userId 1352 $file 1391 $data 1408 $i 1494 $lesson 1504 $sql 1528 $courseId 1626 $key 1716 $fields 2214 $result 2600 $course 2742 $request 3219 $id 3529 $conditions 3870 $user 4505 271 variables utilisées 1 fois
  • 42. Les classes OrderServiceTest 2 FileController 2 ClassroomDataTag 2 LiveCourseController 2 UploadFileController 2 NoteController 2 BlockController 2 OrderLogDaoImpl 2 OpenCourseController 2 FileFilter 2 CourseOrderController 2 Member 2 CoinController 2 ThreadServiceTest 3 BaseProcessor 3 MobileController 3 UserController 3 CategoryDaoImpl 3 CourseReviewController 3 TeacherController 3 AlipaySubmit 3 ThreadServiceImpl 3 ThreadPostDaoImpl 3 AlipayNotify 3 ThreadDaoImpl 3 CourseController 5 DefaultController 5 DefaultControllerTest 5 Configuration 6
  • 43. Les comparaisons none 9 vip 10 .. 10 yes 10 material 11 coin 11 created 11 teacher 12 closed 12 error 13 1 14 RMB 15 0 16 paid 16 lesson 18 liveOpen 19 trend 19 cloud 19 ok 20 Coin 21 classroom 22 video 25 self 25 testpaper 27 success 32 live 32 course 39 published 43 _empty_ 71 POST 237 Chaines utilisées dans une 
 comparaison
 $a == 'ok' On compte juste les b
  • 44. Pour aller plus loin Deptrac Vérifie que les classes restent bien dans leurs couches Deptrac traque les dépendances entre classes qui doivent rester indépendantes Configuré manuellement
  • 45. Pour aller plus loin Le code dynamique 40% du code est en fait statique Transpilage : https://github.com/jaytaph/Transphpile PHP inspections : Intégrées à l'éditeur phpStorm sensio labs insight : SCA pour le framework Intégrer l'analyse statique dans son IC
  • 46. Liste des SCAP cités Deptrac Exakat PHP7mar Phan PHP Inspections Phploc PHPMD PHP 7 cc PHPmetrics RIPS Transphpile