Updating Magento code to be compatible with PHP 5.3


Even tough PHP 5.3 has been out for quite a while, there is still lots of old code out there that will not run correctly when moved from 5.2 to 5.3. In my case I had to move a 2 year old Magento website to a new server and ran into problems as the default version of PHP on the new server was setup as PHP 5.3. Altough PHP 5.3 is a “minor” version, there is quite a few “deprecated” core functions and severak little things that just dont work the same anymore. So in this post I will explain specifically what functions I had to update and a couple of examples of how I did it in each case.

split()

The split function is deprecated, it might still work for now but will output a warning. The split function can be “converted” in two different ways.

If the split is defined by using a character or simple strings like ‘:’ or “\r\n” it can be converted to explode(). The advantage of explode() being that it is slightly faster then using a regex based function.

If the split is defined by using a regex we have to convert it to using the regex comaptible preg_split() function.

To find occurrences you can use the regex search on [^\._\w]split\( 

single character => split to explode (when  regex ‘\|’ convert to character ‘|’)

split(':', $value)  =>  explode(':', $value)
split(self::MULTI_DELIMITER, $value);  =>  
explode(self::MULTI_DELIMITER, $value);

character class or full regex => split to preg_split

split('[[:space:]]+', trim($uname))  =>
preg_split('/[[:space:]]+/', trim($uname))
split("\r?\n", $headers);  =>  preg_split("/\r?\n/", $headers);
split('(, *)|,', $keywordsString);  =>  
preg_split('/(, *)|,/', $keywordsString);

 

magic_quotes

Magic Quotes is mostly deprecated as of 5.3 and should be disabled by default on any serious PHP installation. Remove all lines containing to avoid warnings:

get_magic_quotes_runtime
set_magic_quotes_runtime

 

eregi()

Change eregi to preg_match and change the existing regex expression. Add slashes to the begining and the end of the existing regex and add the i option at the end to make it case-insensitive. Example: /existing regex/i

Make sure any existing forward slashes / in the existing regex are escaped with a backslash \ (ie: ‘x/y’ becomes ‘/x\/y/i’)

There is many changes to do but here is some examples:

eregi('Windows 9', php_uname())

=>

preg_match('/Windows 9/i', php_uname())
$reg = '^' . str_replace(array('*', '?', '/'), array('.*', '.', '\\/'), $fragment) . '$';
 return eregi($reg, $value);

=>

$reg = '/^' . str_replace(array('*', '?', '/'), array('.*', '.', '\\/'), $fragment) . '$/i';
return preg_match($reg, $value);
eregi('^(http|ftp)://', substr($file, 0, 10))
=>
preg_match('/^(http|ftp):\/\//i', substr($file, 0, 10))

 

ereg()

Same principle as eregi(). Change to preg_match and add slashes at the begining and the end of the existing regex. Don’t add the i option, ereg is not case sensitive.

ereg('^libc-(.*)\.so$', basename(readlink('/lib/libc.so.6')), $matches)
=>
preg_match('/^libc-(.*)\.so$/', basename(readlink('/lib/libc.so.6')), $matches)

 

gd_info() “JPG Support”

Look for calls to gd_info(); The “JPG Support” array key was changed to JPEG Support in PHP 5.3.

$gd_options = gd_info();
if (!$gd_options[‘JPG Support’] ) {

to

if ((!isset($gd_options[‘JPG Support’]) || $gd_options[‘JPG Support’] != true) &&
(!isset($gd_options[‘JPEG Support’]) || $gd_options[‘JPEG Support’] != true)) {

 

__toString()

In PHP 5.3 the __toString() magic method does not accept any parameters. Old code such as the one below will trigger a fatal error.

Fatal error: Method __tostring() cannot take arguments

Try a regex search for function[\s]+__toString\([^\)]+\) to find problematic code.

Changing

public function __toString(array $arrAttributes = array(), $valueSeparator=',') {
    $arrData = $this->toArray($arrAttributes);
    return implode($valueSeparator, $arrData);
}

to

public function __toString() {
    if(func_num_args() == 2) {
        return $this->__invoke(func_get_arg(0), func_get_arg(1));
    } elseif(func_num_args() == 1) {
        return $this->__invoke(func_get_arg(0));
    } else {
        return $this->__invoke();
    }
}

/**
 * Convert object attributes to string
 *
 * @param array $arrAttributes array of required attributes
 * @param string $valueSeparator
 * @return string
 */
public function __invoke(array $arrAttributes = array(), $valueSeparator=',') {
    $arrData = $this->toArray($arrAttributes);
    return implode($valueSeparator, $arrData);
}

 

dl()

Do a regex search for [^_\.\w]dl\( which should only match one or two files in the PEAR folder.

Replace

return @dl('php_'.$ext.$suffix) || @dl($ext.$suffix);

with

// return @dl('php_'.$ext.$suffix) || @dl($ext.$suffix);
// dl() is deprecated in php 5.3
return false;

 

PEAR

Some changes inside the PEAR folders to fix potential issues when it tries to install PEAR packages. However, in general I don’t think the PEAR that shipped with older Magento versions is quite ready for php 5.3. Most likely Magento Connect will not work as expected anymore once the website is moved to a server using php 5.3. This should not be a big problem since you can install your Magento extensions manually.

error_reporting(E_ALL & ~E_NOTICE);

to

error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED);

One response to “Updating Magento code to be compatible with PHP 5.3”