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.
Top 10 

chausse-trappes 

en PHP
AFUP Aix-Marseille 2019
Agenda
1 heure
Top 10+ chausses-trappes PHP
Améliorez votre code dès maintenant
Ca peut attendre demain
QUI PARLE?
➤ Damien Seguy
➤ Directeur technique Exakat
➤ Analyse statique de code PHP
➤ Maison de retraite pour elephpant
Erreur tapie dans le code
Un puit de performances
Un outil pratique
La voie de l'éléphpant
🐞
🛠
🐘
🚀
La légende de strpos()
<?php
if (strpos($string, 'a'))  { }
if (strpos($string, 'a') == 0) { }
if ($x = strpos($string, 'a...
Comparaison strpos
<?php
// La seule comparaison possible pour 0/false
if (strpos($string, 'a') === false) { }
// Pas de 0...
comparaison strpos
array_search()
collator_compare()
collator_get_sort_key()
current()
fgetc()
file_get_contents()
file_put_...
Define()
<?php 
define('A', true);
?>
🚀
Define() vers const
<?php 
const A = true;
?>
🐘
Define() en déclin
<?php  
define('A', 3, true); 
define($x, $y); 
?>
🛠
define() vers const
<?php 
const A = true;
const B = 33 + 12 * (23 - 34);
const C = array(A, B, D::E);
const D = A ? B : C;...
Affichages répétés
<?php
  print 'a';
  print $b ;
  print 'c';
?>
🚀
Affichages répétés
<?php
  print 'a' . $b . 'c';
?>
🚀
Affichages répétés
<?php
  echo  'a' , $b , 'c';
?>
🐘
Affichages répétés
<?php
  echo  'a',
$b ,
'c';
?>
echo ne fonctionne pas
<?php
  echo( 'a',
$b ,
'c',
);
?>
<?php
$b = 3; $c = 1;
$a1 = $b and $c;
$a2 = $b && $c;
?>
🐞
La logique en toutes lettres
La logique en toutes lettres
<?php
$b = 3; $c = 1;
$a1 = ($b and $c);
$a2 = $b && $c;
?>
🐘
L'ordre en toutes lettres
<?php   
echo -3 ** 2;
$x = new stdClass();
var_dump(!$x instanceof stdClass);
?>
🐞
Loin du réel
<?php
// Ne plus utiliser
if (!is_real($a)) {
    $a = (real) $a;
}
?>
🐞
Ca flotte…
<?php
if (!is_float($a)) {
    $a = (float) $a;
}
?>
🐘
// Toujours valide en 7.4
Se mesurer au réel
<?php
$a = 1/7;
$b = 2.0;
var_dump( 7 * $a === 1);
var_dump( (0.1 + 0.7) * 10 == 8);
var_dump( (0.1 + 0...
Se mesurer au réel
<?php 
$a = 1/7; 
$c = ((0.1 + 0.7) * 10) - 8;
// calcul de précision
var_dump( abs($c) < 0.0001); 
?>
🐘
Substr(,,1) ?
<?php
$string = "abcde";
echo substr($string, $pos, 1);
?>
🚀
Substr(,,1) ?
<?php
$string = "abcde";
echo substr($string, $pos, 1);
echo $string[$pos];
?>
🐘
Substr(,,1) ?
<?php
$string = "abcde";
echo substr($string, -1, 1);
echo $string[-1];
?>
🐘
Substr(,,1) ?
<?php
$string = "ab⼈人cde";
echo substr($string, $pos, 1);
echo $string[$pos];
echo mb_substr($string, $pos, ...
Toujours substr()
<?php
$result = substr(strtolower($s), $o, $l);
?>
🚀
Substr() d'abord!
<?php
$result = strtolower(substr($s, $o, $l));
?>
🐘
array_slice() d'abord!
<?php
$a = array_slice(array_map('foo', $array),
 2, 
5);
$a = array_map('foo', 
array_slice($array...
array_merge() en boucle
<?php
$res = $sqlite3->query(
'SELECT lists FROM table');
while ($row = $res->fetchArray(PDO_ASSOC...
array_merge() en boucle
<?php 
$res = $sqlite3->query(

'SELECT lists FROM table'); 
while ($row = $res->fetchArray(PDO_AS...
concat en boucle
<?php
$res = $sqlite3->query(
'SELECT value FROM table');
while ($row = $res->fetchArray(PDO_ASSOC)) {
  ...
concat en boucle
<?php 
$res = $sqlite3->query(
        'SELECT value FROM table'); 
$a = array();
while ($row = $res->fet...
addition en boucle
<?php
$res = $sqlite3->
query('SELECT quantite FROM table');
while ($row = $res->fetchArray(PDO_ASSOC))...
<?php
function g1() : Generator {
 for ($i = 0; $i < 4; ++$i ) { yield $i; }
}
function g2() : Generator {
 for ($i = 5; $...
/*
Array
(
    [0] => 6
    [1] => 7
    [2] => 8
    [3] => 9
    [4] => 4  
    [5] => 5  
)
*/
Yield la clé
<?php
function g1() : Generator {
for ($i = 0; $i < 4; ++$i) { yield $i => $i; }
}
function g2() : Generator {
 for ($i = ...
/*
0 
1
2
3
4
5
6
7
8
9
*/
Yield la clé
Le sous-motif qui manque
<?php
preg_match('/(a)(b)?/', 'abc', $r);
/*
Array
(
    [0] => ab
    [1] => a
    [2] => b
)
*/...
Le sous-motif qui manque
<?php
preg_match('/(a)(b)?/', 'adc', $r);
/*
Array
(
    [0] => a
    [1] => a
)
*/
🐞
Le sous-motif qui manque
<?php
preg_match('/(a)(b)?(.)/', 'adc', $r);
/*
Array
(
    [0] => ad
    [1] => a
    [2] => 
  ...
La marque sans-nom™
<?php  
preg_match('/(?<ici>a)(b)?(.)/', 'adc', $r); 
preg_match("/(?'ici'a)(b)?(.)/", 'adc', $r); 
pr...
Ne pas unset() les propriétés
<?php 
class x {
  public $y = 1;
}
$x = new x();
unset($x->y);
print_r($x);
?>
x Object
(
)...
Ne pas unset() les propriétés
<?php 
class x { 
 public $y = 1; 
} 
$x = new x(); 
$x->y = null; 
var_dump(isset($x->y));
...
Ne pas unset() les propriétés
<?php 
class x {
  public $y = 1;
}
$x = new x();
$x->z = 3;
print_r($x);
?>
x Object
(
[y] ...
Propriété non-initialisée
<?php  
class x {  
  function foo() {
   if (!isset($this->y)) {
    $this->y = 0;
  }
  
   re...
Propriété non-initialisée
<?php  
class x {  
 public $y = 0; 
  function foo() {
   if ($this->y === null) {
    $this->y...
Le mois prochain
<?php
echo date('F', 
strtotime('+1 month',
mktime(0,0,0,$i,31,2019)));
?>
// 1er janvier => 1er février
...
Le mois prochain
<?php
echo date('F', 
strtotime('first day of next month',
mktime(0,0,0,$i,31,2019)));
?>
// 1er janvier ...
C'est quand, demain?
<?php
$demain = time() + 86400;
?>
🐞
C'est quand, demain?
<?php
$demain = new DateTime('tomorrow');
?>
🐘
Combien dure mon script?
<?php  
$debut = microtime(true);
// grosse masse de code magnifique
$fin = microtime(true);
prin...
Combien dure mon script?
<?php   
$debut = hrtime(true); 
// grosse masse de code magnifique 
$fin = hrtime(true); 
print ...
Et maintenant ?
<?php
// version rapide
$a = time();
// version lente
$b = strtotime('now');
?>
🚀
La vengence de la
référence
<?php 
$a = range(0, 3);
foreach($a as &$b) { }
foreach($a as $b) { }
print_r($a);
?>
Array
(
...
La vengence de la
référence
<?php  
$a = range(0, 3); 
foreach($a as &$b) { } 
unset($b);
foreach($a as $b) { } 
print_r($...
list() en PHP 4
<?php  
list($a, $b) = array( 1, 2, 3);
?>
🛠
list() en PHP 5
<?php  
[$a, $b] =  [ 1, 2, 3];
?>
🛠
🐘
list() en PHP 7
<?php  
['c' => $a, 'e' => ['d'=> $b]] = 
['c' => 1,  
'e' =>['d' => 2, 
'f' => 3,]
,];
?>
🛠
🐘
list() en PHP 7
<?php  
['e' => $a, 'e' => ['d'=> $b]] = 
['c' => 1,  
'e' =>['d' => 2, 
'f' => 3,]
,];
?>
🛠
🐘
List() pour le futur!
<?php 
$res = $sqlite3->query(
           'SELECT lists FROM table'); 
foreach($res->fetchArray(SQLI...
Encore plus ?
🛠
🐘Exakat
Analyse statique de votre code
Prépare pour PHP 7.4 / 8.0 (parbleu!)
Modernise votre code
https://...
Gramaci!
@exakat
Upcoming SlideShare
Loading in …5
×

Top 10 chausse trappes

327 views

Published on

PHP a son lot de surprises qui pimente notre vie de développeur : le code qui meurt d’un coup de namespace, strpos qui ne trouve pas sa chaîne et les tableaux qui se modifient sans qu’on y touche. Ca vous énerve vous aussi ? Alors, en 20 minutes, on va dresser un florilège des erreurs les plus vicieuses, comment les corriger et comment les garder loin de votre code. Attachez vos ceintures !

Published in: Technology
  • Be the first to comment

  • Be the first to like this

Top 10 chausse trappes

  1. 1. Top 10 
 chausse-trappes 
 en PHP AFUP Aix-Marseille 2019
  2. 2. Agenda 1 heure Top 10+ chausses-trappes PHP Améliorez votre code dès maintenant Ca peut attendre demain
  3. 3. QUI PARLE? ➤ Damien Seguy ➤ Directeur technique Exakat ➤ Analyse statique de code PHP ➤ Maison de retraite pour elephpant
  4. 4. Erreur tapie dans le code Un puit de performances Un outil pratique La voie de l'éléphpant 🐞 🛠 🐘 🚀
  5. 5. La légende de strpos() <?php if (strpos($string, 'a'))  { } if (strpos($string, 'a') == 0) { } if ($x = strpos($string, 'a')) { } 🐞
  6. 6. Comparaison strpos <?php // La seule comparaison possible pour 0/false if (strpos($string, 'a') === false) { } // Pas de 0, pas de confusion if (strpos($string, 'a') == 2) { } // strpos n'est pas la seule! if (preg_match($regex, $string)) { } 🐘
  7. 7. comparaison strpos array_search() collator_compare() collator_get_sort_key() current() fgetc() file_get_contents() file_put_contents() fread() iconv_strpos() iconv_strrpos() imagecolorallocate() imagecolorallocatealpha() mb_strlen() next() pcntl_getpriority() preg_match() prev() readdir() stripos() strpos() strripos() strrpos() strtok() curl_exec()
  8. 8. Define() <?php  define('A', true); ?> 🚀
  9. 9. Define() vers const <?php  const A = true; ?> 🐘
  10. 10. Define() en déclin <?php   define('A', 3, true);  define($x, $y);  ?> 🛠
  11. 11. define() vers const <?php  const A = true; const B = 33 + 12 * (23 - 34); const C = array(A, B, D::E); const D = A ? B : C; ?> 🛠
  12. 12. Affichages répétés <?php   print 'a';   print $b ;   print 'c'; ?> 🚀
  13. 13. Affichages répétés <?php   print 'a' . $b . 'c'; ?> 🚀
  14. 14. Affichages répétés <?php   echo  'a' , $b , 'c'; ?> 🐘
  15. 15. Affichages répétés <?php   echo  'a', $b , 'c'; ?>
  16. 16. echo ne fonctionne pas <?php   echo( 'a', $b , 'c', ); ?>
  17. 17. <?php $b = 3; $c = 1; $a1 = $b and $c; $a2 = $b && $c; ?> 🐞 La logique en toutes lettres
  18. 18. La logique en toutes lettres <?php $b = 3; $c = 1; $a1 = ($b and $c); $a2 = $b && $c; ?> 🐘
  19. 19. L'ordre en toutes lettres <?php    echo -3 ** 2; $x = new stdClass(); var_dump(!$x instanceof stdClass); ?> 🐞
  20. 20. Loin du réel <?php // Ne plus utiliser if (!is_real($a)) {     $a = (real) $a; } ?> 🐞
  21. 21. Ca flotte… <?php if (!is_float($a)) {     $a = (float) $a; } ?> 🐘 // Toujours valide en 7.4
  22. 22. Se mesurer au réel <?php $a = 1/7; $b = 2.0; var_dump( 7 * $a === 1); var_dump( (0.1 + 0.7) * 10 == 8); var_dump( (0.1 + 0.7) * 10); ?> 🐞
  23. 23. Se mesurer au réel <?php  $a = 1/7;  $c = ((0.1 + 0.7) * 10) - 8; // calcul de précision var_dump( abs($c) < 0.0001);  ?> 🐘
  24. 24. Substr(,,1) ? <?php $string = "abcde"; echo substr($string, $pos, 1); ?> 🚀
  25. 25. Substr(,,1) ? <?php $string = "abcde"; echo substr($string, $pos, 1); echo $string[$pos]; ?> 🐘
  26. 26. Substr(,,1) ? <?php $string = "abcde"; echo substr($string, -1, 1); echo $string[-1]; ?> 🐘
  27. 27. Substr(,,1) ? <?php $string = "ab⼈人cde"; echo substr($string, $pos, 1); echo $string[$pos]; echo mb_substr($string, $pos, 1); // $pos = 1 => bbb // $pos = 2 => ??⼈人 ?> 🐘
  28. 28. Toujours substr() <?php $result = substr(strtolower($s), $o, $l); ?> 🚀
  29. 29. Substr() d'abord! <?php $result = strtolower(substr($s, $o, $l)); ?> 🐘
  30. 30. array_slice() d'abord! <?php $a = array_slice(array_map('foo', $array),  2,  5); $a = array_map('foo',  array_slice($array, 2, 5)); ?> 🚀 🐘
  31. 31. array_merge() en boucle <?php $res = $sqlite3->query( 'SELECT lists FROM table'); while ($row = $res->fetchArray(PDO_ASSOC)) {   $l = explode(',', $row['value']);   $final = array_merge($final, $l); } ?> 🚀
  32. 32. array_merge() en boucle <?php  $res = $sqlite3->query(
 'SELECT lists FROM table');  while ($row = $res->fetchArray(PDO_ASSOC)) {    $l = explode(',', $row['value']);    $a []=  $l; } $final = array_merge(...$a);  ?> 🐘
  33. 33. concat en boucle <?php $res = $sqlite3->query( 'SELECT value FROM table'); while ($row = $res->fetchArray(PDO_ASSOC)) {   $a .= $row['value']; } ?> 🚀
  34. 34. concat en boucle <?php  $res = $sqlite3->query(         'SELECT value FROM table');  $a = array(); while ($row = $res->fetchArray(PDO_ASSOC)) {    $a []= $row['value'];  }  $final = implode('', $a); ?> 🐘
  35. 35. addition en boucle <?php $res = $sqlite3-> query('SELECT quantite FROM table'); while ($row = $res->fetchArray(PDO_ASSOC)) {   $a += $row['quantite']; } ?> 🐘 Vu A la tElE
  36. 36. <?php function g1() : Generator {  for ($i = 0; $i < 4; ++$i ) { yield $i; } } function g2() : Generator {  for ($i = 5; $i < 10; ++$i ) { yield $i; } } function aggregator() : Generator {      yield from g1();      yield from g2(); } print_r(iterator_to_array()); Yield la clé 🐞
  37. 37. /* Array (     [0] => 6     [1] => 7     [2] => 8     [3] => 9     [4] => 4       [5] => 5   ) */ Yield la clé
  38. 38. <?php function g1() : Generator { for ($i = 0; $i < 4; ++$i) { yield $i => $i; } } function g2() : Generator {  for ($i = 5; $i < 10; ++$i) { yield $i => $i;} } function aggregator() : Generator {      yield from g1();      yield from g2(); } print_r(iterator_to_array()); Yield la clé 🐘
  39. 39. /* 0  1 2 3 4 5 6 7 8 9 */ Yield la clé
  40. 40. Le sous-motif qui manque <?php preg_match('/(a)(b)?/', 'abc', $r); /* Array (     [0] => ab     [1] => a     [2] => b ) */ ?> 🐞
  41. 41. Le sous-motif qui manque <?php preg_match('/(a)(b)?/', 'adc', $r); /* Array (     [0] => a     [1] => a ) */ 🐞
  42. 42. Le sous-motif qui manque <?php preg_match('/(a)(b)?(.)/', 'adc', $r); /* Array (     [0] => ad     [1] => a     [2] =>      [3] => d ) */ 🐘
  43. 43. La marque sans-nom™ <?php   preg_match('/(?<ici>a)(b)?(.)/', 'adc', $r);  preg_match("/(?'ici'a)(b)?(.)/", 'adc', $r);  print_r($r); /* Array (     [0] => ad [ici] => a     [1] => a     [2] =>      [3] => d ) */ 🐘
  44. 44. Ne pas unset() les propriétés <?php  class x {   public $y = 1; } $x = new x(); unset($x->y); print_r($x); ?> x Object ( ) 🐞
  45. 45. Ne pas unset() les propriétés <?php  class x {   public $y = 1;  }  $x = new x();  $x->y = null;  var_dump(isset($x->y)); print_r($x);  ?> bool(false) x Object ( [y] => ) 🐘
  46. 46. Ne pas unset() les propriétés <?php  class x {   public $y = 1; } $x = new x(); $x->z = 3; print_r($x); ?> x Object ( [y] => 1 [z] => 3 ) 🛠
  47. 47. Propriété non-initialisée <?php   class x {     function foo() {    if (!isset($this->y)) {     $this->y = 0;   }       return $this->y++; }   ?> 🚀
  48. 48. Propriété non-initialisée <?php   class x {    public $y = 0;    function foo() {    if ($this->y === null) {     $this->y = 0;   }   }       return $this->y++; }   ?> 🐘
  49. 49. Le mois prochain <?php echo date('F',  strtotime('+1 month', mktime(0,0,0,$i,31,2019))); ?> // 1er janvier => 1er février // 31 octobre => 1er décembre // 31 janvier => 2 ou 3 mars 🐞
  50. 50. Le mois prochain <?php echo date('F',  strtotime('first day of next month', mktime(0,0,0,$i,31,2019))); ?> // 1er janvier => 1er février // 31 octobre => 1 novembre // 31 janvier => 1er février 🐘
  51. 51. C'est quand, demain? <?php $demain = time() + 86400; ?> 🐞
  52. 52. C'est quand, demain? <?php $demain = new DateTime('tomorrow'); ?> 🐘
  53. 53. Combien dure mon script? <?php   $debut = microtime(true); // grosse masse de code magnifique $fin = microtime(true); print number_format(($fin - $debut),  2) .'ms'; ?> 🐞
  54. 54. Combien dure mon script? <?php    $debut = hrtime(true);  // grosse masse de code magnifique  $fin = hrtime(true);  print number_format(($fin - $debut) / 1000000,  2) .'ms'; ?> 🐘
  55. 55. Et maintenant ? <?php // version rapide $a = time(); // version lente $b = strtotime('now'); ?> 🚀
  56. 56. La vengence de la référence <?php  $a = range(0, 3); foreach($a as &$b) { } foreach($a as $b) { } print_r($a); ?> Array ( [0] => 0 [1] => 1 [2] => 2 [3] => 2 ) 🐞
  57. 57. La vengence de la référence <?php   $a = range(0, 3);  foreach($a as &$b) { }  unset($b); foreach($a as $b) { }  print_r($a);  ?> Array ( [0] => 0 [1] => 1 [2] => 2 [3] => 3 ) 🐘
  58. 58. list() en PHP 4 <?php   list($a, $b) = array( 1, 2, 3); ?> 🛠
  59. 59. list() en PHP 5 <?php   [$a, $b] =  [ 1, 2, 3]; ?> 🛠 🐘
  60. 60. list() en PHP 7 <?php   ['c' => $a, 'e' => ['d'=> $b]] =  ['c' => 1,   'e' =>['d' => 2,  'f' => 3,] ,]; ?> 🛠 🐘
  61. 61. list() en PHP 7 <?php   ['e' => $a, 'e' => ['d'=> $b]] =  ['c' => 1,   'e' =>['d' => 2,  'f' => 3,] ,]; ?> 🛠 🐘
  62. 62. List() pour le futur! <?php  $res = $sqlite3->query(            'SELECT lists FROM table');  foreach($res->fetchArray(SQLITE3_ASSOC)  as ['lists' => $list]) {    $l = explode(',', $list);  $a[] = $l; }    $final = array_merge(…$a);  ?> 🛠 🐘
  63. 63. Encore plus ? 🛠 🐘Exakat Analyse statique de votre code Prépare pour PHP 7.4 / 8.0 (parbleu!) Modernise votre code https://www.exakat.io/
  64. 64. Gramaci! @exakat

×