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, pas de confusion
if (strpos($string, 'a') == 2) { }
// strpos n'est pas la seule!
if (preg_match($regex, $string)) { }
🐘
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()
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.7) * 10);
?>
🐞
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, 1);
// $pos = 1 => bbb
// $pos = 2 => ??⼈人
?>
🐘
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, 2, 5));
?>
🚀
🐘
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);
}
?>
🚀
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); 
?>
🐘
concat en boucle
<?php
$res = $sqlite3->query(
'SELECT value FROM table');
while ($row = $res->fetchArray(PDO_ASSOC)) {
  $a .= $row['value'];
}
?>
🚀
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);
?>
🐘
addition en boucle
<?php
$res = $sqlite3->
query('SELECT quantite FROM table');
while ($row = $res->fetchArray(PDO_ASSOC)) {
  $a += $row['quantite'];
}
?>
🐘
Vu
A
la
tElE
<?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é 🐞
/*
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 = 5; $i < 10; ++$i) { yield $i => $i;}
}
function aggregator() : Generator {
     yield from g1();
     yield from g2();
}
print_r(iterator_to_array());
Yield la clé 🐘
/*
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] => 
    [3] => d
)
*/
🐘
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
)
*/
🐘
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));
print_r($x); 
?>
bool(false)
x Object
(
[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] => 1
[z] => 3
)
🛠
Propriété non-initialisée
<?php  
class x {  
  function foo() {
   if (!isset($this->y)) {
    $this->y = 0;
  }
  
   return $this->y++;
}  
?>
🚀
Propriété non-initialisée
<?php  
class x {  
 public $y = 0; 
  function foo() {
   if ($this->y === null) {
    $this->y = 0;
  }
  }
  
   return $this->y++;
}  
?>
🐘
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
🐞
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
🐘
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);
print number_format(($fin - $debut), 
2)
.'ms';
?>
🐞
Combien dure mon script?
<?php   
$debut = hrtime(true); 
// grosse masse de code magnifique 
$fin = hrtime(true); 
print number_format(($fin - $debut) / 1000000, 
2)
.'ms';
?>
🐘
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
(
[0] => 0
[1] => 1
[2] => 2
[3] => 2
)
🐞
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
)
🐘
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(SQLITE3_ASSOC) 
as ['lists' => $list]) { 
  $l = explode(',', $list); 
$a[] = $l;
} 
  $final = array_merge(…$a); 
?>
🛠
🐘
Encore plus ?
🛠
🐘Exakat
Analyse statique de votre code
Prépare pour PHP 7.4 / 8.0 (parbleu!)
Modernise votre code
https://www.exakat.io/
Gramaci!
@exakat

Top 10 chausse trappes