Project: PHP5 technical notes

This article bundles some technical notes regarding eZ publish and the problems it has on PHP5, and solutions to these problems.

External resources

First carefully read this:

Compatibility mode

Enabling zend.ze1_compatibility_mode doesn't seem to help much, it only makes things worser. So make sure you turn it off.

Backward incompatible changes

New reserved keywords

There's a new reserved keyword clone which is used as a function name in several eZ publish classes. PHP will crash because of this with the following parse error:

syntax error, unexpected T_CLONE, expecting T_STRING in ... on line ...

A possible solution to this problem is renaming the clone function to the magic __clone function when appropriate. All calls to the clone function have to be removed too and instead the clone keyword has to be used.

# grep -irP '^[ \t\f]*function clone(' ./*
# grep -ir '\->clone(' ./*

When it's not suitable to replace the clone function with __clone, then rename it to something else.

The function get_class() is now case-sensitive

A possible solution is to search for this function and wrap it inside strtolower.

# grep -irP 'get_class[(][ \t\f]*\$[a-zA-Z0-9]*[ \t\f]*[)]' ./*
 
# find ./ -name "*.php" -exec sed -i 's/\(get_class[(][ \t\f]*\$[a-zA-Z0-9]*[ \t\f]*[)]\)/strtolower( \1 )/g'  {} \;
 
# find ./ -name "*.php" -exec sed -i 's/\(get_class[(][ \t\f]*\$[a-zA-Z0-9]*\->[^)]*)\)/strtolower( \1 )/gI' {} \;  

Another solution is to replace the class names in lower case with class names with the correct case.

Illegal use of string offsets causes E_ERROR instead of E_WARNING

The error looks like:

Fatal error: Cannot use string offset as an array in ... on line ...

These are actually bugs too on PHP4:

PATH_TRANSLATED server variable is no longer set implicitly

This only affects eZWebdavFileServer.

Escaping non-special characters will print the backslash

This affects the glob pattern used to clear the content caches. Also see the PHP manual page on Strings.

array_merge does not longer accept non-array parameters

Luckily array_merge isn't used too many times in the wrong way. Also see #10132.

PHP5 Strict

mysql_list_tables

You will get PHP warnings: "mysql_list_tables() is deprecated". The mysql_list_tables function documentation in the PHP manual mentions the preferred alternative.

strtotime

You will get a warning like this:

Strict standards: strtotime(): It is not safe to rely on the system's timezone settings. Please use the date.timezone setting, the TZ environment variable 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. We selected 'Europe/Paris' for '2.0/DST' instead in filepath on line linenumber

The solution is to set date.timezone in php.ini:

[Date]
; Defines the default timezone used by the date functions
date.timezone = "Europe/Brussels"

mktime

When mktime is called without arguments, you will get this warning:

mktime(): You should be using the time() function instead in filepath on line linenumber

You can replace all calls to mktime without arguments with a call to the time function:

# grep -irl "mktime([ \t\f]*)" ./*
 # find ./ -name "*.php" -exec sed -i 's/mktime([ \t \f]*)/time()/gI' {} \;

Warning: the commands above also match gmmktime. They should be corrected.

is_a(): Deprecated. Please use the instanceof operator

Find the uses of is_a and replace them.

# grep -irl "is_a(" ./*

Fortunately, is_a is used in only one file: kernel/classes/datatypes/ezimage/ezimagealiashandler.php.

var: deprecated. Please use the public/private/protected modifier

A temporary solution is to replace all var declarations with a public declaration.

# find ./ -name "*.php" -exec sed -i 's/^\([ \t\f]*\)var\([ \t\f]*\$\)/\1public\2/g' {} \;

Non-static method someClass::someFunction() should not be called statically

Some eZ publish class methods can be called both statically or on an instance, and $this is being used inside the function to find out in which way it was called. Under PHP 5 this results in some serious problems.

  • Functions should be either static or not.
  • Static functions should be declared with the static keyword.

You can use the API documentation generated by Doxygen to check where specific functions are referenced. However, these references are not always right since the Doxygen parser does not see any difference between a call to the method someFunction on an instance of Foo and a call to the same function on an instance of Bar, although Bar and Foo can be two classes which have nothing in common except that they have functions with an identical name.

You can find some of the troublesome functions with:

# grep -irl "isset( \$this )" .

Some other functions use $this when the default value of one of its parameters is used. Finding these functions is more difficult.

Incompatible function declarations in child classes

You will get warnings about incompatible function declarations. When you extend a class, the function declarations in the child class should be the same as those of the parent class.

  • number of arguments
  • arguments by reference or by value
  • default value or no default value

References

Objects are always passed by reference:

  • function return values
  • function arguments
  • variable assignment

Incorporating PHP5 specific features

Autoloading objects

In PHP 5 the handy __autoload function is introduced. In order to use it at its full potential some things need to be done:

MySQL improved extension

Because the mysqli extension uses objects and not resources like the mysql extension did, an extra shutdown handler is required to save the session before the database object is destroyed when exiting the script. For an explanation read the text in the red box at http://www.php.net/manual/en/function.session-set-save-handler.php. Other resources:

Discovered bugs also affecting PHP4