Laravel 5项目初始设置最佳实践


Laravel 5 project initial settings best practices

我有一个应用程序,存储配置设置到数据库

数据库表由两个文本列keyvalue组成。

我想在应用程序开始时读取所有值一次,然后通过

使其可用于整个应用程序

MySettings::set(key, value)MySettings::get(key)

我相信最好的方法是通过$app->singleton,但由于我是Laravel的新手,我真的无法理解这是如何完成的:

当然,如果有更好的方法(不需要单例),我很乐意知道如何做到这一点。

通常人们将他们的配置细节保存在.env文件中。在laravel文档中阅读env。我在这里写了一篇关于env使用的长篇文章。在数据库中保存值是没有必要的,也可能不建议,直到你有一些其他的配置,你需要在数据库中保存conf值。

但是如果你想这样做,你可以从数据库中获取所有变量,并将其保存在PHP superglobal variables中。点击这里阅读。

从这些变量中拿出你的图片,仔细阅读它们以及它们被使用的原因。然后选择一个最适合你的。$_ENV似乎适合你的情况。

你说

:

我想读取所有的值一次在我的应用程序的开始

我认为你还没有清楚地理解整个请求响应阶段。你的应用程序没有"启动"这样的事情。每次请求到达服务器时,你的应用程序启动,准备所有的变量并将它们加载到内存中。一旦发送响应,一切都将被销毁。因此,即使您保留一个单例类,它也会在每次请求时被一次又一次地创建。但是,session, cookie等是持久的,它们不会消失。

更新1:

因此,使用超全局变量被认为是一种不好的做法。所以回到最初的问题——如何在Laravel中创建一个单例类。假设我们在L5上,我们可以简单地:
  1. 自动装载composer.json
  2. 遵循命名空间

这两种技术在这里都有很好的解释。


更新2:如何在L5中创建作为Provider的单例类

这是我最近才知道的一种非常简洁的技术,它完全符合提问者的需要。

基于Laravel架构,当服务器端收到请求时,Laravel启动并binds一些服务,如Auth, Cache等。同样,你也可以绑定自己的Provider,这样在启动时,你的类将自动实例化,你可以在整个应用程序中使用它们。

步骤1:使用php artisan命令创建ServiceProvider:

php artisan make:provider DatabaseConfigurationServiceProvider

这将在你的Providers文件夹中创建一个提供商。

步骤2:像这样填充你的新类:

<?php
namespace App'Providers;
use App'Services'DatabaseConfigurationService;
use Illuminate'Support'ServiceProvider;
class DatabaseConfigurationServiceProvider extends ServiceProvider
{
    protected $defer = true;
    public function boot()
    {
    }
    public function register()
    {
        $this->app->singleton('dbconf', function() {
            return new DatabaseConfigurationService();
        });
    }
    public function provides()
    {
        return ['dbconf'];
    }
}

我们在这里做的是:

  • 扩展ServiceProvider。所有的供应商都必须这样做。
  • 使defer为true,因为我们不想在每个请求上加载此配置。相反,我们希望在需要时加载这个类。如果你想在每个请求上加载你的配置,那么你把这个值设为true,然后也删除整个provides()函数,因为我们不再需要它了。然后会发生的是,每次新的请求来了,这个类将被调用,它将加载所有的数据库配置值,并将存储它们,直到请求被处理。然后我们重写register()方法,将这个提供程序注册到你想调用的类中。我们注册了一个名称dbconf,它随后成为全局$app变量的标识符,我们还绑定了一个类DatabaseConfigurationService()。注意,这个类将在后面定义。还要注意,这个class is binded in a单例fashion意味着它将只实例化一次。
  • 然后我们创建了一个provides()方法,只有当您将$defer设置为true时才需要。这将返回在加载该类时应该加载的绑定名称。

步骤3:创建DatabaseConfigurationService

要执行此步骤,您需要在app文件夹中创建一个新文件夹Services。然后编写以下代码:

<?php
namespace App'Services;
use Illuminate'Support'Facades'Log;
class DatabaseConfigurationService
{
    public static $somevar;
    public function __construct()
    {
        //Do some tasks such as getting username/password from your .env file
    }
    public static function getValues()
    {
        //Get all your values here.
    }
}

我们所做的是:

  • 创建这个类,它将在应用程序启动/需要时由Provider类调用(取决于$defer)。

步骤4:为您的新提供者创建一个Facade:

<?php
namespace App'Facades;
use Illuminate'Support'Facades'Facade;
class DatabaseConfiguration extends Facade
{
    protected static function getFacadeAccessor()
    {
        return 'dbconf';
    }
}

步骤5:config/app.php

中进行这些更改
  • provider数组中添加以下行。

    应用' '供应商DatabaseConfigurationServiceProvider

  • 在别名数组中添加下面一行。

    'DatabaseConfiguration '=> 'App'Facades'DatabaseConfiguration'

第6步:最后,你现在可以使用你的Provider在你的控制器,像这样:

注意:我知道这是一个有点冗长的过程,但这是推荐的方法。一旦你做了几个Providers,你就会明白这是一个相当简单的过程。—使用"use DatabaseConfiguration;"导入-使用DatabaseConfiguration::getValues()

调用该类的方法

你也可以实现你自己的Singleton,它可以让你更容易理解到底发生了什么:

<?php
namespace App'Helpers;
class Settings
{
    private static $instance;
    private static $settings = [];
    private function __construct(){}
    public static function getInstance(){
        if(is_null(static::$instance)) 
            static::$instance= new Settings;
        return static::$settings;
    }
    public static function getKey($key)
    {
        if(array_key_exists($key , static::$settings))
            return static::$settings[$key];
        return null;
    }
    public static function setKey($key , $value)
    {
        static::$settings[$key] = $value;
    }
}
<?php
namespace App'Http'Controllers;
//...
class HelloController extends Controller
{
    public function index()
    {
        Settings::getInstance();
        Settings::setKey("foo", "bar");
        Settings::getKey("foo"); // returns bar
        // as long as you don't change "foo" again, it will always be "bar" anywhere in your app
    }
}
    在app文件夹中创建一个名为Helpers的文件夹
  1. 在Helpers文件夹中创建Settings.php
  2. 在laravel目录(不是app目录)中运行"Composer dump- autolload "