Migrating to PHP 5.4
Adam Harvey
aharvey@php.net @LGnome
Removed features
register_globals
register_globals: old
http://your.server/script.php?foo=bar
register_globals: old
http://your.server/script.php?foo=bar echo 'Hello '.htmlspecialchars($foo);
register_globals: old
if ($admin) { // God mode! }
register_globals: old
http://your.server/script.php?admin=1 if ($admin) { // God mode! }
Kneel before Zod
register_globals: new
http://your.server/script.php?foo=bar echo 'Hello '.htmlspecialchars($_GET['foo']);
register_globals: bad option
extract($_REQUEST);
register_globals: better option
magic_quotes_gpc
Magic quotes
http://your.server/script.php?foo=double+quote+"
Magic quotes
http://your.server/script.php?foo=double+quote+" $_GET['foo']: double quote \"
This is, of course, completely sane
Implicit addslashes()
Magic quotes: bad option
foreach (array($_GET, $_POST, $_COOKIE) as &$a) { array_walk($a, function (&$v, $k) { return addslashes($v); }); }
Magic quotes: better option
A slight digression into the evils of addslashes()
Database escaping through the ages
PHP ≤ 4.0.2
PHP 4.0.3 — 4.2.3
PHP 4.3.0 — 4.4.9
PHP ≥ 5.0.0
Who cares?
Internationalisation
WHAT.
The Biting Pear of Salamanca by Ursula Vernon
So, in Big5…
Boom!
United States Federal Government (public domain)
It turns out that isn't an escape character
Use prepared queries!
Safe mode
The Safety Dance
Safe mode
Safe mode: alternatives
Sessions
Sessions: old
$foo = 'bar'; session_register('foo'); if (session_is_registered('foo')) { session_unregister('foo'); }
Sessions: new
$_SESSION['foo'] = 'bar'; if (isset($_SESSION['foo'])) { unset($_SESSION['foo']); }
SQLite
SQLite 2
SQLite 2
$dbh = sqlite_open('my.db'); $rst = sqlite_query('SELECT * FROM t'); if ($rst) { $row = sqlite_fetch_array($rst); } else { echo 'Query failed'; }
SQLite 3 with ext/sqlite3
$dbh = new SQLite3('my.db'); $rst = $dbh->query('SELECT * FROM t'); if ($rst) { $row = $rst->fetchArray(); } else { echo 'Query failed'; }
SQLite 3 with PDO
$dbh = new PDO('sqlite:'.realpath('my.db')); $rst = $dbh->query('SELECT * FROM t'); if ($rst) { $row = $rst->fetch(); } else { echo 'Query failed'; }
Call time pass by reference
Call time pass by reference
function func($f) { $f = 42; } $foo = 6 * 9; func(&$foo);
Call time pass by reference
function func(&$f) { $f = 42; } $foo = 6 * 9; func($foo);
Time zones
Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier.
Time zones
Gotchas
Character set
header('Content-Type: text/html; charset=UTF-8');
Errors
crypt()
Other gotchas
Deprecated features
Deprecated features
New features
Traits
Ctrl-C
Ctrl-V
Traits
trait Hello { public function hello() { echo "Hello!"; } } class Greeter { use Hello; }
Traits
class Greeter { public function hello() { echo "Hello!"; } }
Traits
trait Hello { public function hello() { echo "Hello!"; } } class Greeter { use Hello; } $greeter = new Greeter; $greeter->hello();
Hello!
Closure binding
class Greeter { public function say() { echo "Hello!\n"; } } class Fareweller { public function say() { echo "Goodbye!\n"; } }
Closure binding
class Greeter { public function say() { echo "Hello!\n"; } } class Fareweller { public function say() { echo "Goodbye!\n"; } } $say = function () { return $this->say(); };
Closure binding
class Greeter { public function say() { echo "Hello!\n"; } } class Fareweller { public function say() { echo "Goodbye!\n"; } } $say = function () { return $this->say(); }; $hello = $say->bindTo(new Greeter); $goodbye = $say->bindTo(new Fareweller); $hello(); $goodbye();
Hello!
Goodbye!
Parser improvements
Arrays
$temp = arrayFunction(); $value = $temp['key'];
Arrays
$temp = arrayFunction(); $value = $temp['key']; $value = arrayFunction()['key'];
More arrays
$list = array(1, 2, 3); $assoc = array('a' => 1, 'b' => 2, 'c' => 3);
More arrays
$list = array(1, 2, 3); $assoc = array('a' => 1, 'b' => 2, 'c' => 3); $list = [1, 2, 3]; $assoc = ['a' => 1, 'b' => 2, 'c' => 3];
Objects
$temp = new DateTime(); $temp->format('r');
Objects
$temp = new DateTime(); $temp->format('r'); (new DateTime())->format('r');
Speed
5.3.8 5.4.0 RC1 δ
Wordpress 7.02 7.28 3.70%
Drupal 7.07 7.17 1.41%
Joomla! 5.99 5.73 -4.34%
SilverStripe 8.25 8.67 5.09%
Requests per second
Average of three benchmarks after discarding the first invocation
PHP invoked via FastCGI under lighttpd
Current stable versions of each package were tested
Other improvements
When?
SOON
Evil Pumpkin by Martin Cathrae (Licence: CC-BY-SA 2.0)
When?
Please help!
Questions?