Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 忽略生产上的自定义Laravel Artisan命令_Php_Laravel_Laravel Artisan_Laravel Dusk - Fatal编程技术网

Php 忽略生产上的自定义Laravel Artisan命令

Php 忽略生产上的自定义Laravel Artisan命令,php,laravel,laravel-artisan,laravel-dusk,Php,Laravel,Laravel Artisan,Laravel Dusk,我已经编写了一个自定义Artisan命令(我们称之为mydash.php),它扩展/抽象了核心dash命令的一些功能 此自定义命令从黄昏包中扩展Laravel\dash\Console\dashCommand 问题是,在生产中没有安装Dusk软件包(它位于composer.json中的require dev下) 因此,当composer在生产环境中生成自动加载文件时,当它到达mydash.php时会出错,因为它找不到Laravel\dash\Console\dashcommand PHP Fat

我已经编写了一个自定义Artisan命令(我们称之为
mydash.php
),它扩展/抽象了核心dash命令的一些功能

此自定义命令从黄昏包中扩展
Laravel\dash\Console\dashCommand

问题是,在生产中没有安装Dusk软件包(它位于
composer.json
中的
require dev
下)

因此,当composer在生产环境中生成自动加载文件时,当它到达
mydash.php
时会出错,因为它找不到
Laravel\dash\Console\dashcommand

PHP Fatal error:  Class 'Laravel\Dusk\Console\DuskCommand' not found in app/Console/Commands/Dusk.php on line 10

In Dusk.php line 10:

  Class 'Laravel\Dusk\Console\DuskCommand' not found  
我尝试将Dash软件包移动到
require
,这样它就可以在生产环境中使用(我知道这并不理想),但核心Dash服务提供商中有一行在生产环境中运行时抛出异常,从而阻止了这一点:

# From: vendor/laravel/dusk/src/DuskServiceProvider.php
if ($this->app->environment('production')) {
    throw new Exception('It is unsafe to run Dusk in production.');
}
我正试图想出一个最优雅的解决方案,让我的自定义黄昏命令成为应用程序的一部分,并且可以在本地访问,而不会在生产中引发错误。

一个想法是:将我的Dusk命令作为自己的包编写,这也仅在require-dev中


还有其他想法吗?

我刚看了一下API,您可以这样做:

您可以将命令移动到
App\Console\Commmands\Local\dashcommand.php

默认情况下,如果检查内核中的
commands()
方法,它将只加载
App\Console\commands
中的命令。这将不包括子目录

/**
 * Register the commands for the application.
 *
 * @return void
 */
protected function commands()
{
    $this->load(__DIR__.'/Commands');

    require base_path('routes/console.php');
}
这是默认的
commands()
方法。您可以将此实现切换到以下实现:

/**
 * Register the commands for the application.
 *
 * @return void
 */
protected function commands()
{
    $paths = [
        __DIR__ . '/Commands'
    ]; 

    if(app()->environment('local')) {
        $paths[] = __DIR__ . '/Commands/Local';
    }

    $this->load($paths);

    require base_path('routes/console.php');
}
因此,在local中,我们还将加载基于
App\Console\commands\local
的命令

诚然,我自己没有尝试过,但我认为它应该会起作用

编辑:我试了一下,它似乎工作得很好。我想,我应该试着多解释一下。基本上,在完成
编写器转储自动加载后,Laravel正在收听此事件并做两件事:

"post-autoload-dump": [
    "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
    "@php artisan package:discover --ansi"
]
第二个是尝试运行自动包发现命令,这是它将失败的地方。Artisan可执行文件实际上使用控制台内核引导应用程序

$kernel = $app->make(Illuminate\Contracts\Console\Kernel::class);

$status = $kernel->handle(
    $input = new Symfony\Component\Console\Input\ArgvInput,
    new Symfony\Component\Console\Output\ConsoleOutput
);
在解析内核时,它还将尝试启动所需的命令,以便Artisan可以使用这些命令,而这正是它失败的地方


然而,正如我上面提到的,如果您只启动生产中需要的命令,这个问题就不会发生

公认的答案似乎不适用于Laravel 6。这对我很有用:

  • 使用
    php artisan make:command YourCommand
    创建命令,并将其移动到app/Console/Local
  • 将其命名空间更改为App\Console\Local
  • 然后,在app/Console/Kernel.php中:
  • 受保护的函数命令()
    {
    $path=[
    __目录。'/Commands'
    ];
    if(app()->environment('local')){
    $paths[]=\uuuuu DIR\uuuu.'./Local';
    }
    $this->load($path);
    需要基本路径('routes/console.php');
    }
    
  • 享受;)
    遇到了另一个障碍:因为
    mydash.php
    正在扩展
    Laravel\dash\Console\dashcommand
    ,composer在产品中找不到
    命令时抛出错误。为了解决这个问题,我可以将
    mydash
    移出
    app/
    目录,这样它就不会在生产中自动加载psr-4(并将它的新位置添加到
    autoloaddev
    )。但是,现在这是两个非典型的步骤来让它工作-我认为在这一点上,它是有意义的,只是让它自己的包-esp,因为我可以看到它在其他项目中是有用的。我实际上发现完全相反的行为在Laravel 7+。子目录中的命令绝对是通过控制台内核的load()方法自动加载的。不幸的是,我发现没有简单的方法可以选择性地忽略自动加载中的一个或多个。