fhumanes author
The coding of the SERVER part limited the concurrency of the conversion process to 1 single case, leaving the rest of the requests in the queue until the one currently being produced was completed.
I have made this modification so that the number of concurrent conversion processes is defined (depending on the hardware, since it is a very heavy process). In the attached code it is set to 5, but it is easily adjustable, line 106. <?php
/** * * @About: API Interface * @File: index.php * @Date: $Date:$ Agosot0 -2022 * @Version: $Rev:$ 1.0 * @Developer: Federico Guzman || Modificado por Fernando Humanes para PHP 8.1 **/
/* Los headers permiten acceso desde otro dominio (CORS) a nuestro REST API o desde un cliente remoto via HTTP * Removiendo las lineas header() limitamos el acceso a nuestro RESTfull API a el mismo dominio * Nótese los métodos permitidos en Access-Control-Allow-Methods. Esto nos permite limitar los métodos de consulta a nuestro RESTfull API * Mas información: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS **/ header("Access-Control-Allow-Origin: *"); header('Access-Control-Allow-Credentials: true'); header('Access-Control-Allow-Methods: PUT, GET, POST, DELETE, OPTIONS'); header("Access-Control-Allow-Headers: X-Requested-With"); header('Content-Type: text/html; charset=utf-8'); header('P3P: CP="IDC DSP COR CURa ADMa OUR IND PHY ONL COM STA"');
include_once '../include/Config.php';
require_once("../../include/dbcommon.php"); // DataBase PHPRunner
$debugCode = true; // for Debug custom_error(1,"Se inicia el Proceso de Conversión"); // To debug
$post = $_POST; unset($post['file']); // Quitamos este dato porque es muy grande custom_error(2,"Variable $_POST: ".json_encode($post)); // To debug
// use App\Models\Db; // Utilizamos la conexión de PHPRunner use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ServerRequestInterface as Request; use Selective\BasePath\BasePathMiddleware; use Slim\Factory\AppFactory;
require_once __DIR__ . '/../include/slim_4.11.0/autoload.php'; $app = AppFactory::create(); $app->addRoutingMiddleware(); // $app->add(new BasePathMiddleware($app)); // No usar si se ejecuta en subdirectorio $app->addErrorMiddleware(true, true, true); $app->addBodyParsingMiddleware();
$app->setBasePath(SCRIPTS_DIR);
// --------------------------------------------------------------------------------------
/* Usando POST para convertir fichero */
$app->post('/document', function(Request $request, Response $response) {
$startConvert = date("Y-m-d H:i:s");; // marcar fecha de inicio
// Verify Token Security $verify = authenticate($request, $response); if (is_array($verify)) { // Si es una array, es que hay error $response->getBody()->write(json_encode($verify)); return $response ->withHeader('content-type', 'application/json') ->withStatus(400); } // check for required params $verify = verifyRequiredParams(array('name', 'file','option'), $request, $response); if (is_array($verify)) { // Si es una array, es que hay error $response->getBody()->write(json_encode($verify)); return $response ->withHeader('content-type', 'application/json') ->withStatus(400); } $data = $request->getParsedBody();
$BlobInput=base64_decode($data['file']); // Convert Base64
$part_file = explode(".", $data['name']); // name file $ExtensionFile = $part_file[(count($part_file)-1)]; // Tipo file $new_file = substr($data['name'],0,(strlen($data['name'])-strlen($ExtensionFile)-1)).".pdf";
$option = $data['option']; // Option convert Opffice_to_PDF
// -------------------- for create temporaly file -------------------------- $temp_file = tempnam(sys_get_temp_dir(), 'temp'); $part_path = pathinfo($temp_file); $temp_file1 = $part_path['dirname'].'/'.$part_path['filename'].'.'.$ExtensionFile;
$phpLog = $part_path['dirname'].'/phplog.txt'; // Trace of Debug code
$fp = fopen($temp_file1, 'w'); $fwrite = fwrite($fp, $BlobInput); fclose($fp);
$sizeFile = filesize($temp_file1);
$temp_file2 = $part_path['dirname'].'/'.$part_path['filename'].'.pdf';
do { // Para dotar de mútiples bloqueos $action = false; // Indica que falta la conversión $limint_block = 5; for ($i=0;$i< $limint_block ; $i++) { // El Límite fija el número de procesos concurrentes $fileLock = $part_path['dirname'].'/lockConvert_'.$i.'.txt'; if (!file_exists($fileLock)) { // Si no existe, se crea $fpLock = fopen("$fileLock", "w"); fclose($fpLock); } custom_error(3,"Fichero de bloque: ".$fileLock); // To debug $fp = fopen($fileLock, "r+"); // Fichero de bloqueos para que sólo haya una única ejecución // do { // Bucle de conversión copn control de que sólo un proceso puede estar en ejecución
if (flock($fp, LOCK_EX)) { // adquirir un bloqueo exclusivo
// Convert to PDF custom_error(4,"Iniciamos conversión de : ".$temp_file1." con bloqueo. ".$fileLock); // To debug // $result = shell_exec("..\\Office_to_PDF\\OfficeToPDF.exe $temp_file1 $temp_file2"); $status = exec("..\\Office_to_PDF\\OfficeToPDF.exe $option $temp_file1 $temp_file2", $outputCommand, $result);
if ($result <> 0) { // LOG $a = "Resultado de conversion: ".$result."\n".var_export($outputCommand, true)." \n"; file_put_contents($phpLog, $a, FILE_APPEND | LOCK_EX); } flock($fp, LOCK_UN); // libera el bloqueo custom_error(5,"Termina conversión de : ".$temp_file1." con bloqueo. ".$fileLock); // To debug $action = true; // Se ha hecho la conersión break; } // } while (true); fclose($fp); } if ($action) { break; } // Se termina. Se ha hecho conversión custom_error(6,"Espera en cola fichero: ".$temp_file1); // To debug sleep(1); } while (true); // ------------------ Operation with file result ------------------------------------------- $document = file_get_contents($temp_file2); unlink($temp_file); // delete file tmp unlink($temp_file1); // delete file tmp unlink($temp_file2); // delete file tmp
$responseBody = array(); //capturamos los parametros recibidos y los almacxenamos como un nuevo array $param['name'] = $new_file; $param['file'] = base64_encode($document);
// Write LOG $data = array(); $data["nameFile"] = $new_file; $data["sizeFile"] = $sizeFile; $data["startConvert"] = $startConvert; $data["endConvert"] = date("Y-m-d H:i:s"); DB::Insert("server_pdf_log", $data ); if ( is_array($param) ) { $responseBody["error"] = false; $responseBody["message"] = "Documento convertido satisfactoriamente!"; $responseBody["document"] = $param; $response->getBody()->write(json_encode($responseBody)); return $response ->withHeader('content-type', 'application/json') ->withStatus(200); } else { $responseBody["error"] = true; $responseBody["message"] = "Error al crear auto. Por favor intenta nuevamente."; $response->getBody()->write(json_encode($responseBody)); return $response ->withHeader('content-type', 'application/json') ->withStatus(400); } }); /* corremos la aplicación */ $app->run();
/*********************** USEFULL FUNCTIONS **************************************/
/** * Verificando los parametros requeridos en el metodo */ function verifyRequiredParams($required_fields, Request $request, Response $response) { $error = false; $error_fields = "";
$request_params = $request->getParsedBody();
foreach ($required_fields as $field) { if (!isset($request_params[$field]) || strlen(trim($request_params[$field])) <= 0) { $error = true; $error_fields .= $field . ', '; } }
if ($error) { // Required field(s) are missing or empty // echo error json and stop the app $responseBody = array(); $responseBody["error"] = true; $responseBody["message"] = 'Required field(s) ' . substr($error_fields, 0, -2) . ' is missing or empty';
return $responseBody; } return true; }
/** * Validando parametro email si necesario; un Extra ;) */ function validateEmailRest($email, Request $request, Response $response) { $responseBody = array(); if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { $responseBody["error"] = true; $responseBody["message"] = 'Email address is not valid'; return $responseBody; } return true; } /** * Revisa si la consulta contiene un Header "Authorization" para validar */ function authenticate(Request $request, Response $response) { // Getting request headers $headers = $request->getHeaders(); // Verifying Authorization Header if (isset($headers['Authorization'])) { // get the api key $token = $headers['Authorization'];
// validating api key if (!($token[0] == API_KEY)) { //API_KEY declarada en Config.php
// api key is not present in users table $responseBody["error"] = true; $responseBody["message"] = "Acceso denegado. Token inválido"; // Error 401 return $responseBody; } else { //procede utilizar el recurso o metodo del llamado return true; } } else { // api key is missing in header $responseBody["error"] = true; $responseBody["message"] = "Falta token de autorización"; // error 400 return $responseBody; } }
?> If you are interested in this article, continue reading by clicking this link . Original document: https://asprunner.com/forums/topic/29314-Convert-MS-Office-to-PDF-document
|
|