【问题标题】:Laravel - Executing command in controller, track progressLaravel - 在控制器中执行命令,跟踪进度
【发布时间】:2020-05-17 22:26:22
【问题描述】:

我有一个系统,用户可以通过单击按钮下载作曲家包。安装顺利,包也安装好了,但无法跟踪命令的进度。我想跟踪进度并将其显示在进度条中,但我不知道怎么做?

链接

<a href="{{ route('install_package') }}" class="badge badge-light fa-1x">Install</a>
<div class="progress">
    <div class="progress-bar" role="progressbar" aria-valuenow="75" aria-valuemin="0" aria-valuemax="100"></div>
</div>

<a href="{{ route('uninstall_package') }}" class="badge badge-light fa-1x">Uninstall</a>

路线

Route::get('package/install', 'PackageController@install')->name('install_package');
Route::get('package/uninstall', 'PackageController@uninstall')->name('uninstall_package');

控制器

public function install()
    {
        $package = new Process("composer require rainieren/visitors");
        $package->setWorkingDirectory(base_path());
        $package->run();

        return redirect('/');
    }

    public function uninstall()
    {
        $package = new Process("composer remove rainieren/visitors");
        $package->setWorkingDirectory(base_path());
        $package->run();

        return redirect('/');
    }

这可以吗?提前致谢!

【问题讨论】:

  • 你能找到包裹的尺寸吗?还是直接来自 Composer 的剩余时间?如果是,那么您可以启动一个长轮询“会话”并计算重命名的时间与下载已下载字节所需的时间相比。您可以通过启动 ajax 请求并添加类似 while ($downloading) { //respond with remaining time } 的内容来实现此目的,然后在 AJAX 中,您必须在每次收到响应时不断重复请求,直到服务器返回下载的标志(例如 while($downloading) {...} return 'downloaded';
  • Process 类可以被赋予一个回调,它将接收通常显示在控制台中的分块输出。如果您将该回调与 AJAX 轮询或 websockets 结合使用,您将能够显示正在执行的命令的进度。 symfony documentation 对此提供了很好的解释。

标签: javascript php laravel laravel-5


【解决方案1】:

您可以使用execshell_exec php 函数。 例如

exec('composer require rainieren/visitors');
// or
shell_exec('composer require rainieren/visitors');

见:

http://php.net/manual/en/function.shell-exec.php

http://php.net/manual/en/function.exec.php

或者你可以这样做:

$phpFinder = new PhpExecutableFinder();

        if($phpBin = $phpFinder->find()) {

            $cmdLine = "$phpBin ".base_path('lib/composer/composer.phar').' require rainieren/visitors';
            $process = new Process(str_replace('\\','/',$cmdLine),base_path($this->getDistPath()));
            $process->setTimeout(0);
            $process->mustRun(function($type,$line){
                // get output if needed
            });
        }

不要依赖全局作曲家安装,该路径可在项目基础文件夹中访问。

附: PhpExecutableFinder

【讨论】:

    猜你喜欢
    • 2019-03-08
    • 2015-08-30
    • 2014-09-18
    • 1970-01-01
    • 2019-05-23
    • 2017-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多