03 08 2020

例:

Cache::set("name", $value, 3600);


以文件缓存为例


thinkphp/library/think/facade/Cache.php

<?php

class Cache extends Facade
{
    /**
     * 获取当前Facade对应类名(或者已经绑定的容器对象标识)
     * @access protected
     * @return string
     */
    protected static function getFacadeClass()
    {
        return 'cache';
    }
}


门面模式获取Cache的实例,调用set方法,因为不存在set方法,自动调用 __call 方法


thinkphp/library/think/Cache.php

/**
 * 连接缓存
 * @access public
 * @param  array         $options  配置数组
 * @param  bool|string   $name 缓存连接标识 true 强制重新连接
 * @return Driver
 */
public function connect(array $options = [], $name = false)
{
    if (false === $name) {
        $name = md5(serialize($options));
    }

    if (true === $name || !isset($this->instance[$name])) {
        $type = !empty($options['type']) ? $options['type'] : 'File';

        if (true === $name) {
            $name = md5(serialize($options));
        }

        $this->instance[$name] = Loader::factory($type, '\\think\\cache\\driver\\', $options);
    }

    return $this->instance[$name];
}

/**
 * 自动初始化缓存
 * @access public
 * @param  array         $options  配置数组
 * @param  bool          $force    强制更新
 * @return Driver
 */
public function init(array $options = [], $force = false)
{
    if (is_null($this->handler) || $force) {

        if ('complex' == $options['type']) {
            $default = $options['default'];
            $options = isset($options[$default['type']]) ? $options[$default['type']] : $default;
        }

        $this->handler = $this->connect($options);
    }

    return $this->handler;
}

public function __call($method, $args)
{
    return call_user_func_array([$this->init(), $method], $args);
}


通过工厂方法获取  think\cache\driver\File  的实例,调用 set 方法


thinkphp/library/think/cache/driver/File.php

/**
 * 写入缓存
 * @access public
 * @param  string        $name 缓存变量名
 * @param  mixed         $value  存储数据
 * @param  int|\DateTime $expire  有效时间 0为永久
 * @return boolean
 */
public function set($name, $value, $expire = null)
{
    $this->writeTimes++;

    if (is_null($expire)) {
        $expire = $this->options['expire'];
    }

    $expire   = $this->getExpireTime($expire);
    $filename = $this->getCacheKey($name, true);

    if ($this->tag && !is_file($filename)) {
        $first = true;
    }

    $data = $this->serialize($value);

    if ($this->options['data_compress'] && function_exists('gzcompress')) {
        //数据压缩
        $data = gzcompress($data, 3);
    }

    $data   = "<?php\n//" . sprintf('%012d', $expire) . "\n exit();?>\n" . $data;
    $result = file_put_contents($filename, $data);

    if ($result) {
        isset($first) && $this->setTagItem($filename);
        clearstatcache();
        return true;
    } else {
        return false;
    }
}