【问题标题】:Laravel 5 dynamically run migrationsLaravel 5 动态运行迁移
【发布时间】:2016-10-23 13:18:21
【问题描述】:

所以我在Packages/Sitemanager/Blog 的结构中创建了自己的博客包,我有一个如下所示的服务提供者:

namespace Sitemanager\Blog;

use Illuminate\Support\ServiceProvider as LaravelServiceProvider;

class BlogServiceProvider extends LaravelServiceProvider {

    /**
     * Indicates if loading of the provider is deferred.
     *
     * @var bool
     */
    protected $defer = false;

    /**
     * Bootstrap the application events.
     *
     * @return void
     */
    public function boot() {

        $this->handleConfigs();
        $this->handleMigrations();
        $this->handleViews();
        $this->handleRoutes();
    }

    /**
     * Register the service provider.
     *
     * @return void
     */
    public function register() {

        // Bind any implementations.
        $this->app->make('Sitemanager\Blog\Controllers\BlogController');
    }

    /**
     * Get the services provided by the provider.
     *
     * @return array
     */
    public function provides() {

        return [];
    }

    private function handleConfigs() {

        $configPath = __DIR__ . '/config/blog.php';

        $this->publishes([$configPath => config_path('blog.php')]);

        $this->mergeConfigFrom($configPath, 'blog');
    }

    private function handleTranslations() {

        $this->loadTranslationsFrom(__DIR__.'/lang', 'blog');
    }

    private function handleViews() {

        $this->loadViewsFrom(__DIR__.'/views', 'blog');

        $this->publishes([__DIR__.'/views' => base_path('resources/views/vendor/blog')]);
    }

    private function handleMigrations() {

        $this->publishes([__DIR__ . '/migrations' => base_path('database/migrations')]);
    }

    private function handleRoutes() {

        include __DIR__.'/routes.php';
    }
}

现在,如果我想在安装过程之前或安装过程中从未运行过迁移,我想做的是动态运行迁移。我在旧文档中看到你可以这样:

Artisan::call('migrate', array('--path' => 'app/migrations'));

但是,这在 laravel 5 中无效,我该如何处理?

【问题讨论】:

标签: php laravel laravel-5


【解决方案1】:
Artisan::call('migrate', array('--path' => 'app/migrations'));

可以在 Laravel 5 中使用,但您可能需要进行一些调整。

首先,由于 Laravel 5 的命名空间,您需要在文件顶部有一个 use Artisan; 行(use Illuminate\Support\ServiceProvider... 所在的位置)。 (您也可以使用\Artisan::call - \ 很重要)。

您可能还需要这样做:

Artisan::call('migrate', array('--path' => 'app/migrations', '--force' => true));

--force 是必需的,因为 Laravel 默认会在生产环境中提示您输入是/否,因为它是一个具有潜在破坏性的命令。如果没有--force,您的代码只会坐在那里旋转(Laravel 正在等待 CLI 的响应,但您不在 CLI 中)。

我鼓励您在服务提供商的boot 方法之外的其他地方执行此操作。。这些可能是繁重的调用(依赖于文件系统和数据库调用,您不想在每个页面浏览中进行)。请考虑使用显式安装控制台命令或路由。

【讨论】:

  • 现在使用我的引导命令,我可能会希望在安装后运行某种安装命令(目前不确定执行此操作的最佳方法)。无论如何做 \Artisan::call('migrate', array('--path' => 'packages/sitemanager/blog/migrations', '--force' => true));为我工作,我可以看到对数据库所做的更改。您将如何进行安装过程?我怎样才能从这里恢复迁移?我会调用 migrate:rollback 到路径吗?
  • @mdixon18 回滚可能非常讨厌 - 我不会自动化。 To my knowledge 没有 Artisan 命令来回滚 特定 迁移,因此您最终可能会回滚错误的迁移并吹走数据。我会通过您的应用提供的 Artisan 控制台命令进行安装。
  • 我明白了,我将如何从包外的控制器加载包,我只是在提供程序类中命名空间并调用安装方法吗? -- 它对配置和视图等的作用是否足以让一个包发布?
【解决方案2】:

发布包后:

php artisan vendor:publish --provider="Packages\Namespace\ServiceProvider"

您可以使用以下命令执行迁移:

php artisan migrate

Laravel 会自动跟踪已执行的迁移并相应地运行新的迁移。

如果您想从 CLI 外部执行迁移,例如在路由中,您可以使用 Artisan 外观:

Artisan::call('migrate')

您可以将可选参数(例如力和路径)作为数组传递给 Artisan::call 中的第二个参数。

进一步阅读:

【讨论】:

    【解决方案3】:

    对于 Laravel 7(可能还有 6 个):

    use Illuminate\Support\Facades\Artisan;
    
    
    Artisan::call('migrate');
    

    会很有效。

    【讨论】:

    • 这个过程是用来更新(升级)已发布的项目而不丢失数据吗?
    • @ufuk 迁移默认不会损害您的数据库或数据。 php artisan migrate 是一个用于更新已发布项目的数据库的好命令。在运行迁移之前不要忘记备份。
    • 所以通常情况下,在yes终端的帮助下,我们可以轻松做到不丢失数据。但是我将如何将其应用于我的客户?您知道如何将其应用于 Cpanel 中的数据库吗?
    • @ufuk 这不是在 Cpanel 中运行迁移的好方法。但是您可以编写一个端点并在代码中调用migrate 命令。在 Cpanel 中,人们通常手动修改数据库。
    • 我了解,但我会将应用程序提供给我的客户。而且我不知道他的cpanel信息。我应该以什么方式尝试遵循它,以便它可以升级更新。
    猜你喜欢
    • 2015-07-06
    • 2016-08-29
    • 2017-01-16
    • 2016-05-09
    • 2016-04-12
    • 2015-10-18
    • 1970-01-01
    • 2016-10-13
    • 2020-10-24
    相关资源
    最近更新 更多