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();
}
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();
}然后,我又完成了两个实现类:Cacheable和NoCache:
- 实现具体缓存。
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;
}
}
- 不缓存。
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的中文翻译为假象的原因。