Joomla, YooTheme and Warp PHP Memory Exhausted Error When Caching Is Turned On
2 Comments Published May 5th, 2011 in Monkey Rant, Monkey Tech.It’s like a dream within a dream within a dream where you dream you’re dreaming…
Or, in this case, replace “dream” with “framework.”

"You created a work-around by over-riding a function to reference a function that wrapped around a function that we were over-riding? Genius!"
In Inception, the movie, if you die in a dream within a dream within a dream you are stuck in limbo – never to wake up. When dealing with a template with a custom framework that interfaces with Joomla that has its own framework, what happens if you have an error deep in the middle of all that code?
Most of the time PHP sends out friendly errors telling you what is broken, where and why. However, if code is stuck in infinite recursion you end up timing out and/or exhausting your available memory. In simpler times, you would only have to sift through one or two scripts to find the break. With frameworks within frameworks it’s a whole different story. Good times…
My client wanted to move to the cloud. I was happy to set them up on an instance with Amazon’s EC2 service. Their site uses Joomla (1.5.22) along with a YooTheme template which, in turn, uses Warp (5.5.15, developed by the YooTheme folks). Everything was moving along nice and smooth until I started to test the newly migrated site with the Joomla module caching turned on.
I load up the home page, no problem. Then, refreshing the home page to pull it from cache…
Crash.
Memory exhausted?
PHP Fatal error: Allowed memory size of xxxxxxxxx bytes exhausted (tried to allocate xxxxxx bytes)…
It really didn’t matter how much memory I gave PHP by updating the “memory_limit” parameter in /etc/php.ini. The application had a voracious appetite for memory. Nothing could satisfy it. That told me that I was dealing with either recursion or some ridiculous database issue (like pulling a million records into memory). I ruled out the database issue and started to focus on infinite recursion as the culprit.
Poking around the code, I found the break point was in the Warp framework’s directory in ./yoo_enterprise/warp/systems/joomla.1.5/helpers/system.php with the following code:
if (!function_exists('mb_strpos')) {
function mb_strpos($haystack, $needle, $offset = false) {
return JString::strpos($haystack, $needle, $offset);
}
}
I commented out that function to discover I hadn’t set up the new box with multibyte support (http://php.net/manual/en/book.mbstring.php).
Call to undefined function mb_strpos()
Oops. However, it would seem the developers of Warp had accounted for this. After all, the comment right above that nifty function stated the following: “mb_strpos function for servers not using the multibyte string extension”
How thoughtful. So why was this failing?
Digging deeper, I looked into the JString method in the Joomla libraries in ./libraries/joomla/utilities/string.php and found this bit of useful code:
function strpos($str, $search, $offset = FALSE)
{
if ( $offset === FALSE ) {
return utf8_strpos($str, $search);
} else {
return utf8_strpos($str, $search, $offset);
}
}
Ah, I see. Joomla devs seemed to have created a useful function for dealing with utf8. I wonder what that function looked like…
Digging into ./libraries/phputf8/mbstring/core.php I found the following:
function utf8_strpos($str, $search, $offset = FALSE) {
if(strlen($str) && strlen($search)) {
if ( $offset === FALSE ) {
return mb_strpos($str, $search);
} else {
return mb_strpos($str, $search, $offset);
}
} else
return FALSE;
}
At this point in the movie Leonardo Dicaprio spins his totem and you wonder if it will ever stop spinning. Well, it will… when it runs out of memory. Yes, Warp’s mb_strpos calls Joomla’s utf8_strpos which, in turn, calls mb_strpos which, of course, has been overwritten by Warp’s mb_strpos which calls Joomla’s utf8_strpos and so on and so on…
Satisfied that I figured out what was the causing the error, I ran the following commands on the box:
sudo yum install php-mbstring.i686 sudo /etc/init.d/httpd restart
And… it works. The site — not the code. I left that broken and tried to report the bug to the devs. Now that I have multibyte support the site bypasses that first function that started this bad dream in the first place.
Of course, I could have just installed php-mbstring as soon as I figured out I needed it but where’s the fun in that when finding recursive black hole code is so much more fun and time consuming?
Update… 5/6/2011 @ 9:25AM
After emailing the devs (I could find no bug tracking system), the devs replied that there actually is a core Joomla function to deal with this issue in libraries/phputf8/native/core.php.
function utf8_strpos($str, $needle, $offset = NULL) {
if ( is_null($offset) ) {
$ar = explode($needle, $str);
if ( count($ar) > 1 ) {
return utf8_strlen($ar[0]);
}
return FALSE;
} else {
if ( !is_int($offset) ) {
trigger_error('utf8_strpos: Offset must be an integer',E_USER_ERROR);
return FALSE;
}
$str = utf8_substr($str, $offset);
if ( FALSE !== ( $pos = utf8_strpos($str, $needle) ) ) {
return $pos + $offset;
}
return FALSE;
}
}
He went on to tell me that the decision to include native/core.php resides in libraries/phputf8/utf8.php
Looking at utf8.php, I find the following:
/**
* Load the smartest implementations of utf8_strpos, utf8_strrpos
* and utf8_substr
*/
if ( !defined('UTF8_CORE') ) {
if ( function_exists('mb_substr') ) {
require_once UTF8 . '/mbstring/core.php';
} else {
require_once UTF8 . '/native/core.php';
}
}
Yes, that’s right… the native implementation is loaded if mb_substr is defined. Since the Warp code is calling the JString method after it defines its own version of mb_substr… well, you get it.
Update… 5/6/2011 @ 9:45AM
The devs responded with the following fix:
This should be placed in warp/systems/joomla.1.5/helpers/system.php just before the first multibyte (mb_) check:
/* Load string class */ require_once(JPATH_ROOT.'/libraries/joomla/utilities/string.php');
By loading that first, Joomla does its job by establishing the correct utf8 function call for the Warp system to use. You can now wake up.
However, it should be noted that performance takes a big hit through the Joomla utf8 work-around. If you can get multibyte support installed, do that first.
2 Responses to “Joomla, YooTheme and Warp PHP Memory Exhausted Error When Caching Is Turned On”
Leave a Reply
You must login to post a comment.

Hey there!
Glad I found this post.
I too am having a server issue with the warp framework using a wordpress theme.
Do you think its a similar issue with wordpress and the utf8 sting?
Thanks,
David
Great post!
This fixed my problem perfectly.
Thank you so much