Codeigniter Memcached

2019-05-27 02:59发布

问题:

I am unlucky figuring why does memcached not working properly.

PHP Info Details which is already enabled:

memcache support | enabled
Active persistent connections | 0
Version | 2.2.6
Revision | $Revision: 303962 $

etc...

Loading Driver

$this->load->driver('cache',array('adapter'=>'mecached'));

Error Response:

get() on a non-object in /system/libraries/Cache/drivers/Cache_memcached.php on line 50

When I try to use this code

var_dump(var_dump($this->cache->memcached->is_supported()));

Response: bool(false)

I also check this forum topic

http://codeigniter.com/forums/viewthread/180005/#855216

It seems memcache still not working.

回答1:

Seems you have an older version of Codeigniter. Your server has Memcache extension enable, but codeigniter's Cache driver is expecting Memcached to be installed. "Johnbellone" added support for both Memcached extensions about a year ago. Details here.



回答2:

When running Memcache under windows, be carefull with just changing Memcached to Memcache in system/libraries/Cache/drivers/Cache_memcached.php.

This will make Memcache work, but it will not make your items expire properly since Memcache uses the 4rd parameter as TTL and Memcached uses the 3rd parameter as TTL and CI only accepts 3 parameters.

To overcome this (and to make it work both with Memcache and Memcached) you need to make the following changes to system/libraries/Cache/drivers/Cache_memcached.php.

1) Declare a new property private $_is_memcache = FALSE;

2) Change the function save() as follows:

public function save($id, $data, $ttl = 60)
{
    if($this->_is_memcache) {
        return $this->_memcached->add($id, array($data, time(), $ttl), FALSE, $ttl);
    } else {
        return $this->_memcached->add($id, array($data, time(), $ttl), $ttl);
    }
}

3) In the function _setup_memcached() replace the line $this->_memcached = new Memcached(); with:

if(class_exists("Memcached")) {
    $this->_memcached = new Memcached();
} else {
    $this->_memcached = new Memcache();
    $this->_is_memcache = TRUE;
}

4) In the function is_supported () replace the line if ( ! extension_loaded('memcached')) with:

if ( !extension_loaded('memcached') && !extension_loaded('memcache'))

Complete class

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
 * CodeIgniter
 *
 * An open source application development framework for PHP 4.3.2 or newer
 *
 * @package     CodeIgniter
 * @author      ExpressionEngine Dev Team
 * @copyright   Copyright (c) 2006 - 2011 EllisLab, Inc.
 * @license     http://codeigniter.com/user_guide/license.html
 * @link        http://codeigniter.com
 * @since       Version 2.0
 * @filesource  
 */

// ------------------------------------------------------------------------

/**
 * CodeIgniter Memcached Caching Class 
 *
 * @package     CodeIgniter
 * @subpackage  Libraries
 * @category    Core
 * @author      ExpressionEngine Dev Team
 * @link        
 */

class CI_Cache_memcached extends CI_Driver {

    private $_memcached;            // Holds the memcached object
    private $_is_memcache = FALSE;  // Identifies wether it's Memcache instead of Memcached

    protected $_memcache_conf   = array(
                    'default' => array(
                        'default_host'      => '127.0.0.1',
                        'default_port'      => 11211,
                        'default_weight'    => 1
                    )
                );

    // ------------------------------------------------------------------------ 

    /**
     * Fetch from cache
     *
     * @param   mixed       unique key id
     * @return  mixed       data on success/false on failure
     */ 
    public function get($id)
    {   
        $data = $this->_memcached->get($id);

        return (is_array($data)) ? $data[0] : FALSE;
    }

    // ------------------------------------------------------------------------

    /**
     * Save
     *
     * @param   string      unique identifier
     * @param   mixed       data being cached
     * @param   int         time to live
     * @return  boolean     true on success, false on failure
     */
    public function save($id, $data, $ttl = 60)
    {
        if($this->_is_memcache) {
            return $this->_memcached->add($id, array($data, time(), $ttl), FALSE, $ttl);
        } else {
            return $this->_memcached->add($id, array($data, time(), $ttl), $ttl);
        }
    }

    // ------------------------------------------------------------------------

    /**
     * Delete from Cache
     *
     * @param   mixed       key to be deleted.
     * @return  boolean     true on success, false on failure
     */
    public function delete($id)
    {
        return $this->_memcached->delete($id);
    }

    // ------------------------------------------------------------------------

    /**
     * Clean the Cache
     *
     * @return  boolean     false on failure/true on success
     */
    public function clean()
    {
        return $this->_memcached->flush();
    }

    // ------------------------------------------------------------------------

    /**
     * Cache Info
     *
     * @param   null        type not supported in memcached
     * @return  mixed       array on success, false on failure
     */
    public function cache_info($type = NULL)
    {
        return $this->_memcached->getStats();
    }

    // ------------------------------------------------------------------------

    /**
     * Get Cache Metadata
     *
     * @param   mixed       key to get cache metadata on
     * @return  mixed       FALSE on failure, array on success.
     */
    public function get_metadata($id)
    {
        $stored = $this->_memcached->get($id);

        if (count($stored) !== 3)
        {
            return FALSE;
        }

        list($data, $time, $ttl) = $stored;

        return array(
            'expire'    => $time + $ttl,
            'mtime'     => $time,
            'data'      => $data
        );
    }

    // ------------------------------------------------------------------------

    /**
     * Setup memcached.
     */
    private function _setup_memcached()
    {
        // Try to load memcached server info from the config file.
        $CI =& get_instance();
        if ($CI->config->load('memcached', TRUE, TRUE))
        {
            if (is_array($CI->config->config['memcached']))
            {
                $this->_memcache_conf = NULL;

                foreach ($CI->config->config['memcached'] as $name => $conf)
                {
                    $this->_memcache_conf[$name] = $conf;
                }               
            }           
        }

        if(class_exists("Memcached")) {
            $this->_memcached = new Memcached();
        } else {
            $this->_memcached = new Memcache();
            $this->_is_memcache = TRUE;
        }

        foreach ($this->_memcache_conf as $name => $cache_server)
        {
            if ( ! array_key_exists('hostname', $cache_server))
            {
                $cache_server['hostname'] = $this->_default_options['default_host'];
            }

            if ( ! array_key_exists('port', $cache_server))
            {
                $cache_server['port'] = $this->_default_options['default_port'];
            }

            if ( ! array_key_exists('weight', $cache_server))
            {
                $cache_server['weight'] = $this->_default_options['default_weight'];
            }

            $this->_memcached->addServer(
                    $cache_server['hostname'], $cache_server['port'], $cache_server['weight']
            );
        }
    }

    // ------------------------------------------------------------------------


    /**
     * Is supported
     *
     * Returns FALSE if memcached is not supported on the system.
     * If it is, we setup the memcached object & return TRUE
     */
    public function is_supported()
    {
        if ( !extension_loaded('memcached') && !extension_loaded('memcache'))
        {
            log_message('error', 'The Memcached Extension must be loaded to use Memcached Cache.');

            return FALSE;
        }

        $this->_setup_memcached();
        return TRUE;
    }

    // ------------------------------------------------------------------------

}
// End Class

/* End of file Cache_memcached.php */
/* Location: ./system/libraries/Cache/drivers/Cache_memcached.php */