Features Download
From: Christian Schmidt <pear.php.net <at> chsc.dk>
Subject: Making old PEAR packages (more) E_STRICT compatible
Newsgroups: gmane.comp.php.pear.devel
Date: Friday 21st September 2007 23:11:30 UTC (over 10 years ago)
New major packages and new major releases are required to be E_STRICT 
compatible, and PEAR2 is visible in the horizon. But a lot of existing 
PEAR packages will probably be around for quite a while yet.

This is a proposal on how to fix the existing PHP4-compatible PEAR 
packages in a way so that they remain PHP4 compatible but can also be 
used from PHP5 with E_STRICT error reporting enabled. It still requires 
some effort by the user, but at least the old packages no longer prevent 
people from turning on E_STRICT error reporting.

Using a custom error handler one can mute E_STRICT errors from 
non-E_STRICT-compliant code, e.g. PEAR. Our error handler begins with 
something like this:

if ($errorNumber == E_STRICT &&
     (strpos($fileName, '/pear/') !== false ||
      preg_match('/^Non-static method (DB|HTTP|Mail|PEAR)::/',
                 $message))) {

However, when using an opcode cache, some warnings cannot be muted this 
way. I don't know much about the inner workings of an opcode cache, but 
using Xcache I have found two types of warnings that are triggered 
before I have a chance to register my own error handler:

#1. "Strict Standards: Assigning the return value of new by reference is 
deprecated." This is caused by code like "$foo =& new Bar()".

#2. "Strict Standards: Declaration of Bicycle::foo() should be 
compatible with that of Vehicle::foo()". This happens when a method is 
overridden in a child class, but the two methods take a different number 
of arguments or similar.

These two types of errors are often easy to fix. In many cases, the fix 
for #1 is to simply replace =& with =. #2 may be fixed by adding dummy 
parameters to one of the methods.

Previously I have manually made these fixes to PEAR packages in order to 
be able to use PEAR and run with E_STRICT error reporting. The package 
owners of Mail, Net_SMTP and DB liked the idea and made changes in 
official release:

This has been very helpful. Now the only problem for me is the last 
lines of PEAR::raiseError(). The solution here is a bit more tricky, 
because here it is not possible to simply replace &= with =. A possible 
solution is to enclose the offending lines in an eval() call, or at 
least do it for PHP4, i.e. something like this:

if (intval(PHP_VERSION) >= 5) {
     if ($skipmsg) {
         $a = new $ec($code, $mode, $options, $userinfo);
     } else {
         $a = new $ec($message, $code, $mode, $options, $userinfo);
} else {
     if ($skipmsg) {
         eval('$a = &new $ec($code, $mode, $options, $userinfo);');
     } else {
         eval('$a = &new $ec($message, $code, $mode, $options, 

My suggestion is to encourage package owners to avoid using the 
constructs #1 and #2. As mentioned, this is often quite easy. In 
particular, the PEAR package should avoid them, as this is required by 
all other packages.

I don't know whether the inability to mute all strict errors is specific 
to Xcache, or whether other opcode caches have the same problem. It has 
been a while since a ran without an opcode cache, but AFAIR there 
weren't any problems back then. Also, I don't know whether there are 
other constructs that has to be avoided, but so far I don't think I have 
met any.

If somebody knows of other ways of solving this problem, I'd be 
interested in hearing about them.

What to you think of this?


PEAR Development Mailing List (http://pear.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php
CD: 3ms