Download - Trucs et astuces PHP et MySQL
Trucs et astucesPHP & MySQL
Toute cette puissance au bout des doigtsMontréal, Québec, Canada
Agenda
Trucs et astuces PHP et MySQL
Issus des distributions
Rien de spécial
Encore valide en PHP 4 (mais passez en 5!)
Le mois de la fonction PHP
Questions?
Qui parle?
Damien Séguy
PHP Québec, AFUP
Expert PHP et MySQL : sécurité, audit
Auteur des documentations rédacteur en chef
http://www.nexen.net/
Au hasard
rand() et mt_rand()
array_rand() : extrait des lignes d'un tableau
Extrait les clés!
shuffle() : mélange un jeu de cartes
str_shuffle : Mélange une chaîne
Au hasard
<?php$a = range('a','d');shuffle($a);
print_r($a);
print_r(array_rand($a,3));
print str_shuffle('abcdef');// eabdcf?>
Array( [0] => c [1] => d [2] => b [3] => a)Array( [0] => 0 [1] => 1 [2] => 3)
Tableaux SQL?
Array_unique : DISTINCT
array_count_values : GROUP BY
Bien plus rapide que la précédente
Tableaux SQL?<?php$array = array("1", "MySQL", 1, "PHP", "PHP");$array = array_count_values($array);asort($array);print_r($array);?>
Array( [1] => 2 [PHP] => 2 [MySQL] => 1)
sort r u
ksort kr uk
asort ar ua
Tableaux SQL
array_multisort() : tri surplusieurs tableaux en même temps
Fonctionne comme ORDER BY
<?php$ar1 = array(5,4,3,2);$ar2 = array('a','b','c','d');array_multisort($ar1, $ar2);array_multisort($ar1, SORT_ASC, SORT_INT, $ar2);
?>
Array( [0] => 2 [1] => 3 [2] => 4 [3] => 5)Array( [0] => d [1] => c [2] => b [3] => a)
Étranges tris?
mysql> SELECT id, ordre FROM table ORDER BY ordre ASC;+----+------------+| id | ordre |+----+------------+| 1 | premier || 2 | deuxième || 3 | troisième || 4 | quatrième |+----+------------+
Est ce que ça cloche?
Étranges tris
mysql> CREATE TABLE `test` ( `id` tinyint unsigned, `ordre` enum(‘premier’,’deuxième’, ’troisième’,’quatrième’),) ENGINE=MYISAM;
Enum est une chaîne et un nombre
Utilisé en interne comme entier
Affiché par défaut comme une chaîne
Variables MySQL
Disponibles depuis la pré-histoire
Gérée au niveau des connexions
Détruites à la déconnexion
Pas de concurrence
Stockage local de scalaires
Permet de se passer de PHP
Variables MySQL
mysql> SELECT @total := sum(nombre) FROM statsPHP ;mysql> UPDATE statsPHP SET pourcentage = nombre / @total * 100;
<?php $requete = "SELECT sum(nombre) FROM statsPHP"; $res = mysqli_query($mid, $requete); $ligne = mysqli_fetch_row($res); mysqli_free_result($res);
$requete = "UPDATE statsPHP SET pourcentage = nombre / ".$ligne." * 100;"; mysqli_query($mid, $requete); ?>
Sécurité SQL<?php $requete = "SELECT droits FROM utilisateurs WHERE login = '". mysqli_real_escape_string($mid, $_POST["login"])."'"; $res = mysqli_query($mid, $requete); $droits = mysqli_fetch_row($res); ?>
<?php $requete = "SET @login :=
'".mysqli_real_escape_string($mid, $_POST["login"])."'"; $res = mysqli_query($mid, $requete);
$requete = "SELECT droits FROM utilisateurs WHERE login = @login"; $res = mysqli_query($mid, $requete); $droits = mysqli_fetch_row($res); ?>
Classementsmysql> SET @rank := 0;mysql> SELECT @rank := @rank + 1 AS rank, country, php FROM statsPHP ORDER BY php;+------+---------------+-----+| rank | country | php |+------+---------------+-----+| 1| F. Polynesia | 67 | | 2| Turk&Caicos | 55 | | 3| France | 41 | | 4| USA | 31 | | 5| Canada | 31 | | 7| Greenland | 17 | | 8| Israel | 17 | +------+---------------+-----+8 rows in set (0.00 sec)
Ex-aequomysql> SET @num := 0, @rank := 0, @prev := NULL;mysql> SELECT @num := @num + 1 AS row, @rank := if(@prev != php, @num, @rank) AS rank, country, @prev := php AS php FROM statsPHP ORDER BY php;+------+------+---------------+-----+| row | rank | country | php |+------+------+---------------+-----+| 1| 1| Polynésie Fr. | 67 | | 2| 2| Turk & Caicos | 55 | | 3| 3| France | 41 | | 4| 4| USA | 31 | | 5| 4| Canada | 31 | | 6| 6| Groënland | 17 | | 7| 6| Israel | 17 | +------+------+---------------+-----+
Variables en masse
Compact() et extract()
<?php $requete = "SELECT * FROM table WHERE login = @login"; $res = mysqli_query($mid, $requete); $resultat = mysqli_fetch_row($res);
extract($resultat); // $colonne1 = 'valeur'; $colonne2 = 'valeur'
extract($_GET); // ne l'utilisez pasimport_request_variables(); // non plus?>
PHP est dynamique
Variables variables
<?php $x = 'y'; $y = 'z'; $z = 'a';
echo $x; // affiche y echo $$x; // affiche z echo $$$x; // affiche a ?>
constantes variables
Une seule définition
Accès dynamique à une valeur constante
<?php define ("CONSTANTE", 'PHP Québec'); echo CONSTANTE; echo constant("CONSTANTE"); print_r(get_defined_constants());?>
Fonctions variables
<?php $fonc = 'foo'; $foo = 'bar'; $classe = 'bb';
$fonc($foo); // vaut foo('bar'); call_user_func($fonc, $foo);// idem
call_user_func(array($classe, $fonc), $foo); // $bb->fonc('bar'); // bb::fonc('bar'); $classe->$fonc($foo); // idem?>
Variables en masse
Compact() et extract()
<?php $x = 'a'; $y = 'b'; $z = compact('x','y'); // $z = array('x'=> 'a', 'y' => 'b');
$r = call_user_func_array('fonc', $z); // vaut fonc($x, $y) ou fonc('a', 'b');
extract($r); // $x = 'c'; $y = 'd'; $t = 'e'; list($x, $y, $t) = array_values($r); ?>
Toute cette dynamite..
Métamoteur
Gabarits
Gestion de structures dynamiques
SOAP
Personnalisation de bibliothèques
Magie de l'objet
__autoload() : Juste à temps
<?php// php.ini auto_prependfunction __autoload($classe) { include 'classes/' . $classe . '.php';}
$objet = new MaClasse();$objet2 = new MaClasse2(); ?>
Magie de l'objet__toString() :
transforme un objet en chaîne
toArray(), __toInteger()?
<?php class db { function __toString() { return "La connexion à ".$this->hote." est ". (is_null($this->mid ? 'active' : 'inactive' ).""; } }
$db = new db(); echo $db; ?>
PHP Catchable fatal error: Object of class mysqli could not be converted to string
Magie de l'objet
__sleep() et __wakeup()
Stocke un objet en session
Avant serialize()
class db { // ..... function __sleep() { unset($this->mid); } function __wakeup() { $this->mid = new mysqli("host", "user", "secret", "base"); } // ..... }
Buffer de sortie
Intercepte le contenu
Evite le bogue 'already sent'
Nettoyez : tidy
Compressez : gz
Cachez : ce sein que
<?phpob_start("ob_gzhandler");echo "Hello\n";setcookie("c", "v");ob_end_flush();?>
Caches simples
auto_prepend :
auto_append :
if ( filemtime( CACHE )+3600 < time()) { include($cachefile); exit; } ob_start();
$content = ob_get_contents(); file_put_contents(CACHE, $contents); ob_end_flush();
Connexions HTTP
PHP Enregistre l'état de la connexion
0 Normal; 1 Annulé; 2 expiré
ignore_user_abort() évite les interruptions
connexion_status() surveille l'état
Register_shutdown
Semblable au __destruct()
Fonction exécutée à l'extinction du script
Fermeture des ressources
Plus pratique que ignore_user_abort pour une bibliothèque
Variables
var_export : Crée le code pour une variable
Pratique pour les tableaux de configuration
Optimise ces tableaux
<?php
$array = array(5,4,3,2);
print var_export($array, true);
?>
array ( 0 => 5, 1 => 4, 2 => 3, 3 => 2,)
Assertions
tests dans les scripts
assertion sont gérées par directive
Par défaut, activé
Facile à supprimer echo/var_dump
Développement par contrat
Assertions
<?php assert_options(ASSERT_CALLBACK,'assert_callback'); function carre_naturel($x) { assert('is_integer( $x );' ); assert('$x < 0'); assert('$x > sqrt(PHP_INT_MAX) //* $x doit être plus petit' );
return $x * $x; } ?>
Assertions
<?php
function assert_callback($script,$line, $message){ echo 'Un problème est survenu dans le script <b>', $script,'</b>, à la ligne <b>', $line, '</b> : <br />' . $message; exit; } ?>
Déboguage
phpinfo()
get_defined_funcs()
get_extension_funcs()
get_defined_classes()
get_object_vars()
get_class_var()
<?phpReflection::export( new ReflectionClass('Exception'));?>Class [ <internal> class Exception ] { - Constants [0] {} - Static properties [0] { } - Static methods [0] { }
Débogage
get_defined_vars()
get_included_files()
__FILE__, __LINE__
__FUNCTION__, __CLASS__, __METHOD__
Débogage
debug_backtrace()
Affiche la pile PHP
Inclus les arguments utilisés
array(2) {[0]=>array(4) { ["file"] => string(10) "/tmp/a.php" ["line"] => int(10) ["function"] => string(6) "a_test" ["args"]=> array(1) { [0] => &string(6) "friend" }}[1]=>array(4) { ["file"] => string(10) "/tmp/b.php" ["line"] => int(2) ["args"] => array(1) { [0] => string(10) "/tmp/a.php" } ["function"] => string(12) "include_once" }}
Listes rapides
scandir(‘/tmp’, true);
Permet le tri sur les noms
Remplace opendir(), readdir(), closedir() et une boucle!
Glob(‘*.html’);
Listes rapides
<?phpprint_r(scandir('/tmp/', 1));print_r(glob('/tmp/sess_*'));?>
Array( [0] => sess_um8rgjj10f6qvuck91rf36srj7 [1] => sess_u58rgul68305uqfe48ic467276 [2] => mysql.sock [3] => .. [4] => .)Array( [0] => /tmp/sess_um8rgjj10f6qvuck91rf36srj7 [1] => /tmp/sess_u58rgul68305uqfe48ic467276)
URL
parse_url() : Détaille une URL
parse_string() : Découpe les paramètres
http_build_query() : Reconstruit une URL
URL
<?php$url = 'htp://login:[email protected]/ path/file.php?a=2 &b[]=3#ee';
$d = parse_url($url);print_r($d);
parse_str($d["query"]);var_dump($GLOBALS["b"]);
print http_build_query( array_merge($_GET , array(' de ' => '对了!')));?>
Array( [scheme] => htp [host] => www.site.com [user] => login [pass] => pass [path] => /path/file.php [query] => a=2 &b[]=3 [fragment] => ee)array(1) { [0]=> string(1) "3"}+de+=%E5%AF%B9%E4%BA%86%EF%BC%81
URL
<?php get_headers('http://localhost/logo.png', false);?>
Array( [0] => HTTP/1.1 200 OK [Date] => Fri, 09 Mar 2007 21:09:52 GMT [Server] => Apache/1.3.33 (Darwin) PHP/5.2.1 [X-Powered-By] => PHP/5.2.1 [En_plus] => non [Set-Cookie] => Array ( [0] => a=a [1] => a=b )
[Connection] => close [Content-Type] => text/html)
Cette conférence
http://www.nexen.net/conferences.php
Tableaux
array_combine : combine deux tableaux en un seul
<?php$a = array('vert', 'rouge', 'jaune');$b = array('avocat', 'pomme', 'banane');$c = array_combine($a, $b);
print_r($c);?>
Array( [vert] => avocat [rouge] => pomme [jaune] => banane)