Unknown class E_WARNING

After running the changed files for a few days, I found this in one of the Error Reporting plugin log files

E_WARNING
Unknown class passed as parameter at …../wp-includes/class-IXR.php (326)

referring to a is_subclass_of line. My initial thought was that the unknown class was a non-existant class passed as the first argument. Realizing that this could be prevented by testing for is_object before testing for get_class or is_subclass_of, I ran some more tests.

Using IS object AND (IS class OR IS subclass), instancof, and is_a
Using IS NOT object OR (IS NOT class AND IS NOT subclass), !instancof, and !is_a
And testing an $object that was not a class, a class but not the parent class or a subclass, a subclass, and an instance of the parent class, yielded the following summarized run times

Not obj		iogciso 22	iof 32	isa 63
Not obj 	!iogciso 23	iof 33	!isa 66

other obj 	iogciso 94	iof 36	isa 99
other obj 	!iogciso 93	iof 36	!isa 102

sub obj		iogciso 96	iof 35	isa 98
sub obj 	!iogciso 94	iof 35	!isa 99

parent obj 	iogciso 49	iof 36	isa 103
parent obj 	!iogciso 47	iof 36	!isa 101

As can be seen, all conditional tests were more or less faster when testing a non-object. But when the $object was a class, the addition of the is_object generally negated any perfomance improvements over is_a.

Still uncertain as to whether or not this would in fact prevent possible E_WARNING errors, I read the PHP documentation again and this time noticed

In PHP 5.0, is_a() was deprecated and replaced by the instanceof operator. There were some issues with the initial implementation of instanceof, which relied on __autoload() to search for missing classes. If the class was not present, instanceof would throw a fatal E_ERROR due to the failure of __autoload() to discover that class. The same behaviour occurred in the catch operator and the is_subclass_of() function, for the same reason.
None of these functions or operators call __autoload() in PHP 5.1.x, and the class_exists() workarounds used in code written for PHP 5.0.x, while not problematic in any way, are no longer necessary.

So, as is_subclass_of has the same problems as the instanceof operator, why not just use the easier to read conditional?

Because first testing for is_object had some performance benefit when the $object was a non-class, I put together conditionals that tested for is_class and then used version_compare to determine the value of the PHP_VERSION constant and tested for either instanceof or is_a based on the version. Unfortunately version_compare slowed things down considerably, in some cases more than twice as long as is_object AND (get_class OR is_subclass_of)

Other than testing for the PHP version, the autoload problem can also be avoided by using a string variable in place of the string in both instanceof and is_subclass_of. Because testing for is_object either ran slightly slower or slightly faster depending on the $object, I again ran tests using is_a, instanceof, and get_class OR is_subclass_of conditionals without testing for is_object, this time testing for non-object, other object, subclass, and parent class. Because the NOT conditionals proved to be similar to the IS conditionals I did not test them. Again for 4400000 (4 million 400 thousand) iterations, and running each variation only once this time, the run times were

$test_obj = null	$test_name = 'nonClass'
isa: F isa_run_time: 63.8112490177
iof: F iof_run_time: 27.4505140781
gciso: F gciso_run_time: 37.5824019909

$test_obj = null	$test_name = 'subClass'
isa: F isa_run_time: 62.1618340015
iof: F iof_run_time: 36.1470940113
gciso: F gciso_run_time: 38.2189328671

$test_obj = null	$test_name = 'parentClass'
isa: F isa_run_time: 64.0376930237
iof: F iof_run_time: 31.3636629581
gciso: F gciso_run_time: 37.3621349335

$test_obj = otherClass	$test_name = 'nonClass'
isa: F isa_run_time: 94.293446064
iof: F iof_run_time: 31.2466518879
gciso: F gciso_run_time: 71.0462958813

$test_obj = otherClass	$test_name = 'subClass'
isa: F isa_run_time: 105.786374092
iof: F iof_run_time: 38.7829210758
gciso: F gciso_run_time: 80.2897667885

$test_obj = otherClass	$test_name = 'parentClass'
isa: F isa_run_time: 102.1823318
iof: F iof_run_time: 34.5454649925
gciso: F gciso_run_time: 74.7066178322

$test_obj = subClass	$test_name = 'nonClass'
isa: F isa_run_time: 93.7578001022
iof: F iof_run_time: 30.5689721107
gciso: F gciso_run_time: 69.8373310566

$test_obj = subClass	$test_name = 'subClass'
isa: T isa_run_time: 103.760252953
iof: T iof_run_time: 38.9862082005
gciso: T gciso_run_time: 35.7183160782

$test_obj = subClass	$test_name = 'parentClass'
isa: T isa_run_time: 98.5362439156
iof: T iof_run_time: 35.4245359898
gciso: T gciso_run_time: 77.2220799923

$test_obj = parentClass	$test_name = 'nonClass'
isa: F isa_run_time: 94.5036940575
iof: F iof_run_time: 30.6256258488
gciso: F gciso_run_time: 69.396201849

$test_obj = parentClass	$test_name = 'subClass'
isa: F isa_run_time: 103.611497879
iof: F iof_run_time: 39.3666779995
gciso: F gciso_run_time: 81.0174598694

$test_obj = parentClass	$test_name = 'parentClass'
isa: T isa_run_time: 100.992965221
iof: T iof_run_time: 35.7687740326
gciso: T gciso_run_time: 35.2318360806
Technorati Tags: ,

Post a Comment

Your email is never shared. Required fields are marked *

*
*