在 php 服务器上使用 Symfony 运行进程时出错 对进一步执行结果的回答

问题描述

我在 PHP 中开发了一个带有可清洗的 API,以使用 opencv 在 C++ 中运行算法。应用程序将照片发送到服务器,服务器又会启动一个负责处理此图像的 .exe 文件。通过终端执行文件时,算法正确处理图像。但是,为了通过 API 中的代码执行此处理,我使用的是 Symfony,更准确地说是 Process。好吧,当执行下面的行时,它总是告诉我找不到 .exe 文件

$process = new Process(['feridas/exec','final.png']);

我也尝试了以下方法,但都没有成功。

$process = new Process(['./exec','final.png']);
$process = new Process(['server-laravel/resources/feridas/exec']);

代码完整:

namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\Process\Process;

class ClassificationController extends Controller
{

public function process(Request $request)
{
    /** @var $image UploadedFile*/
    $image = $request->files->get('image');
    if (empty($image)) {
        throw new \Exception("Arquivo não fornecido.");
    }

    $validExtensions = ['image/jpeg','image/png','image/jpg'];

    if (!in_array($image->getMimeType(),$validExtensions)) {
        dd($image->getMimeType());
        throw new \Exception("Arquivo não suportado");

    }

    if (!$image->move(resource_path('feridas'),$image->getClientOriginalName())) {
        throw new \Exception("Error moving file.");
    }

    $newPath = resource_path('feridas/' . $image->getClientOriginalName());

    return $this->processImage($newPath);
}

private function processImage($newPath){
    $process = new Process(['ls','-la',resource_path('feridas')]);

    $process->run();
    $process->wait();
    

    if (!$process->isSuccessful()) {
        return [
            'success' => true,//ou false
            'message'    => 'Could not execute script: %s',$process->getErrorOutput()
        ];
        throw new ProcessFailedException($process);
    }

    $output = $process->getoutput();
    return [
        'success' => true,//ou false
        'message'    => $output
    ];
 
}
}

输出

enter image description here

当通过终端执行相同的算法时,它正确返回输出,以秒为单位的算法执行时间。

enter image description here

解决方法

如果 Process 类中没有 cwd 参数值,则 getpwd() php 的当前路径。

Laravel 是入口点的路径,public/index.php

var_dump(getcwd());

// /home/user/public

所以明确定义文件所在的绝对路径。

var_dump(resource_path('feridas/exec'));

// /home/user/resources/feridas/exec

试试吧。

use Symfony\Component\Process\Process;

$process = new Process([resource_path('feridas/exec'),resource_path('feridas/final.png')]);

$process->run(function ($type,$buffer) {
    if (Process::ERR === $type) {
        echo 'ERR > '.$buffer;
    } else {
        echo 'OUT > '.$buffer;
    } 
});

如果这不起作用,请告诉我们下一个结果。

$process = new Process(['ls','-la',resource_path('feridas/exec'),resource_path('feridas/final.png')]);
$process = new Process(['ls',$newPath]);
// SSH Terminal

[root@dev ~]# /home/user/resources/feridas/exec /home/user/resources/feridas/final.png

[root@dev ~]# ls -la /home/user/resources/feridas/exec /home/user/resources/feridas/final.png

Symfony 流程文档 - https://symfony.com/doc/current/components/process.html#getting-real-time-process-output


对进一步执行结果的回答。

enter image description here

在第二个参数 $cwd 中输入要移动的目录。

//$process = new Process(['ls',resource_path('feridas')]);
$process = new Process(['./exec'],resource_path('feridas'));


// arguments
// $command = ['./exec']
// $cwd = resource_path('feridas')

检查类参数 - https://github.com/symfony/process/blob/5.x/Process.php#L141

public function __construct(array $command,string $cwd = null,array $env = null,$input = null,?float $timeout = 60)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...