【问题标题】:Laravel 5.4 - Passing Data from Controller to Artisan HandleLaravel 5.4 - 将数据从控制器传递到 Artisan Handle
【发布时间】:2017-09-19 16:15:28
【问题描述】:

为了开始,我创建了一个名为 MySqlRestore. 的自定义 Artisan 命令

它只是使用转储的sql 文件恢复数据库。

这是我的MySqlRestore 代码:

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;

class MySqlRestore extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'db:restore';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Restores database using info from .env';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        $sqlfile = //data from controller;

        $ds = DIRECTORY_SEPARATOR;
        $host = env('DB_HOST');
        $username = env('DB_USERNAME');
        $password = env('DB_PASSWORD');
        $database = env('DB_DATABASE');

        $mysqlpath = 'C:\xampp\mysql\bin\mysql';
        $path = 'C:\salesandinventory\Backups\\';

        $command = sprintf($mysqlpath . ' --user=' . $username . ' --password=' . $password . ' --host=' . $host . ' ' . $database . ' < ' . $path . $sqlfile);

        exec($command);
    }
}

现在在这条线上$sqlfile = //data from controller;,我需要来自我的控制器的数据。

这是我的控制器的样子:

<?php

namespace App\Http\Controllers;

use App\Database;
use Illuminate\Http\Request;
use Artisan;

class DatabaseController extends Controller
{
    public function index()
    {
        return view('database.index');
    }
    public function restoreDatabase(Request $request)
    {
        $sqlfile = $request->sqlfile; // the data I need.

        Artisan::call('db:restore');
        return view('database.index');
    }
}

现在我不知道如何将 $sqlfile = $request-&gt;sqlfile; 这个数据从我的控制器传递到我的 Artisan handle 函数中。

【问题讨论】:

  • 你试过通过constructor吗?
  • 如果 $sqlfile = $request-&gt;sqlfile 来自我 Blade 的 &lt;input&gt;? 是否适用另外,我还没有使用过这个 constructor

标签: laravel


【解决方案1】:

数据通过使用花括号 {dataName} 的受保护 $signature 传递

例如

protected $signature = 'db:restore {dataName}'

并使用

调用它
$this->argument('dataName');

在你的控制器中

Artisan::call('db:restore',['test'=> $test]);

namespace App\Console\Commands;

use Illuminate\Console\Command;

class MySqlRestore extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'db:restore {test}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Restores database using info from .env';

    public $sqlFile;
    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        $sqlfile = $this->argument('test');

        $ds = DIRECTORY_SEPARATOR;
        $host = env('DB_HOST');
        $username = env('DB_USERNAME');
        $password = env('DB_PASSWORD');
        $database = env('DB_DATABASE');

        $mysqlpath = 'C:\xampp\mysql\bin\mysql';
        $path = 'C:\salesandinventory\Backups\\';

        $command = sprintf($mysqlpath . ' --user=' . $username . ' --password=' . $password . ' --host=' . $host . ' ' . $database . ' < ' . $path . $sqlfile);

        exec($command);
    }
}

Call it like this

Artisan::call('db:restore',['test'=> $test]);

【讨论】:

    【解决方案2】:
    <?php
    
    namespace App\Console\Commands;
    
    use Illuminate\Console\Command;
    
    class MySqlRestore extends Command
    {
        /**
         * The name and signature of the console command.
         *
         * @var string
         */
        protected $signature = 'db:restore';
    
        /**
         * The console command description.
         *
         * @var string
         */
        protected $description = 'Restores database using info from .env';
    
        public $sqlFile;
        /**
         * Create a new command instance.
         *
         * @return void
         */
        public function __construct($sqlFile)
        {
            $this->sqlFile = $sqlFile;
            parent::__construct();
        }
    
        /**
         * Execute the console command.
         *
         * @return mixed
         */
        public function handle()
        {
            $sqlfile = $this->sqlFile;
    
            $ds = DIRECTORY_SEPARATOR;
            $host = env('DB_HOST');
            $username = env('DB_USERNAME');
            $password = env('DB_PASSWORD');
            $database = env('DB_DATABASE');
    
            $mysqlpath = 'C:\xampp\mysql\bin\mysql';
            $path = 'C:\salesandinventory\Backups\\';
    
            $command = sprintf($mysqlpath . ' --user=' . $username . ' --password=' . $password . ' --host=' . $host . ' ' . $database . ' < ' . $path . $sqlfile);
    
            exec($command);
        }
    }
    

    控制器

    <?php
    
    namespace App\Http\Controllers;
    
    use App\Database;
    use Illuminate\Http\Request;
    use Artisan;
    
    class DatabaseController extends Controller
    {
        public function index()
        {
            return view('database.index');
        }
        public function restoreDatabase(Request $request)
        {
            $sqlfile = $request->sqlfile; // the data I need.
    
            Artisan::call('db:restore',['sqlFile'=>$sqlFile]);
            return view('database.index');
        }
    }
    

    【讨论】:

    • 它给了我这个错误。 Type error: Argument 2 passed to Illuminate\Foundation\Console\Kernel::call() must be of the type array, string given, called in C:\Users\Zack\Google Drive\salesandinventory\vendor\laravel\framework\src\Illuminate\Support\Facades\Facade.php on line 221
    • 现在它返回一个关于不可解析依赖的错误:Unresolvable dependency resolving [Parameter #0 [ &lt;required&gt; $data ]] in class App\Console\Commands\MySqlRestore
    • 哦,对不起,这是$sqlfile 而不是$data
    • Laravel 无法解析通过构造函数传递的字符串参数
    【解决方案3】:

    您的控制器不应执行 Artisan 命令,尤其是可能长时间运行的命令,例如执行数据库备份。

    相反,请考虑分派一个排队的作业来执行恢复。然后,您可以将控制权交还给用户,他们可以继续他们需要做的事情,而不是让网页保持打开状态,否则可能会超时并使数据库处于损坏状态。

    class DatabaseRestoreController extends Controller
    {
        public function store(Request $request)
        {
            dispatch(new RestoreDatabaseJob($request->input('filename')));
    
            return redirect()->back()->withSuccess('Restoring database.');
        }
    }
    

    还有工作类本身:

    class RestoreDatabaseJob implements ShouldQueue
    {
        use InteractsWithQueue;
    
        public $filename;
    
        public function __construct($filename)
        {
            $this->filename = $filename;
        }
    
        public function handle()
        {
            Artisan::call('db:restore', [
                'filename' => $this->filename,
            ]);
    
            // You can notify user restore completed
            // Send email, SMS via notification etc.
        }
    }
    

    【讨论】:

    • 问题是将filename 变量传递给command
    • Artisan::command('db:restore', [ 'filename' => $this->filename, ]);
    • command() 是一个错字,因为我是直接写的;方法名实际上是call()。但是按照我的示例,您将参数作为数组传递给 Artisan 命令。
    • 是的..但它没有解决。 $filename 实际上是一个上传的文件实例
    • 您将无法将上传的文件传递给排队的作业,因为它们无法被序列化。相反,您需要将文件实际上传到某处,然后将该文件的名称传递给作业,然后将其传递给 Artisan 命令。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-04-13
    • 2017-01-29
    • 1970-01-01
    • 1970-01-01
    • 2021-02-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多