The document discusses different types of dead code in PHP applications, including unreachable code, useless variables, PHP-specific issues, and structural dead code. It provides examples of each type and explains how to identify and remove dead code to make code more maintainable and efficient. The speaker is the CTO of Exakat, a company that provides static code analysis for PHP to help find dead and unused code.
4. Dead code
❖ Code that is never used
❖ Data never delivered to the user
❖ Opposite to :
PHP Fatal error: Uncaught Error: Call to
undefined function foo()
7. Dead code
❖ PHP base install
❖ 766 functions
❖ 92 classes
❖ 1024 constants
❖ Avoid compiling too
many PHP extensions
❖ Use disable_functions
8. Why remove?
❖ Larger code source
❖ Less maintainable code
❖ Dead code is often maintained
❖ Slower code
❖ Dead code grows over time
9. Why keep dead code?
❖ No one was ever fired to keep dead code
❖ Why fix something that isn't broken
❖ All tests for this feature are OK
❖ Other part of the code depends on it
❖ Code base always grows organically
❖ No time for that!
10. How to remove dead code
❖ Spot the original code
❖ Check for its usage
❖ Remove usages one by one
❖ Remove the original code
11. 3 types of dead code
❖ Classic dead code
❖ PHP stealth dead code
❖ Structural dead code
23. Default clause in switch()
<?php
switch($x) {
case '1' :
break;
default :
break;
default :
break;
case '2' :
break;
}
❖ PHP 7.0+ : Fatal error
❖ 'case' order is "not"
important
24. Multiple cases ?
❖ Switch() uses ==
❖ Transtyping happens
switch($x) {
case 1 :
break;
case 0+1 :
break;
case '1' :
break;
case true :
break;
case 1.0 :
break;
case $y :
break;
}
25. Arrays index
<?php
$a = [ true => 1,
1.0 => 2,
1.1 => 3,
4,
"1.4" => 5,
2 => 6];
print_r($a);
?>
❖ are int or strings
❖ Beware of mix between
auto-indexing and
fixed values Array
(
[1] => 3
[2] => 6
[1.4] => 5
)
26. Dead code in plain sight
<?php
try {
doSomething();
} catch (NotAnException $e) {
} catch (MyExxeption $e) {
} catch (Exception $e) {
} catch (MyException $e) {
}
❖ Non Existing classes
❖ Non-Exceptions
❖ Specific to general
❖ Simply ignored
27. Instanceof
❖ The target class
is in the current
namespace
<?php
class MyClass {}
$o = new MyClass();
if ($o instanceof MyClass) {
print "Found MyClassn";
}
?>
28. Instanceof
❖ The target class
is in the current
namespace
❖ Beware of moving
classes and
instanceof around
<?php
namespace {
class MyClass {}
}
namespace X {
$o = new MyClass();
if ($o instanceof MyClass) {
print "Found MyClassn";
}
}
?>
29. Instanceof
❖ Hardcoded names
vs
strings classnames
namespace {
class MyClass {}
}
namespace X {
$o = new MyClass();
$a = 'XMyClass';
if ($o instanceof $a) {
print "Found MyClass with $a
}
}
30. Typehint
❖ Typehint are not
checked either
❖ You can check
type hint at
execution time
<?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
❖ Used in class-'use' expression
❖ Depends on 'use' expression
❖ Used in static method call, static
properties
<?php
trait t1 {
use t2;
}
class c {
use t1;
}
?>
36. Traits
❖ Easy to spot : only static calls
❖ Namespaced, aliased
❖ Trait local dependencies leads to
more dead code
<?php
use t1 as t3;
trait t1 {
use t2;
}
class c {
use t3;
}
?>
39. Interfaces
❖ Used in classes
❖ Used in interfaces
❖ Used in static constants
❖ Used in instanceof, catch and type hint
<?php
interface i2 { const konst =
interface i1 implements i2 {
class c implements i1 { }
echo i2::konst;
?>
40. Interfaces
❖ It may end up in
variables/literals
❖ It inherits from
parents
<?php
interface i2 { const konst = 3;
interface i1 implements i2 { }
$interfaceName = 'i2';
if ($object instanceof $interfac
echo i1::konst;
?>
42. Classes
❖ Used in other classes
❖ Used in all static calls
❖ constants, properties, methods
❖ Normal calls ->
❖ Used in instanceof, catch, typehint
❖ Used in new
<?php
class c1 { }
class c2 extends c1
new c2();
?>
43. Classes
❖ new a / new a()
❖ Dynamic calls all
over the place
❖ It has special
keywords : 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
❖ Circular
dependencies
❖ Actually applies to
traits and interfaces
as well
<?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 then classes
❖ Start with lowest positions, then least used
48. Functions
❖ Used in function calls
❖ Depends on namespaces
and aliases
❖ Used in native functions
like array_map()
<?php
function foo() {}
array_map('foo', $array);
?>
49. Constants
❖ Defined with const, define
❖ May be case-insensitive
❖ Dynamic constant()
❖ Namespaced, aliased
❖ Used in static expressions
❖ This leads to inclusion hells
<?php
define(ONE, 1, true);
const TWO = ONE + 1;
$constant = 'TWO';
echo constant($constant
?>
50. Inclusion
❖ include/require, /_once
❖ new() because autoload
❖ Static constant, static methods calls, static property
❖ Order is important, as include also execute…
<?php
include 'file.php';
?>
51. How to spot issues?
❖ Code knowledge
❖ lint
❖ Grep / Search
❖ Static analysis
❖ Logs / error_reporting
❖ Unit Tests
52. When to hunt dead code?
❖ An every day relaxation
❖ My most productive day
saw 200 classes removed
❖ trigger_error($msg,
E_USER_DEPRECATED)
and
debug_backtrace()
❖ Bath in the energy of live
code