Laravel 的核心概念


工欲善其事,必先利其器。在开发Xblog的过程中,稍微领悟了一点Laravel的思想。确实如此,这篇文章读完你可能并不能从无到有写出一个博客,但知道Laravel的核心概念之后,当你再次写起Laravel时,会变得一目了然胸有成竹。

源码点击这里):

namespace App\Contracts;
use Closure;
interface XblogCache
{
    public function setTag($tag);
    public function setTime($time_in_minute);
    public function remember($key, Closure $entity, $tag = null);
    public function forget($key, $tag = null);
    public function clearCache($tag = null);
    public function clearAllCache();
}

然后,我又完成了两个实现类:CacheableNoCache

  1. 实现具体缓存。
class Cacheable implements XblogCache
{
    public $tag;
    public $cacheTime;
    public function setTag($tag)
    {
        $this->tag = $tag;
    }
    public function remember($key, Closure $entity, $tag = null)
    {
        return cache()->tags($tag == null ? $this->tag : $tag)->remember($key, $this->cacheTime, $entity);
    }
    public function forget($key, $tag = null)
    {
        cache()->tags($tag == null ? $this->tag : $tag)->forget($key);
    }
    public function clearCache($tag = null)
    {
        cache()->tags($tag == null ? $this->tag : $tag)->flush();
    }
    public function clearAllCache()
    {
        cache()->flush();
    }
    public function setTime($time_in_minute)
    {
        $this->cacheTime = $time_in_minute;
    }
}
  1. 不缓存。
class NoCache implements XblogCache
{
    public function setTag($tag)
    {
    // Do Nothing
    }
    public function setTime($time_in_minute)
    {
    // Do Nothing
    }
    public function remember($key, Closure $entity, $tag = null)
    {
        /**
         * directly return
         */
        return $entity();
    }
    public function forget($key, $tag = null)
    {
        // Do Nothing
    }
    public function clearCache($tag = null)
    {
        // Do Nothing
    }
    public function clearAllCache()
    {
        // Do Nothing
    }
}

然后再利用容器的绑定,根据不同的配置,返回不同的实现(源码):

public function register()
{
    $this->app->bind('XblogCache', function ($app) {
        if (config('cache.enable') == 'true') {
            return new Cacheable();
        } else {
            return new NoCache();
        }
    });
}

这样,就实现了缓存的切换而不需要更改你的具体逻辑代码。当然依靠接口而不依靠具体实现的好处不仅仅这些。实际上,Laravel所有的核心服务都是实现了某个Contracts接口(都在Illuminate\Contracts\文件夹下面),而不是依赖具体的实现,所以完全可以在不改动框架的前提下,使用自己的代码改变Laravel框架核心服务的实现方式。

说一说Facades。在我们学习了容器的概念后,Facades就变得十分简单了。在我们把类的实例绑定到容器的时候相当于给类起了个别名,然后覆盖Facade的静态方法getFacadeAccessor并返回你的别名,然后你就可以使用你自己的Facade的静态方法来调用你绑定类的动态方法了。其实Facade类利用了__callStatic() 这个魔术方法来延迟调用容器中的对象的方法,这里不过多讲解,你只需要知道Facade实现了将对它调用的静态方法映射到绑定类的动态方法上,这样你就可以使用简单类名调用而不需要记住长长的类名。这也是Facades的中文翻译为假象的原因。

https://lufficc.com/blog/the-core-conception-of-laravel