I received another report from a user experiencing blank pages on some of the wp-SwimTeam tabs. I had run into this previously and determined it to be a PHP issue in the early 5.3.x releases (.1 and .2 for sure). PHP was terminating with a fatal error which resulted in an incomplete HTML page. If you looked at the page source for these “blank” pages you would see nice HTML simply terminate with no closing tags which obviously resulted in missing content.
It turns out that phpHtmlLib was the culprit (which I suspected) and it was behavior that is inconsistent between releases of PHP including PHP4.
Many of the widgets in phpHtmlLib build upon one another by extending classes. It is not uncommon to find some classes that are extended 3-4 levels. No problem, that is one of the beauties of classes. The problem came from some classes having constructors where some of their descendants did not AND the grand child (or great grand child) class referenced the parent constructor.
Because phpHtmlLib originated in PHP4, all of the syntax remains in PHP4 format including the use of class constructors. The following example illustrates the problem I had run into:
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
class Sample_A {
/**
* Constructor
*/
function Sample_A() {
printf('<h3>%s::%s - Sample A Constructor</h3>', basename(__FILE__), __LINE__);
}
}
class Sample_B extends Sample_A {
/**
* No Constructor!
*/
}
class Sample_C extends Sample_B {
/**
* Constructor
*/
function Sample_C() {
printf('<h4>%s::%s - Sample C Constructor</h4>', basename(__FILE__), __LINE__);
parent::Sample_B() ;
}
}
ini_set('display_errors','stdout');
error_reporting(E_STRICT | E_ALL) ;
printf('<h2>%s::%s - Instantiating Sample A</h2>', basename(__FILE__), __LINE__);
$A = new Sample_A() ;
printf('<h2>%s::%s - Instantiating Sample B</h2>', basename(__FILE__), __LINE__);
$B = new Sample_B() ;
printf('<h2>%s::%s - Instantiating Sample C</h2>', basename(__FILE__), __LINE__);
$C = new Sample_C() ;
?>
Running the code above results in the following with certain versions of PHP (e.g. 5.3.1).
<h2>sample.php::33 - Instantiating Sample A</h2>
<h3>sample.php::9 - Sample A Constructor</h3>
<h2>sample.php::35 - Instantiating Sample B</h2>
<h3>sample.php::9 - Sample A Constructor</h3>
<h2>sample.php::37 - Instantiating Sample C</h2>
<h4>sample.php::24 - Sample C Constructor</h4>
Fatal error: Call to undefined method Sample_B::Sample_B() in /var/www/clients/client3/web44/web/sample.php on line 25
Why does this happen? It turns out that earlier (and now later) versions of PHP would handle the missing constructor in Sample_B implicitly. Because some constructors are fairly complex and pass multiple arguments, I don’t really want to add all of the intermediate constructors just because some versions of PHP don’t handle the constructor chain properly (or at least consistently). So I came up with the following solution:
class Sample_B extends Sample_A {
/**
* Constructor - needed for early PHP 5.3.x compatibility
*
* @param Parent Constructor
* @param array of Constructor Arguments
*/
function Sample_B() {
call_user_func_array('parent::Sample_A', func_get_args()) ;
}
}
Adding this constructor to the Sample_B class results in the following (which is what I want):
<h2>sample.php::39 - Instantiating Sample A</h2>
<h3>sample.php::9 - Sample A Constructor</h3>
<h2>sample.php::41 - Instantiating Sample B</h2>
<h3>sample.php::9 - Sample A Constructor</h3>
<h2>sample.php::43 - Instantiating Sample C</h2>
<h4>sample.php::30 - Sample C Constructor</h4>
<h3>sample.php::9 - Sample A Constructor</h3>
There is a chance there are more places within phpHtmlLib that could have this problem with some versions of PHP5.3.x. Now that I know how to solve them, fixing them is pretty simple and very quick. If you run into any blank pages within wp-SwimTeam, let me know ASAP and more than likely a solution like the above within phpHtmlLib will address the issue.
The phpHtmlLib plugin has been updated to v2.6.4.3566 and committed to the WordPress plugin repository.