Appuyez sur [s] pour ouvrir les notes présentateur dans une nouvelle fenêtre.
Utilisez la touche [ESPACE]
pour passer au slide suivant.
Source : w3techs.com
Source : w3techs.com
Depuis PHP 5.4
Support de sécurité allongé pour PHP 5.6
$ tree php-108
php-108
├── common.c
├── common.h
├── config.h
├── error.c
...
├── README
├── subvar.c
├── version.h
├── wm.c
└── wm.h
0 directories, 18 files
<?
msqlsethost("localhost");
$name = "bob";
$result = msql($database,"select * from table where firstname='$name'");
$num = msql_numrows($result);
echo "$num records found!<p>";
$i=0;
while($i<$num);
echo msql_result($result,$i,"fullname");
echo "<br>";
echo msql_result($result,$i,"address");
echo "<br>";
$i++;
endwhile;
>
<?
msqlsethost("localhost");
$name = "bob";
$result = msql($database,"select * from table where firstname='$name'");
$num = msql_numrows($result);
echo "$num records found!<p>";
$i=0;
while($i<$num);
echo msql_result($result,$i,"fullname");
echo "<br>";
echo msql_result($result,$i,"address");
echo "<br>";
$i++;
endwhile;
>
Migration PHP 4 → 5 difficile
Novembre 2005
Novembre 2006
DateTime
Juin 2009
?:
, goto
, mysqlnd, Garbage Collector, Phar, Intl, Fileinfo, Sqlite3Un tournant dans l'utilisation de PHP
Mars 2012
register_globals
, magic_quotes
, safe_mode
Juin 2013
finally
, ::class
, API mots de passeGenerators
Août 2014
use
pour fonctions et constantes**
, surcharge d'opérateurs (classes internes), phpdbgPHP 6 and MySQL 5 for Dynamic Web Sites: Visual QuickPro Guide
PHP 6 Fast and Easy Web Development
Professional PHP6 (Wrox Programmer to Programmer)
PHP 6/MySQL Programming for the Absolute Beginner
PHP6 and MySQL Bible
$username = isset($_GET['user']) ? $_GET['user'] : 'nobody';
$username = $_GET['user'] ?? 'nobody';
$model = Model::get($id) ?? $default_model;
$ php -r 'echo "I \u{2665} PHP!\n";'
I ♥ PHP!
$ php -r 'echo "\u{1F408} \u{1F431} \u{1F638} \u{1F639} \u{1F63A} \u{1F63B} \u{1F63C} \u{1F63D} \u{1F63E} \u{1F63F} \u{1F640} - so cute!!!\n";'
🐈 🐱 😸 😹 😺 😻 😼 😽 😾 😿 🙀 - so cute!!!
function add(int $a, int $b) {
return $a + $b;
}
var_dump( add(10, 20) );
var_dump( add('10', '20') );
int(30)
int(30)
try {
var_dump( add(10, 'abc') );
}
catch (TypeError $e) {
var_dump( $e->getMessage() );
}
string(148) "Argument 2 passed to add()
must be of the type integer, string given,
called in .../test-01.php on line 12"
function add(int $a, int $b) : int {
return $a + $b;
}
function get_config() : array {
return 42;
}
get_config();
Fatal error: Uncaught TypeError:
Return value of get_config() must be
of the type array, integer returned
declare(strict_types=1);
function add(int $a, int $b) {
return $a + $b;
}
add(10, '20');
Fatal error: Uncaught TypeError:
Argument 2 passed to add()
must be of the type integer, string given
function order_func($a, $b) {
return $a <=> $b;
}
function order_func($a, $b) {
return [$a->x, $a->y, $a->foo]
<=> [$b->x, $b->y, $b->foo];
}
use Mon\Espace\De\Nom\ClasseAa;
use Mon\Espace\De\Nom\ClasseBb;
use Mon\Espace\De\Nom\ClasseCc;
use Mon\Espace\De\Nom\Enfant\AutreClasse as ClassDd;
use Mon\Espace\De\Nom\ {
ClasseAa, ClasseBb, ClasseCc,
Enfant\AutreClasse as ClassDd
};
use function Mon\Nom\fonc01;
use const Mon\Nom\CONST01;
use Mon\Nom\Class01;
use Mon\Nom\ {
function fonc01,
const CONST01,
Class01
};
Error
$obj = null;
try {
// Ooops !
$obj->methode();
}
catch (Error $e) {
var_dump($e>getMessage());
}
string(43) "Call to a member function methode() on null"
$php = <<<'PHP'
$a = 10 // -- Parse error ! -- //
printf("\$a = %d\n", $a);
PHP;
try {
eval($php);
}
catch (ParseError $e) {
var_dump($e->getMessage());
}
string(44) "syntax error, unexpected 'printf' (T_STRING)"
echo "Fichier 1 - avant\n";
try {
// Fichier avec une erreur de syntaxe
include __DIR__ . '/test-06-2.php';
}
catch (Error $e) {
echo "Error catchée : ";
var_dump($e->getMessage());
}
echo "Fichier 1 - après\n";
Fichier 1 - avant
Error catchée : string(42) "syntax error, unexpected '$b' (T_VARIABLE)"
Fichier 1 - après
Hiérarchie d'erreurs / exceptions
interface Throwable
Exception implements Throwable
// Toutes les exceptions usuelles
Error implements Throwable
AssertionError extends Error
ParseError extends Error
TypeError extends Error
$obj = new class ("Monde") {
protected $qui;
public function __construct($qui) {
$this->qui = $qui;
}
public function hello() {
printf("Hello, %s !\n", $this->qui);
}
};
var_dump($obj);
$obj->hello();
$obj = new class ("Monde") {
protected $qui;
public function __construct($qui) {
$this->qui = $qui;
}
public function hello() {
printf("Hello, %s !\n", $this->qui);
}
};
var_dump($obj);
$obj->hello();
object(class@anonymous)#1 (1) {
["qui":protected]=>
string(5) "Monde"
}
Hello, Monde !
return
function plop() {
yield 100;
yield 200;
return 42;
}
foreach (($generator = plop()) as $val) {
var_dump($val);
}
var_dump( $generator->getReturn() );
int(100)
int(200)
int(42)
function test() {
yield from [10, 20, 30];
}
foreach (test() as $val) {
var_dump($val);
}
int(10)
int(20)
int(30)
function sub_generator_1() {
yield 10;
yield 20;
}
function sub_generator_2() {
yield from [ 'aa', 'bb', ];
}
function delegating_generator() {
yield from sub_generator_1();
yield from sub_generator_2();
}
foreach (delegating_generator() as $val) {
// Travail avec $val
}
$data = unserialize($serialized, [
"allowed_classes" => false
]);
$data = unserialize($serialized, [
"allowed_classes" => [
MaClasse::class,
'MonAutreClasse',
]
]);
var_dump( random_int(10, 100) );
var_dump( bin2hex(random_bytes(12)) );
int(23)
string(24) "903c636403869d3c3ab3310e"
jsond
JSON_PRESERVE_ZERO_FRACTION
pour json_encode()
var_dump( json_encode(42.0) );
var_dump( json_encode(42.0, JSON_PRESERVE_ZERO_FRACTION) );
string(2) "42"
string(4) "42.0"
Pour en savoir plus sur les changements internes :
PHP 7 – What changed internally? - Nikita Popov - Forum PHP 2015
class MaClasse {
public const MA_PUBLIQUE = 42;
private const MA_PRIVEE = 1234;
public function test() {
var_dump( self::MA_PRIVEE );
}
}
var_dump( MaClasse::MA_PUBLIQUE ); // int(42)
(new MaClasse())->test(); // int(1234)
// Error: Cannot access private const MaClasse::MA_PRIVEE
var_dump( MaClasse::MA_PRIVEE );
list()
$array = [
'glop' => "Hello",
'plop' => 123456,
'who' => "World",
];
list (
'glop' => $a,
'who' => $b
) = $array;
var_dump($a, $b);
// string(5) "Hello"
// string(5) "World"
[$a, $b] = [10, 20];
var_dump($a, $b);
// int(10)
// int(20)
['glop' => $glop, 'plop' => $plop] = [
'plop' => 42,
'glop' => "Hello",
];
var_dump($plop, $glop);
// int(42)
// string(5) "Hello"
$str = "Pascal";
var_dump($str[2]); // string(1) "s"
var_dump($str[-2]); // string(1) "a"
$str = "Pas.al";
$str[-3] = 'c';
var_dump($str); // string(6) "Pascal"
var_dump( strpos("Pascal", "c", -5) ); // int(3)
class Plop extends Exception {}
class Blah extends Exception {}
class Another extends Exception {}
try {
switch (mt_rand(0, 2)) {
case 0: throw new Plop();
case 1: throw new Blah();
case 2: throw new Another();
}
} catch (Plop | Blah $e) {
printf("1er catch : %s\n", get_class($e));
} catch (Another $e) {
printf("2nd catch : %s\n", get_class($e));
}
La majorité des erreurs fatales levées par des extensions intégrées à PHP sont converties en exceptions.
PHP 7.0
function fonc01(int $a) {
var_dump($a);
}
fonc01(100); // int(100)
fonc01(null); // TypeError: Argument 1 passed to
// fonc01() must be of the type
// integer, null given
PHP 7.1
function fonc01(?int $a) {
var_dump($a);
}
fonc01(100); // int(100)
fonc01(null); // NULL
fonc01();
// Error: Too few arguments to function fonc01(), 0 passed
function fonc02(?int $a, ?int $b) : ?int {
if ($a === null || $b === null) {
return null;
}
return $a + $b;
}
var_dump( fonc02(10, 20) ); // int(30)
var_dump( fonc02(10, null) ); // NULL
function fonc01() {
printf("%s\n", __FUNCTION__);
}
function fonc02() : void {
printf("%s\n", __FUNCTION__);
}
function function03() : void {
printf("%s\n", __FUNCTION__);
// Fatal error: A void function must not return a value
return 'plop';
}
function fonc01(iterable $data) {
foreach ($data as $key => $val) {
// ...
}
}
fonc01( [10, 20, 30] );
fonc01( new SplFixedArray(5) );
fonc01( mon_generateur() );
function ma_fonction() {
var_dump(__FUNCTION__);
}
$closure = Closure::fromCallable('ma_fonction');
$closure(); // string(11) "ma_fonction"
$closure = Closure::fromCallable('plop');
// TypeError: Failed to create closure from callable:
// function 'plop' not found or invalid function name
Assez peu de bc-breaks
Mais quand même.
Usage interdit en tant que :
int
float
bool
string
true
et false
null
On sait jamais ^^
resource
object
scalar
mixed
numeric
Supprimés !
<%
et <%=
... %>
asp_tags
<script language="php">
... </script>
<?
et <?=
sont conservés !
Suppression d'extensions
ext/ereg
→ PCREext/mysql
→ mysqli
Enfin !
Suppression d'extensions
ext/mssql
ext/sybase_ct
ext/imap
et ext/mcrypt
ont été conservées, mais sont basées sur des bibliothèques non maintenues !
Suppression des fonctionnalités obsolètes
new
by referenceset_magic_quotes_runtime()
et magic_quotes_runtime()
dl()
on fpm-fcgi$this
contextSuppression des fonctionnalités obsolètes
mbstring
et iconv
#
dans les fichiers .ini
$is_dst
de mktime()
et gmmktime()
xsl.security_prefs
Suppression des fonctionnalités obsolètes
/e
de preg_replace()
setlocale()
Suppression de SAPIs
sapi/aolserver
sapi/apache
sapi/apache_hooks
sapi/apache2filter
sapi/caudium
sapi/continuity
sapi/isapi
Suppression de SAPIs
sapi/milter
sapi/phttpd
sapi/pi3web
sapi/roxen
sapi/thttpd
sapi/tux
sapi/webjames
switch
+ >1 default
switch (10) {
default:
var_dump("premier default");
break;
default:
var_dump("second default");
break;
}
Fatal error: Switch statements may only contain one default clause
E_DEPRECATED
E_STRICT
transformées en E_DEPRECATED
ou E_NOTICE
ou E_WARNING
"OxAB"
function plop() {
return [
'a' => 'aaa', // Nom d'une fonction
'b' => 'bbb',
'c' => 'ccc',
];
}
function aaa() { var_dump(__FUNCTION__); } // La fonction
function bbb() { var_dump(__FUNCTION__); }
function ccc() { var_dump(__FUNCTION__); }
$fonction = 'plop';
$fonction()['a']();
class MaClasse {
public $propriete;
public function __construct($val) {
$this->propriete = $val;
}
}
$a = new MaClasse(42);
$b = new MaClasse(123);
var_dump( [ $a, $b ][0]->propriete );
class MaClasse {
public function maMethode() {
var_dump(__METHOD__);
}
}
$obj = new MaClasse();
[ $obj, 'maMethode' ]();
class MaClasse {
public static function maMethode() {
var_dump(__METHOD__);
}
}
$methode = 'maMethode';
'MaClasse'::$methode();
Appel d'une fonction anonyme
function ma_fonction() {
var_dump(__FUNCTION__);
}
( function () {
return 'ma_fonction'();
})();
Écriture désormais invalide :
global $$foo->bar;
À remplacer par :
global ${$foo->bar};
Changements
// écriture // PHP 5 // PHP 7
$$foo['bar']['baz'] ${$foo['bar']['baz']} ($$foo)['bar']['baz']
$foo->$bar['baz'] $foo->{$bar['baz']} ($foo->$bar)['baz']
$foo->$bar['baz']() $foo->{$bar['baz']}() ($foo->$bar)['baz']()
Foo::$bar['baz']() Foo::{$bar['baz']}() (Foo::$bar)['baz']()
Casse Magento 1.x ;-)
Oui...
var_dump('10 apples' + '5 oranges');
// Notice: A non well formed numeric value encountered in .../01-warn-invalid-string-arithmetic.php on line 7
// Notice: A non well formed numeric value encountered in .../01-warn-invalid-string-arithmetic.php on line 7
// int(15)
var_dump(10 + "plop");
// Warning: A non-numeric value encountered in .../01-warn-invalid-string-arithmetic.php on line 12
// int(10)
function my_function($a, $b) { ... }
my_function(10);
PHP <= 7.0
Warning: Missing argument 2 for my_function(),
called in ... and defined in ...
int(10)
NULL
PHP >= 7.1
Fatal error: Uncaught Error: Too few arguments to function my_function(),
1 passed in ... and exactly 2 expected in ...
Ne spécifier que les paramètres utiles
htmlspecialchars($string, double_encode => false);
Ou juste s'y retrouver
strpos(hasytack => "foobar", needle => "bar");
Bah non.
while ($cond) {
// loop body
}
or {
// did not enter while loop
}
Non plus.
Pas la façon de faire de PHP.
pthreads
Exactement comme pour n'importe quelle autre montée de version !
Travail tout juste commencé, mais déjà une bonne dizaine de RFCs acceptées ;-)
session_gc()
, session_create_id()
E_WARNING
for invalid container array-accessget_class()
disallow null
parameter
$var = false;
$var[1][2][3][4][5];
// This will throw a single E_WARNING, as accessing ($a[1])[2]
// is attempting to access a IS_VAR chain that is NULL.
$var = array(123);
$var[0][1];
// This will throw an E_WARNING, as accessing $a[0] is valid
// [1] is accessing an integer as an array.
png2wbmp()
and jpeg2wbmp()
HashContext
as ObjectINTL_IDNA_VARIANT_2003
Pour l'instant, à peine évoqué comme cible d'évolutions ou refontes.
Surtout cible de quelques suppressions et bc-breaks, anticipés dès PHP 7.1 et 7.2 par j'ajout de E_DEPRECATED
.
mb_ereg_replace()
eval optionpng2wbmp()
and jpeg2wbmp()
Les six-huit prochains mois vont être intéressants !
L'appel à conférenciers et conférencières est encore ouvert ;-)
Pascal MARTIN
blog.pascal-martin.fr
contact@pascal-martin.fr
@pascal_martin
Meetup « PHP 7.x », Marseille/Aix & Montpellier, 21-22 fév. 2017 — Pascal MARTIN