Search code examples
cachingzend-frameworkmysqliphpbb

ZF1 + phpbb 3.1.5 - problems with $cache->get


Site running ZF1 which links to a phpbb forum.
Updating phpbb from 3.0.12 to 3.1.5 (didn't have this issue in 3.0.12)

Forum works fine when I access it directly.

However when accessing it through the framework
(eg to access user functions like data['user_unread_privmsg'])
I get the following error:

Call to undefined method Zend_Cache_Core::get() in /forum/phpbb/db/driver/mysqli.php on line 119

I've followed this through using xe-debug and it stops at the following function:

/**
    * {@inheritDoc}
    */
    function sql_server_info($raw = false, $use_cache = true)
    {
        global $cache;

        if (!$use_cache || empty($cache) || ($this->sql_server_version = $cache->get('mysqli_version'))  === false)
        {
            $result = @mysqli_query($this->db_connect_id, 'SELECT VERSION() AS version');
            if ($result !== null)
            {
                $row = @mysqli_fetch_assoc($result);

                $this->sql_server_version = $row['version'];

                if (!empty($cache) && $use_cache)
                {
                    $cache->put('mysqli_version', $this->sql_server_version);
                }
            }
            @mysqli_free_result($result);
        }

        return ($raw) ? $this->sql_server_version : 'MySQL(i) ' . $this->sql_server_version;
    }

the exact line causing the error is the following
if (!$use_cache || empty($cache) || ($this->sql_server_version = $cache->get('mysqli_version')) === false)

my ZF cache set-up (which works well for other cache items) looks like this

$cachedir = APPLICATION_PATH . '/public/tmp/cache';

    if (!is_dir($cachedir)) {
        mkdir($cachedir, 0755, true);       // make directory if it doesn't exist
    }

    $frontendOptions = array(
        'lifetime' => 600,
        'automatic_serialization' => true
    );

    $backendOptions = array(
        'cache_dir' => $cachedir
    ); 

    // getting a Zend_Cache_Core object
    $cache = Zend_Cache::factory('Core', 'File', $frontendOptions, $backendOptions);

    Zend_Registry::set("cache", $cache);
    Zend_Db_Table_Abstract::setDefaultMetadataCache($cache);

    $cache = Zend_Cache::factory('Core', 'APC', $frontendOptions);
    Zend_Registry::set("apc_cache", $cache);

Any ideas how to get around this issue ?

(I've deleted the old cache, set tmp/cache permissions to 777 etc)


Solution

  • phpBB uses the $cache variable in a global scope (importing it into function scopes using global $cache). It should be an instance of phpBB's cache class, not the Zend_Cache_Core class.

    Effectively, by assigning this:

    $cache = Zend_Cache::factory('Core', 'File', $frontendOptions, $backendOptions);
    

    you overwrite the global variable set here: https://github.com/phpbb/phpbb/blob/3.1.x/phpBB/includes/compatibility_globals.php and everything explodes.

    phpBB3 was not good at being included together with another script and sharing the same scope and memory. It's got way better lately (and as you see, the file linked is called compatability), but still you have to be careful and code cautiously.