在 Laravel 中为数据库做种时使用进度条

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37319676/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 13:50:22  来源:igfitidea点击:

Using a Progress Bar while Seeding a database in Laravel

phpsymfonylaravel

提问by Sevenearths

I have to seed quite a lot of data into a database and I want to be able to show the user a progress bar while this happens. I know this is documented:

我必须将大量数据播种到数据库中,并且我希望能够在发生这种情况时向用户显示进度条。我知道这是记录在案的:

but I'm having problems including it in my seeder.

但是我在将它包含在播种机中时遇到了问题。

<?php

use Illuminate\Database\Seeder;

class SubDivisionRangeSeeder extends Seeder
{
    public function run()
    {
        $this->output->createProgressBar(10);
        for ($i = 0; $i < 10; $i++) {
            sleep(1);
            $this->output->advance();
        }
        $this->output->finish();
    }
}

or

或者

<?php

use Illuminate\Database\Seeder;

class SubDivisionRangeSeeder extends Seeder
{
    public function run()
    {
        $this->output->progressStart(10);
        for ($i = 0; $i < 10; $i++) {
            sleep(1);
            $this->output->progressAdvance();
        }
        $this->output->progressFinish();
    }
}

from https://mattstauffer.co/blog/advanced-input-output-with-artisan-commands-tables-and-progress-bars-in-laravel-5.1

来自https://mattstauffer.co/blog/advanced-input-output-with-artisan-commands-tables-and-progress-bars-in-laravel-5.1

Any ideas?

有任何想法吗?

回答by Dmitry

You can get access to output through $this->command->getOutput()

您可以通过以下方式访问输出 $this->command->getOutput()

public function run()
{
    $this->command->getOutput()->progressStart(10);
    for ($i = 0; $i < 10; $i++) {
        sleep(1);
        $this->command->getOutput()->progressAdvance();
    }
    $this->command->getOutput()->progressFinish();
}

回答by Francesco Malatesta

Your code isn't working because you're using $this->outputin the wrong class. If you take a look again to the article you shared, $this-outputis used in an Artisan command class.

您的代码不起作用,因为您$this->output在错误的类中使用。如果您再次查看您共享的文章,它$this-output是在 Artisan 命令类中使用的。

In fact, every Artisan command is made with the Symfony Consolecomponent.

事实上,每个 Artisan 命令都是由Symfony Console组件创建的。

You're actually trying to use it in a database seeder :)

您实际上是在尝试在数据库播种机中使用它 :)

My suggestion: build your seeders and then call them with an "install" or "seed" customized command for your needs.

我的建议:构建您的播种机,然后根据您的需要使用“安装”或“种子”自定义命令调用它们。

回答by LytayTouch

Here is my implementation code,

这是我的实现代码,

<?php

use Illuminate\Database\Seeder;

class MediaTypeTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        $media_types = [
            ['name'=>'movie'],
            ['name'=>'channel'],
            ['name'=>'drama'],
            // ['name'=>'ebook'],
            // ['name'=>'shopping'],
            // ['name'=>'reseller'],
            // ['name'=>'broadcasting']
        ];
        $this->command->getOutput()->progressStart(count($media_types));
        App\Models\Backoffice\MediaType::query()->delete();
        foreach($media_types as $media_type){
            App\Models\Backoffice\MediaType::create($media_type);
            $this->command->getOutput()->progressAdvance();
        }
        $this->command->getOutput()->progressFinish();
    }
}

回答by Sevenearths

Just in case anyone else comes across a similar scenario and is looking for a solution I created the following base class:

以防万一其他人遇到类似的情况并正在寻找解决方案,我创建了以下基类:

<?php

use Illuminate\Database\Schema\Blueprint;

class TestCase extends Illuminate\Foundation\Testing\TestCase
{
    protected $progress = 0;

    protected function outputInfo($text)
    {
        $this->output('info', $text, 34);
    }

    protected function outputSuccess($text)
    {
        $this->output('success', $text, 32);
    }

    protected function outputWarning($text)
    {
        $this->output('warning', $text, 33);
    }

    protected function outputError($text)
    {
        $this->output(strtoupper('error'), $text, 31);
    }

    private function output($status, $text, $colour_code = 34)
    {
        $this->newLine();
        print "3[1;" . $colour_code . "m" . str_pad($status.':', 8) . " " . $text . " 3[0m";
    }

    protected function progressDots()
    {
        if ($this->progress % 20 == 0) {
            print '.';
        }
    }

    protected function newLine()
    {
        echo "\n";
    }

    /**
     * Prevents a warning on the command line
     */
    public function testDefault()
    {
        $this->assertTrue(true);
    }
}

And then used it something like this...

然后像这样使用它......

<?php

class SomethingTests extends TestCase
{

    public function testSomething()
    {
        $array = range(0, 100);

        foreach ($array as $value) {

            $this->outputInfo('Testing '.$value);

            $this->assertGreaterThan(101,$value,'101 is not greater then '.$value);

            $this->progressDots();

        }

        $this->newLine();

    }

}