Ошибка запуска процесса с помощью Symfony на сервере php

#php #laravel #serve

#php #laravel #служить

Вопрос:

Я разработал API на php с помощью washable для запуска алгоритма на C с opencv. Приложение отправляет фотографию на сервер, который, в свою очередь, запускает 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 AppHttpControllersApi;
use AppHttpControllersController;
use IlluminateHttpRequest;
use SymfonyComponentHttpFoundationFileUploadedFile;
use SymfonyComponentProcessProcess;

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
    ];
 
}
}
 

вывод:

введите описание изображения здесь

При выполнении того же алгоритма через терминал он корректно возвращает выходные данные, время выполнения алгоритма в секундах.

введите описание изображения здесь

Комментарии:

1. Вы пробовали использовать resource_path('feridas/exec') в качестве пути? Предполагая, что в этой папке есть файл «exec».

2. Энрико, верни ошибку 500

3. оцените каталоги, например var_dump(__DIR__, realpath('.'), realpath('feridas/exec')) … вы используете относительный путь, который не соответствует ожидаемому пути. редактировать: забыл cwd.. var_dump(getcwd())

4. Я изменил код в соответствии с вашим ответом: var_dump(__DIR__, realpath('.'), realpath('feridas/exec')); $process = new Process([var_dump(getcwd())]); «sh: 1: exec:: В разрешении отказано n»

5. Я уже дал разрешение chmod -R 777, и при отправке изображения разрешение изменяется.

Ответ №1:

Если в классе процесса нет значения аргумента 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 SymfonyComponentProcessProcess;

$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', '-la', resource_path('feridas/exec'), $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


Ответы на результаты дальнейшего выполнения.

введите описание изображения здесь

Введите каталог, который будет перемещен во втором аргументе, $cwd .

 //$process = new Process(['ls', '-la', 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)
 

Комментарии:

1. Было, я изменил код, как вы предложили, обновил в вопросе, однако алгоритм не выполнялся с изображением. При выходе он не показывает время выполнения алгоритма, как это появляется при его выполнении через терминал, как показано в обновленном вопросе.

2. Добавил я… Answers to the results of further execution.

3. большое вам спасибо, наконец-то все сработало правильно