Laravel AppServiceProvider中的代码在通过DeployHQ部署时停止Composer和构建

8yoxcaq7  于 2023-01-27  发布在  其他
关注(0)|答案(1)|浏览(116)

在我的AppServiceProvider.php文件中有以下代码:

<?php

namespace App\Providers;

use App\Models\Setting;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        //
    }

    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {        
        if (Schema::hasTable('settings')) {
            foreach (Setting::all() as $setting) {
                Config::set('settings.'.$setting->key, $setting->value);
            }
        }
    }
}

这在本地可以很好地完成工作,但当我通过DeployHQ部署时,它会终止进程,并出现以下错误:
SQLSTATE[HY000] [2002]没有此类文件或目录(SQL:从信息模式.表中选择 *,其中表模式= giga,表名称=设置,表类型= '基本表')
这是有道理的,数据库不存在于构建服务器上,所以检查无法运行,因为没有什么可检查的。有没有其他方法可以在 Boot 时使用数据库中的值来水合settings配置,而不影响php artisan package:discover的运行?
我知道可能会有人问,但是.env文件等都设置正确,这个问题是因为构建服务器没有数据库,但是文件通过管道传输到的服务器有。
编辑:为了给予更多的上下文,也许可以提供一些建议,我只是在Service类中的代码中真正使用这个配置值:

public function __construct()
{
    $this->domain = config('api.domain');
    $this->apiVersion = config('api.version');
    $this->bearerToken = config('settings.bearer_token');
    $this->clientId = config('api.client_id');
    $this->clientSecret = config('api.client_secret');
}

网上所有的东西都建议把这些值放到config中,但是如果它只在这里被调用,直接从数据库中检索它可以吗?

wvt8vs2t

wvt8vs2t1#

问题是代码试图访问数据库中的“设置”表,而构建服务器上不存在该表。处理此问题的一种方法是在运行访问数据库的代码之前检查应用程序是否正在生产环境中运行。
您可以使用Laravel提供的app()-〉environment()函数检查当前环境。

if (app()->environment() !== 'production') {
    if (Schema::hasTable('settings')) {
        foreach (Setting::all() as $setting) {
            Config::set('settings.'.$setting->key, $setting->value);
        }
    }
}

这将确保代码只在应用程序不在生产环境中时运行,这样,代码就不会干扰php artisan package:discover的运行,也不会在构建服务器上引起错误。
您还可以将设置值移动到配置文件中,并在应用程序在生产环境中运行时将其包含在内,这样,当数据库不存在时,应用程序就不会崩溃。
另一种选择是,如果您只使用此服务类中的设置,则可以直接从构造函数方法中的数据库检索它们,而不是使用config。这样,您就不必担心构建服务器上的设置是否可用,并且您仍然可以使用这些值,而不必担心它们是否存在于config中。

public function __construct()
{
    $this->domain = config('api.domain');
    $this->apiVersion = config('api.version');
    $setting = Setting::where('key', 'bearer_token')->first();
    $this->bearerToken = $setting->value;
    $this->clientId = config('api.client_id');
    $this->clientSecret = config('api.client_secret');
}

在这个版本的构造函数中,它直接从数据库的设置表中检索bearer_token值,而不是使用config。API.domain、api.version、api.client_id和api.client_secret值仍然从config中检索。
作为提醒,您应该确保处理的是数据库中不存在该设置的情况,以避免应用程序中出现任何错误。

相关问题