Lorem Ipsum Dolor
A la recherche du
code mort
AFUP, Paris
Agenda
❖ Qu'est-ce que du code mort
❖ Code mort classique en PHP
❖ Supprimer le code mort
Conférencier
❖ Damien Seguy
❖ Exakat CTO
❖ Ik ben een boterham
❖ Analyse statique de code PHP : SCAP
Code mort
❖ Le code jamais utilisé
❖ Les résultats jamais utilisés
❖ Le contraire de :
PHP Fatal error: Uncaught Error: Call to
undefined function foo()
Code mort
<?php
function foo() {}
$y = rand(0, 12);
echo 'two';
?>
if ($y == 2) {
   echo 'deux';
} 
?>
Code mort
<?php 
class A implements B {}
interface B {}
?>
<?php
interface B implementedBy A,B,C {}
class A {}
?>
Il serait beaucoup mieux de pouvoir écrire
Code mort en PHP
❖ Installation de base
❖ 766 fonctions
❖ 92 classes
❖ 1024 constantes
❖ Éviter de compiler 

trop d'extensions
❖ Utilisez disable_functions
Pourquoi faire la chasse ?
❖ Les sources sont plus grandes
❖ Le code est moins maintenable
❖ Le code mort est souvent maintenu
❖ Le code est plus lent
❖ Le code mort grandit au fil dutemps
Pourquoi garder le code mort ?
❖ Personne n'a jamais été viré pour l'avoir gardé
❖ Pourquoi corriger ce qui marche bien
❖ Tous les tests passent pour ce code
❖ D'autres parties du code dépendent de ce code
❖ Le code source croit toujours
❖ On a pas le temps pour ça!
Comment rechercher le code mort?
❖ Identifier du code
❖ Rechercher son utilisation et ses impacts
❖ Retirer chacun un par un
❖ Retirer le code mort
Trois types de code mort
❖ Code mort classique
❖ Code mort à la mode PHP
❖ Code mort structurel
Code mort classique
Mort dans toutes les langues
Code inaccessible
<?php
if (false) {
   print_r($variable);
}
if (0) { 
   // Gros morceau de code
   // fonctionnalité en développem
// code avec bug
} 
?>
❖ Débogage de 

mon grand-père
Code inaccessible
<?php
function foo($bar) {
   for($i = 0; $i < 10; $i++) {
     $bar *= 2;
      
     exit; // ou die
     $bar += 1;
   }
}
?>
❖ Code inaccessible
Code inaccessible
<?php
function foo($bar) {
   for($i = 0; $i < 10; $i++) {
    $bar *= 2;
      
     continue;
     $bar += 1;
   }
}
?>
❖ Code inaccessible
Code inaccessible
<?php
function foo($bar) {
   for($i = 0; $i < 10; $i++) {
     $bar *= 2;
      
     break 1;
     $bar += 1;
   }
}
?>
❖ Code inaccessible
Code inaccessible
<?php
function foo($bar) {
   $bar *= 2;
   
   return $bar;
   $bar += 1;
   return $bar;
}
?>
❖ Code inaccessible
Code inaccessible
<?php
$bar *= 2;
goto END:
$bar += 1;
      
exit; 
end:
print $bar;
?>
❖ Code inaccessible
Unreachable code
<?php
$bar = 2;
goto END;
 
class X {
   const ONE = 1;
}
exit; 
END:
print $bar . X::ONE;
?>
❖ Code inaccessible
❖ Mais pas les 

définitions
Variables inutilisées
<?php 
$uneFois = "Bonjour AFUP";
?>
❖ Les variables mythiques
'utilisées une fois'
❖ 75% des sources contiennent
des variables
❖ Global ou local à un
contexte
❖ Attention aux imports en
masse $_GET/_POST
<?php 
echo $utiliséUneFois;
?>
Variables inutiles
<?php  
function foo() {
  $a = "Bonjour AFUP"; 
  //more code 
  $a = "Bonjour PHP Tour"; 
  //more code
  $a .= " et les autres"; 
}
?>
❖ Variables
uniquement écrites
❖ Dans une fonction
❖ Variables
uniquement lues
sont OK, mais
méritent de
l'attention
Code mort à la mode
PHP
Quelques squelettes dans les placards
Clause default dans switch()
<?php   
switch($x) {   
    case '1' :    
        break;   
    default :    
        break;   
    default :    
        break;   
    case '2' :    
        break;   
}   
❖ PHP 7.0+ : Fatal error
❖ l'ordre des 'case' n'est
pas important
Le cas des cases
❖ Switch() utilise ==
❖ Les valeurs sont transtypées
switch($x) {   
    case 1 :    
        break;   
    case 0+1 :    
        break;   
    case '1' :    
        break;   
    case true :    
        break;   
    case 1.0 :    
        break;   
    case $y :    
        break;   
}   
Les index des tableaux
<?php
$a = [ true  => 1, 
       1.0  => 2, 
       1.1  => 3, 
       4,
       "1.4" => 5,
       2  => 6];
       
print_r($a);
?>
❖ Uniquement int et string
❖ Attention aux mélanges entre les
index fixes et auto-générés.
Array
(
[1] => 3
[2] => 6
[1.4] => 5
)
Le code mort s'exhibe
<?php
try {
   doSomething();
} catch (NotAnException $e) {
} catch (MyExxeption $e) {
} catch (Exception $e) {
} catch (MyException $e) {
}
❖ Classes inexistantes
❖ Non-exceptions
❖ Ordre des exceptions,

de spécifique à
général
❖ Simplement ignorée
Instanceof
❖ La cible est l'espace

de noms courant
<?php
class MaClass {}
$o = new MaClass();
if ($o instanceof MaClass) {
   print "MaClass est trouvéen";
}
?>
Instanceof
❖ La cible est l'espace

de noms courant
❖ Attention à l'ajout

d'espaces de noms
<?php
namespace {
class MyClass {}
}
namespace X {
$o = new MyClass();
if ($o instanceof MyClass) {
    print "Found MyClassn";
}
}
?>
Instanceof
❖ Noms complets

dans les

chaînes
namespace {
class MyClass {}
}
namespace X {
$o = new MyClass();
$a = 'XMyClass';
if ($o instanceof $a) {
    print "Found MyClass with $a
}
}
Typehint
❖ Les typehint ne
sont pas vérifiés
❖ On peut vérifier
les typehint à
l'exécution
<?php
class foo {}
$o = new foo();
function bar(fooo $a) {}
bar($o);
?>
PHP Fatal error: Uncaught TypeError: Argument 1 passed to
bar() must be an instance of fooo, instance of foo given,
Code mort structurel
Fichiers
Constantes
Variables
Functions
Classes
Interfaces
Traits
Synopsis
❖ Définitions
❖ Usage
❖ Quelques pièges inévitables
❖ Appels dynamiques
Structural dead code
Traits
Interfaces
Classes
Functions
Constantes
Fichiers
Traits
<?php
trait t1 {
   use t2;
}
class c {
   use t1;
}
?>
Traits
❖ Utilisées dans les 'use' de classes
❖ Utilisées dans les 'use' de traits
❖ Utilizes dans les appels de
méthode statiques, ou de
propriétés statiques
<?php
trait t1 {
   use t2;
}
class c {
   use t1;
}
?>
Traits
❖ Facile à repérer : appels statique
❖ En espace de noms, avec des alias
❖ Les dépendances locales conduisent

à plus de code mort
<?php 
use t1 as t3;
trait t1 { 
   use t2; 
} 
class c { 
   use t3; 
} 
?>
Traits
<?php
trait t {
   function setName($name) {
     $this->name = $this->normalize($name);
  }
}
class bar {
   use t;
   private $name = 'aucun';
   function normalize($string) {}
}
?>
Interfaces
<?php
interface i2 { }
interface i1 implements i2 { }
class c implements i1 { }
?>
Interfaces
❖ Utilisée dans
❖ les classes
❖ les interfaces
❖ les constante statiques
❖ Les instanceof, catch et type hint
<?php 
interface i2 { const konst = 
interface i1 implements i2 { 
class c implements i1 { } 
echo i2::konst;
?>
Interfaces
❖ Peuvent finir en
chaînes
❖ Peuvent hériter des
parents
<?php 
interface i2 { const konst = 3; 
interface i1 implements i2 { } 
$interfaceName = 'i2';
if ($object instanceof $interfac
echo i1::konst;
?>
Classes
<?php
classes c1  { }
class c2 extends c1 { }
new c2();
?>
Classes
❖ Utilisées dans
❖ Les autres classes
❖ les appels statiques
❖ constantes, propriétés, méthodes
❖ les appels normaux
❖ instanceof, catch, typehint
❖ les instantiations : new
<?php
class c1  { }
class c2 extends c1
new c2();
?>
Classes
❖ new a / new a()
❖ Appels
dynamiques un
peu partout
❖ Gestion des mots
spéciaux : parent,
self, static
<?php
class foo {
   const ONE = 1;
   const TWO = self::ONE + 1;
}
class bar extends foo {
   const THREE = parent::TWO + s
}
$class = 'bar';
$o = new bar;
?>
Classes
❖ Dépendances
circulaires
❖ S'applique aussi
aux traits et aux
interfaces
<?php 
class foo extends bar { 
   const TWO = bar::ONE + 1; 
} 
class bar extends foo { 
   const ONE = bar::ONE;
} 
?>
PHP Fatal error: Class 'bar' not found
Classes
❖ Dépendance
circulaire vicieuse
<?php 
class foo { 
   const ONE = 1; 
   const TWO = bar::ONE + 1; 
} 
class bar { 
   const ONE = foo::TWO;
} 
echo bar::ONE;
PHP Fatal error: Uncaught Error: Cannot declare self-
referencing constant 'foo::TWO' on line 12
❖ Interfaces, traits puis classes
❖ Commencez avec les positions basses, puis les moins
utilisées
Functions
❖ Utilisées dans les appels

de fonction
❖ Dépend des espaces de 

noms, et les alias
❖ Utilises dans les fonctions

natives array_map(),…
<?php
function foo() {}
array_map('foo', $array);
?>
Constantes
❖ Définies avec const, define
❖ Insensible à la casse, parfois
❖ Les constant() dynamiques
❖ Espaces de noms, alias
❖ Utilisées dans les expressions

statiques
❖ Encore des dépendances vicieuses
<?php 
define(ONE, 1, true);
const TWO = ONE + 1; 
$constant = 'TWO';
echo constant($constant
?>
Inclusions
❖ include/require, /_once
❖ new() parce que autoload()
❖ Constantes statiques, propriété statiques, appels de
méthodes statiques
❖ L'ordre est important, car les inclusions s'exécutent
<?php 
include 'file.php';
?>
Comment repérer du code mort
❖ Connaissance du code
❖ lint
❖ Grep / Chercher
❖ Analyse statique
❖ Logs / error_reporting
❖ Tests unitaires
Quand chasser le code mort?
❖ Comme relaxation quotidienne
❖ Ma meilleure journée de 

programmation fut la 

suppression de 200 classes
❖ trigger_error($msg,
E_USER_DEPRECATED) et 

debug_backtrace()
❖ Sentez en vous la puissance du code vivant
Merci!
@exakat
http://www.exakat.io/
http://slideshare.net/dseguy/

A la recherche du code mort