2

I developed an API in php with washable to run an algorithm in C ++ with opencv. The application sends a photo to the server, which in turn starts an .exe file responsible for processing this image. When executing the file via terminal, the algorithm correctly processes the image. However, to perform this processing via code in the API I am using Symfony, more precisely Process. Well, when executing the line below it always returns to me that the .exe file was not found.

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

I have also tried in the following ways, but without success.

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

Code complete:

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

outuput:

enter image description here

When executing the same algorithm via terminal, it correctly returns the output, time of execution of the algorithm in seconds.

enter image description here

Carlos Diego
  • 348
  • 5
  • 20
  • 1
    Have you tried using ```resource_path('feridas/exec')``` as the path? Assuming that there is an "exec" file in this folder. – Enrico Dias Dec 19 '20 at 21:01
  • Enrico, return error 500 – Carlos Diego Dec 21 '20 at 13:26
  • 1
    evaluate the directories, like `var_dump(__DIR__, realpath('.'), realpath('feridas/exec'))`... you're using a relative path which doesn't resolve to the path you're expecting. edit: forgot the cwd.. `var_dump(getcwd())` – Honk der Hase Dec 28 '20 at 17:55
  • I changed the code according to your answer: `var_dump(__DIR__, realpath('.'), realpath('feridas/exec')); $process = new Process([var_dump(getcwd())]);` "sh: 1: exec: : Permission denied\n" – Carlos Diego Dec 28 '20 at 20:03
  • I already gave permission chmod -R 777 and when sending the image the permission is changed. – Carlos Diego Dec 28 '20 at 20:08
  • I asked a new question now with the new error I'm having. Can you help me please? https://stackoverflow.com/questions/65483579/full-file-permission-is-changed-when-uploading-file-to-my-api – Carlos Diego Dec 28 '20 at 20:21

1 Answers1

2

If there is no cwd argument value in the Process class, getpwd() the current path of php.

Laravel is the path to the entry point, public/index.php.

var_dump(getcwd());

// /home/user/public

So it is clear to define the absolute path where the file exists.

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

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

Try it.

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

If that doesn't work, please let us know the next result.

$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 process doc - https://symfony.com/doc/current/components/process.html#getting-real-time-process-output


Answers to the results of further execution.

enter image description here

Enter the directory to be moved in the second argument, $cwd.

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


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

Check the class arguments - 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)
Been Kyung-yoon
  • 1,644
  • 12
  • 13
  • Been, I changed the code as you suggested, updated in the question, however the algorithm did not execute with the image. On exit it does not show the execution time of the algorithm, as it appears when executing it via terminal, seen in the updated question. – Carlos Diego Dec 30 '20 at 19:44
  • I added... `Answers to the results of further execution.` – Been Kyung-yoon Dec 31 '20 at 11:28
  • thank you very much, it finally worked correctly – Carlos Diego Dec 31 '20 at 16:57