Reputation: 358
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:
When executing the same algorithm via terminal, it correctly returns the output, time of execution of the algorithm in seconds.
Upvotes: 3
Views: 2090
Reputation: 1754
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
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)
Upvotes: 2