September 21, 2011

funny zencart class loading issue

Tags: , , ,
Filed under: ZenMagick — DerManoMann @ 11:43 am

Today I came across an interesting issue related to class loading. Someone asked me to look at an out-of-memory issue upgrading a (slightly older) ZenMagick installation to PHP5.3 in order to prepare for a ZenMagick upgrade (good on ya!)

The upgrade seemed to work fine, but just for the homepage. All other pages ran into out-of-memory issues in ZMLoader (may the code rest in peace).

First I thought, ‘oh, well, it has to run out of memory somewhere‘, but with nothing left to analyse I decided to add some debug code to check what the loader was trying to load. Not surprisingly, a lot of actual classes. But then the list changed to just strings. Nothing random, mind, stuff you just remember from looking at zencart code. Here is an example:

resolve class: ZMNetUtils
resolve class: Always Free Shipping
resolve class: ZMAlways Free Shipping
resolve class: /index.php?main_page=static&cat=conditions
resolve class: ZM/index.php?main_page=static&cat=conditions

So as was evident, the (no longer used ‘ZM’ prefixing magic) was causing an endless loop. Still, why would PHP try to resolve those strings as classes?

Further digging lead to this bit of code in zen_not_empty:

} elseif( is_a( $value, 'queryFactoryResult' ) ) {

This is the second else case after a check for an array value. Together with a small note in the PHP docs about un-deprecating is_a in PHP 5.3! things started to make sense.

Every call to zen_not_empty with a value that is not an array will run into the above check and cause a class lookup for the given string (most common case).

So, adding a simple is_object() to the above code sorted the memory issue and also is a performance improvement as it avoids unnecessary class loader lookup:

} elseif( is_object($value) && is_a( $value, 'queryFactoryResult' ) ) {

No Comments

No comments yet.

RSS feed for comments on this post.

Sorry, the comment form is closed at this time.