Le code meurt lorsqu'il n'est jamais exécuté, ou qu'il n'est jamais utilisé pour la production finale. Le code meurt tout au long des projects à long terme, et grandit de jour en jour. C'est une partie significative de la dette technique, qui conduit à des pertes de temps, de compréhension. C'est aussi le code le mieux maintenu du dépôt.
Il prend différentes forme, tels que le code inaccessible, les fonctions inutilisées, les conditions redondantes. Il faut alors le repérer, puis identifier tous les usages et les impacts qu'il a avant de le retirer sans provoquer d'erreur spectaculaire. Les outils d'analyse statique sont alors une aide précieuse pour fouiller le code de manière systématique.
4. 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()
7. Code mort en PHP
❖ Installation de base
❖ 766 fonctions
❖ 92 classes
❖ 1024 constantes
❖ Éviter de compiler
trop d'extensions
❖ Utilisez disable_functions
8. 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
9. 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!
10. Comment rechercher le code mort?
❖ Identifier du code
❖ Rechercher son utilisation et ses impacts
❖ Retirer chacun un par un
❖ Retirer le code mort
11. Trois types de code mort
❖ Code mort classique
❖ Code mort à la mode PHP
❖ Code mort structurel
20. 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;
?>
22. Code mort à la mode
PHP
Quelques squelettes dans les placards
23. 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
24. 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;
}
25. 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
)
26. 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
27. Instanceof
❖ La cible est l'espace
de noms courant
<?php
class MaClass {}
$o = new MaClass();
if ($o instanceof MaClass) {
print "MaClass est trouvéen";
}
?>
28. 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";
}
}
?>
29. 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
}
}
30. 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,
35. 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;
}
?>
36. 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;
}
?>
39. 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;
?>
40. 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;
?>
42. 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();
?>
43. 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;
?>
44. 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
47. ❖ Interfaces, traits puis classes
❖ Commencez avec les positions basses, puis les moins
utilisées
48. 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);
?>
49. 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
?>
50. 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';
?>
51. Comment repérer du code mort
❖ Connaissance du code
❖ lint
❖ Grep / Chercher
❖ Analyse statique
❖ Logs / error_reporting
❖ Tests unitaires
52. 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