With PHP 5.5 out and many production environments still running 5.2 (or older), it's time to paint a clear picture on why everyone should move to 5.4 and 5.5 and how to get code ready for the latest version of PHP. In this talk, we'll migrate an old piece of code using some standard and some very non-standard tools and techniques.
2. Who am I ?
Wim Godden (@wimgtr)
Founder of Cu.be Solutions (http://cu.be)
Open Source developer since 1997
Developer of OpenX, PHPCompatibility, Nginx SCL, ...
Speaker at PHP and Open Source conferences
3. Why vs How
Part 1 : why upgrade ?
Bad reasons :
It's cool to have the latest version
Annoy sysadmins
Oh cool, a new toy !
Part 2 : how to upgrade ?
The nightmare of compatibility
The joy of automation
No miracles here !
4. Show of hands
3 / 4
5.0
5.1
5.2
5.3
5.4
5.5
6.0 (just kidding)
6. 5.3 quick recap
Namespaces ()
Late static binding
Closures
Better garbage collection
Goto
Mysqlnd
Performance gain
7. 5.3 – people are not even using it !
37.6% still on PHP 5.2
No :
Symfony 2
Zend Framework 2
Other frameworks that need namespaces
Problematic for developers
8. PHP 5.4/5.5 – what's changed ?
New features
Performance and memory usage
Improved consistency
Some things removed
9. New things – short array syntax (5.4)
$yourItems = array('a', 'b', 'c', 'd');
$yourItems = ['a', 'b', 'c', 'd'];
$yourItems = ['a' => 5, 'b' => 3];
10. New things – function array dereferencing (5.4)
function getCars()
{
return array(
'Mini',
'Smart',
'Volvo',
'BMW'
);
}
$cars = getCars();
echo $cars[1];
function getCars()
{
return [
'Mini',
'Smart',
'Volvo',
'BMW'
];
}
echo getCars()[1];
11. New things – Traits
Reuse methods across classes
Classes have no common parent
12. Traits - example
Log output : abcd
trait Logger
{
public function log($data) {
echo "Log output : " . $data;
}
}
class SomeClass {
use Logger;
}
$someObject = new SomeClass();
$someObject->log('abcd');
13. Traits - example
class SomeClass {
public function log($data) {
echo "Log output : " . $data;
}
}
$someObject = new SomeClass();
$someObject->log('abcd');
14. Traits – careful !
trait Logger {
private $foo;
}
class SomeClass {
private $foo;
use Logger;
}
will throw E_STRICT !
15. New things – Webserver (5.4)
Built-in webserver
Development only !
Handles requests sequentially
Ideal for quick testing
Ideal for unit testing of webservices
16. Webserver – how to
/var/www/php54test/html> php -S localhost:8000
PHP 5.4.15 Development Server started at Sat May 2 00:41:12 2013
Listening on http://localhost:8000
Document root is /var/www/php54test/html
Press Ctrl-C to quit.
/var/www/php54test/html> php -S localhost:8000 -t /var/www/other-path/html
PHP 5.4.15 Development Server started at Sat May 2 00:41:12 2013
Listening on http://localhost:8000
Document root is /var/www/other-path/html
Press Ctrl-C to quit.
/var/www/php54test/html> php -S localhost:8000 bootstrap.php
PHP 5.4.15 Development Server started at Sat May 2 00:41:12 2013
Listening on http://localhost:8000
Document root is /var/www/php54test/html
Press Ctrl-C to quit.
17. New things – SessionHandler (5.4)
New session handling class
Groups all methods for session handling :
close()
destroy()
gc()
open()
read()
write()
18. SessionHandler
class MySessionHandler extends SessionHandler
{
public function read($session_id)
{
// Get the session data
}
public function write($session_id, $session_data)
{
// Set the session data
}
...
}
$handler = new MySessionHandler();
session_set_save_handler($handler, true);
session_start();
19. New things – more session stuff (5.4)
File upload extension
→ file upload registers in session
→ readable through AJAX calls
New function session_status()
Return values : PHP_SESSION_ACTIVE / PHP_SESSION_NONE
20. New things – Generators (5.5)
Simple way of implementing iterators
Simply put : foreach over a function
Say what ?
21. Generators - example
<?php
function returnAsciiTable($start, $end) {
for ($i = $start; $i <= $end; $i++) {
yield $i => chr($i);
}
}
foreach (returnAsciiTable(97, 122) as $key => $value) {
echo $key . " - " . $value . "n";
}
Output :
97 - a
98 - b
99 - c
100 - d
101 - e
102 - f
103 - g
104 - h
105 - i
106 - j
107 - k
108 - l
109 - m
110 - n
111 - o
112 - p
113 - q
114 - r
115 - s
116 - t
117 - u
118 - v
119 - w
120 - x
121 - y
122 - z
24. Password hashing (5.5)
To create :
$hash = password_hash($password, PASSWORD_DEFAULT);
To verify :
password_verify($password, $hash);
Currently only supports Blowfish
Also has password_needs_rehash() → check if hash was strong enough
25. Zend Optimizer+ (5.5)
Name in PHP 5.5 : OPcache
Opcode cache (like APC, Xcache, ...)
APC users : no userland (variable) caching in OPcache
→ Use APCu
26. What else is new ?
Binary notation
Decimal : 123
Octal : 0173
Hex : 0x7B
Binary : 0b1111011
Class member access on object instantiation
$fooObj = new Foo();
echo $fooObj->bar();
echo (new Foo)->bar();
New reserved keywords : (5.4)
trait
insteadof
Callable
27. Other changes
Error handling :
5.3 : Parse error: syntax error, unexpected T_STRING, expecting '{' in index.php on line 1
5.4 : Parse error: syntax error, unexpected 'bar' (T_STRING), expecting '{' in index.php on line 1
Array to string conversion :
5.3 : Array
5.4 : Note: Array to string conversion in test.php on line 8
<?= always works (even with short_tags off)
Default charset = UTF8 (be careful !)
class foo bar
$var = array();
echo $var;
28. Time to remove !
register_globals (5.4)
magic_quotes (5.4)
safe_mode (5.4)
Removed (5.4) : Still working :
break $var; break 2;
continue $var; continue 3;
session_register() php_logo_guid()
session_unregister() php_egg_logo_guid()
session_is_registered() php_real_logo_guid()
→ use $_SESSION zend_logo_guid()
(5.4) (5.5)
29. More stuff removed
Timezone guessing → date.timezone in php.ini (5.4)
sqlite extension → use sqlite3 (5.4)
Windows XP and 2003 support (5.5)
30. Performance and memory usage
Performance : 10 – 30%
How ?
Core optimizations
New internal caches (functions, constants, …)
Better (un)serialization
Inlining often-used code paths
…
Reduced memory usage : up to 50% !
Big impact on large frameworks
Even bigger impact on codebases such as Drupal
32. Upgrade : yes / no
Yes No
Using removed extensions x
Using removed functions x
Need extra performance / reduced memory x
Really need new feature x
Want to use recent framework x
No unit tests x
No package available (.rpm, .deb, ...) x
33. Postponing upgrades
End-Of-Life
In the past : we'll see
Now : minor release + 2 = out → EOL
5.5 = OUT → 5.3 = EOL
5.6 = OUT → 5.4 = EOL (next year !)
Critical security patches : 1 year
No bugfixes
Framework support
Developer motivation
34. So you want to upgrade...
Option 1 : run your unit tests
Option 2 : visit each page (good luck !) + check error_log
Or : record visits, then replay log on test environment
Option 3 : automated static analysis
35. Back in 2010...
PHP Architect @ Belgian Railways
8 years of legacy code
40+ different developers
40+ projects
Challenge :
migrate all projects from
PHP 5.1.x (on Solaris)
to
PHP 5.3.x (on Linux)
39. PHPCompatibility
New PHP_CodeSniffer standard
Only purpose : find compatibility issues
Detects :
Deprecated functions
Deprecated extensions
Deprecated php.ini settings and ini_set() calls
Prohibited function names, class names, …
…
Works for PHP 5.0, 5.1, 5.2, 5.3, 5.4 and 5.5
40. PHPCompatibility – making it work
Via GIT :
git clone git://github.com/wimg/PHPCompatibility.git PHPCompatibility
Download from Github :
http://github.com/wimg/PHPCompatibility
Install in <pear_dir>/PHP/CodeSniffer/Standards
Run :
phpcs --standard=PHPCompatibility <path>
42. Important notes
Large directories → can be slow !
Use --extensions=php,phtml
No point scanning .js files
Static analysis
Doesn't run code
Can not detect every single incompatibility
Provides filename and line number
44. Some common apps – phpBB (latest)
FILE: /usr/src/phpBB3/adm/index.php
--------------------------------------------------------------------------------
FOUND 0 ERROR(S) AND 2 WARNING(S) AFFECTING 1 LINE(S)
--------------------------------------------------------------------------------
48 | WARNING | INI directive 'safe_mode' is deprecated in PHP 5.3 and forbidden in PHP 5.4.
48 | WARNING | INI directive 'safe_mode' is deprecated in PHP 5.3 and forbidden in PHP 5.4.
--------------------------------------------------------------------------------
45. Common apps - MediaWiki
FILE: /usr/src/mediawiki-1.19.8/includes/GlobalFunctions.php
--------------------------------------------------------------------------------
FOUND 0 ERROR(S) AND 1 WARNING(S) AFFECTING 1 LINE(S)
--------------------------------------------------------------------------------
2705 | WARNING | The use of function dl is discouraged in PHP version 5.3 and
| | discouraged in PHP version 5.4 and discouraged in PHP version
| | 5.5
--------------------------------------------------------------------------------
46. Common apps – Wordpress (latest)
FILE: /usr/src/wordpress/wp-admin/includes/class-pclzip.php
--------------------------------------------------------------------------------
FOUND 2 ERROR(S) AFFECTING 2 LINE(S)
--------------------------------------------------------------------------------
5340 | ERROR | The use of function set_magic_quotes_runtime is discouraged in
| | PHP version 5.3 and forbidden in PHP version 5.4 and forbidden
| | in PHP version 5.5
5371 | ERROR | The use of function set_magic_quotes_runtime is discouraged in
| | PHP version 5.3 and forbidden in PHP version 5.4 and forbidden
| | in PHP version 5.5
--------------------------------------------------------------------------------
FILE: /usr/src/wordpress/wp-includes/SimplePie/Item.php
--------------------------------------------------------------------------------
FOUND 0 ERROR(S) AND 1 WARNING(S) AFFECTING 1 LINE(S)
--------------------------------------------------------------------------------
125 | WARNING | INI directive 'zend.ze1_compatibility_mode' is deprecated in
| | PHP 5.3 and forbidden in PHP 5.4.
--------------------------------------------------------------------------------
FILE: /usr/src/wordpress/wp-includes/wp-db.php
--------------------------------------------------------------------------------
FOUND 16 ERROR(S) AFFECTING 16 LINE(S)
--------------------------------------------------------------------------------
641 | ERROR | Extension 'mysql_' is deprecated since PHP 5.5 - use mysqli
| | instead.
646 | ERROR | Extension 'mysql_' is deprecated since PHP 5.5 - use mysqli
| | instead.
47. Conclusion
No 100% detection
But : 95% automation = lots of time saved !
First : PHPCompatibility on local machine
Then : upgrade CI/test environment and run unit tests
Start upgrading !
part 2 look at difficulties you might encounter in upgrading. I'll provide solutions not a magician can't solve everything ;-)
5.3.3 = Debian Squeezy = 12% Wait a second... that means people aren't even on 5.3 ? And there was 3 year gap between the release of 5.2 and 5.3, so 5.3 brought a lot of cool things.