其中我们可以最方便地利用的一个特性就是 Laravel 的服务容器了。在这里我不多赘述 Service Container 是个啥,想了解的可以自行搜索。不想了解的就只要大致知道它是个可以 绑定/取出 实例的东西就好了(当然服务容器可不止这么点功能)。

相信很多 Web 应用都会在数据库建立一个 options 表来储存一些用户的配置信息,而为了方便,我们通常会封装一个 Option 类来方便地进行数据的 get 、 set 操作。而通常的做法是把这些操作做成类内静态方法来调用。

但是这样的弊端就是每一次的操作都要去查询数据库,这对于性能还是有挺大影响的,尤其是在一次响应中要使用很多 options 的情况下。

那么在 Laravel 下我们可以怎么优化呢?

蛤?你说 Eloquent?你 TM 长点脑子啊 

用了 ORM 那 tm 还叫优化?你们呀,不要听的风是得雨,看到 Laravel 就想到 Eloquent!

好吧好吧,再强行 +1s 是要出事的,我们回到正题。没错,我们正是要把 options 放到 Laravel 的服务容器里去。

这样的话我们只需要在应用启动的时候实例化一个 OptionRepository 类,在构造函数里读入所有的 options 并放到类内属性上, get 方法直接从该属性里取值,而调用 set 操作的时候则对该属性进行修改,同时 push 修改过的 key 到一个 $items_modified 数组里去,在对象析构的时候再真正执行数据库操作,写入所有修改过的 options 。

下面我们来定义 OptionRepository 类:

<php namespace App\Services; use DB; use ArrayAccess; use Illuminate\Support\Arr; use Illuminate\Contracts\Config\Repository as ConfigContract; class OptionRepository implements ArrayAccess, ConfigContract { /** * All of the option items. * * @var array */ protected $items = []; protected $items_modified = []; /** * Create a new option repository. * * @return void */ public function __construct() { $options = DB::table('options')->get(); foreach ($options as $option) { $this->items[$option->option_name] = $option->option_value; } } /** * Determine if the given option value exists. * * @param string $key * @return bool */ public function has($key) { return Arr::has($this->items, $key); } /** * Get the specified option value. * * @param string $key * @param mixed $default * @return mixed */ public function get($key, $default = null) { return Arr::get($this->items, $key, $default); } /** * Set a given option value. * * @param array|string $key * @param mixed $value * @return void */ public function set($key, $value = null) { if (is_array($key)) { foreach ($key as $innerKey => $innerValue) { Arr::set($this->items, $innerKey, $innerValue); $this->items_modified[] = $innerKey; } } else { Arr::set($this->items, $key, $value); $this->items_modified[] = $key; } } protected function save() { $this->items_modified = array_unique($this->items_modified); foreach ($this->items_modified as $key) { if (!DB::table('options')->where('option_name', $key)->first()) { DB::table('options') ->insert(['option_name' => $key, 'option_value' => $this[$key]]); } else { DB::table('options') ->where('option_name', $key) ->update(['option_value' => $this[$key]]); } } } /** * Prepend a value onto an array option value. * * @param string $key * @param mixed $value * @return void */ public function prepend($key, $value) { $array = $this->get($key); array_unshift($array, $value); $this->set($key, $array); } /** * Push a value onto an array option value. * * @param string $key * @param mixed $value * @return void */ public function push($key, $value) { $array = $this->get($key); $array[] = $value; $this->set($key, $array); } /** * Get all of the option items for the application. * * @return array */ public function all() { return $this->items; } /** * Determine if the given option option exists. * * @param string $key * @return bool */ public function offsetExists($key) { return $this->has($key); } /** * Get a option option. * * @param string $key * @return mixed */ public function offsetGet($key) { return $this->get($key); } /** * Set a option option. * * @param string $key * @param mixed $value * @return void */ public function offsetSet($key, $value) { $this->set($key, $value); } /** * Unset a option option. * * @param string $key * @return void */ public function offsetUnset($key) { $this->set($key, null); } /** * Save all modified options into database */ public function __destruct() { $this->save(); } } 可以看到我们顺便实现了 ArrayAccess 接口,所以我们在拿到 OptionRepository 的实例后就可以使用类似于 $option['fuck'] 的形式来获取数据了(其实我后来一次也没用到)。

不过光是实现了一个 Repository 还是不够的,我们还需要把它绑定到服务容器里,同时注册个 Facade 给它,让我们能够更优雅地调用仓库类的相关方法:

class AppServiceProvider extends ServiceProvider { /** * Register any application services. * * @return void */ public function register() { // 绑定单例到服务容器上 $this->app->singleton('option', \App\Services\OptionRepository::class); } }

新建一个 Option 类并集成 Laravel 的 Facade 基类:

<?php namespace App\Services\Facades; use \Illuminate\Support\Facades\Facade; class Option extends Facade { /** * Get the registered name of the component. * * @return string */ protected static function getFacadeAccessor() { return 'option'; } }

然后我们在 config/app.php 中加入我们 Facade 的别名:

<?php return [ 'aliases' => [ 'Option' => App\Services\Facades\Option::class ], ];

怎么使用 Laravel 的服务容器来优化读写数据库中的 options关键词的更多相关文章

  1. php--理解PHP的依赖注入和laravel的服务容器

    写在前面 为了了解laravel的服务容器在网上搜了许多文章,其中大多数都有其侧重点,没有很系统的一套东西以供参考,看完之后仍觉似乎少了一根把他们串起来的绳子,近期有幸拜读了陈昊的<Larave ...

  2. Laravel开发:Laravel核心——服务容器的细节特性

    前言 在前面几个博客中,我详细讲了 Ioc 容器各个功能的使用.绑定的源码.解析的源码,今天这篇博客会详细介绍 Ioc 容器的一些细节,一些特性,以便更好地掌握容器的功能. 注:本文使用的测试类与测试 ...

  3. Laravel 学习笔记 —— 神奇的服务容器 [转]

    容器,字面上理解就是装东西的东西.常见的变量.对象属性等都可以算是容器.一个容器能够装什么,全部取决于你对该容器的定义.当然,有这样一种容器,它存放的不是文本.数值,而是对象.对象的描述(类.接口)或 ...

  4. laravel服务容器-----深入理解控制反转(IoC)和依赖注入(DI)

    首先大家想一想什么是容器,字面意思就是盛放东西的东西,常见的变量,对象属性都是容器,一个容器能够装什么东西,完全在于你对这个容器的定义.有的容器不仅仅只是存文本,变量,而是对象,属性,那么我们通过这种 ...

  5. laravel 服务容器

    服务容器,也叫IOC容器,其实包含了依赖注入(DI)和控制反转(IOC)两部分,是laravel的真正核心.其他的各种功能模块比如 Route(路由).Eloquent ORM(数据库 ORM 组件) ...

  6. laravel 服务容器实例——深入理解IoC模式

    刚刚接触laravel,对于laravel的服务容器不是很理解.看了<Laravel框架关键技术解析>和网上的一些资料后对于服务容器有了一些自己的理解,在这里分享给大家 1.依赖 IoC模 ...

  7. Laravel 服务容器实例教程 —— 深入理解控制反转(IoC)和依赖注入(DI)

    容器,字面上理解就是装东西的东西.常见的变量.对象属性等都可以算是容器.一个容器能够装什么,全部取决于你对该容器的定义.当然,有这样一种容器,它存放的不是文本.数值,而是对象.对象的描述(类.接口)或 ...

  8. laravel 学习笔记 —— 神奇的服务容器

    转载自:https://www.insp.top/learn-laravel-container 容器,字面上理解就是装东西的东西.常见的变量.对象属性等都可以算是容器.一个容器能够装什么,全部取决于 ...

  9. Laravel开发:Laravel核心——Ioc服务容器

    服务容器 在说 Ioc 容器之前,我们需要了解什么是 Ioc 容器. Laravel 服务容器是一个用于管理类依赖和执行依赖注入的强大工具. 在理解这句话之前,我们需要先了解一下服务容器的来龙去脉:  ...

随机推荐

  1. Chrome控制台调试工具用法

    下面我们来看看console里面具体提供了哪些方法可以供我们平时调试时使用. Console API 当打开 firebug (也包括 Chrome 等浏览器的自带调试工具),window 下面会注册 ...

  2. AngularJs赋值问题

    $scope.showUpgradeForm = function(item){ $scope.upgrade = item; $scope.upgrade.vercode++; // 其它操作 } ...

  3. 一个前端html模板处理引擎(javascript) - pure

    做后台开发(java/python)的同学开发web应用,对于前端页面生成技术并不陌生,像jsp,freemark等.开发UGC类型的互联网站,因为要SEO友好,所以一般都会在后台用模板引擎直接生成好 ...

  4. 文本属性Attributes

    1.NSKernAttributeName: @10 调整字句 kerning 字句调整 2.NSFontAttributeName : [UIFont systemFontOfSize:_fontS ...

  5. UIAlertView

    1.Title 获取或设置UIAlertView上的标题. 2.Message 获取或设置UIAlertView上的消息 UIAlertView *alertView = [[UIAlertViewa ...

  6. CNContact对通讯录的基本使用(第二篇)

    /** * 注意:iOS9才有能使用 * 首先在工程里导入ContactsUI.framework和Contacts.framework两个框架 * * * 源代码的链接地址 * 链接: http:/ ...

  7. Java基础之处理事件——添加工具栏(Sketcher 7 with File toolbar buttons)

    控制台程序. 工具栏在应用程序窗口中通常位于内容面板顶部的菜单栏下,包含直接访问菜单选项的按钮.在Sketcher程序中可以为最常用的菜单项添加工具栏. 工具栏是javax.swing.JToolBa ...

  8. 从零开始攻略PHP(9)——错误和异常处理

    1.Exception类 这个类是PHP为异常处理提供的内置类.构造函数的两个参数分别是错误消息和错误代码. 除了构造函数之外,该类还提供了如下的内置方法: · getCode() 返回传递给构造函数 ...

  9. Java数组(初学者必看)

    数组无论在哪种编程语言中都算是最重要的数据结构之一,同时不同语言的实现及处理也不尽相同.但凡写过一些程序的人都知道数组的价值及理解数组的重要性,与链表一道,数组成为了基本的数据结构.尽管Java提供了 ...

  10. PostgreSQL Configuration – managing scary settings

    When it comes to highly available database servers and configuration, a very important aspect is whe ...