Eseguire codice da JSON in PHP
Ultima funzione aggiunta al repo mp-utils.
Si tratta di una funzione che ci permette di eseguire una funzione partendo da un JSON.
Mi è stata molto utile in alcuni contensti.
Partiamo da un JSON del genere per intenderci:
{
"class": "MyClass",
"method": "miaFunzione",
"params": []
}
Ovviamente alla classe potete passare anche tutto il percorso del namespace se volete.
La funzione fa diversi controlli sull'esistenza della classe, del metodo, dei parametri, ecc.
Per fare tutto questo usa la Reflection.
Ecco la funzione:
/**
* Funzione che esegue altre funzioni leggendo un JSON
* @param string $json
* @param bool $checkWhitelist
* @param array $whitelist
* @return array
*/
public function executeFromJson(string $json, bool $checkWhitelist = false, array $whitelist = []): array {
$data = json_decode($json, true);
if (json_last_error() !== JSON_ERROR_NONE) {
return [
"status" => false,
"error" => "JSON non valido",
];
}
$class = $data['class'] ?? null;
$method = $data['method'] ?? null;
$params = $data['params'] ?? [];
if (!$class || !$method) {
return [
"status" => false,
"data" => null,
"error" => "Class o method mancanti",
];
}
if (!is_array($params)) {
return [
"status" => false,
"data" => null,
"error" => "Params deve essere un array",
];
}
if ($checkWhitelist) {
if (!isset($whitelist[$class]) || !in_array($method, $whitelist[$class], true)) {
return [
"status" => false,
"data" => null,
"error" => "Metodo non autorizzato",
];
}
}
if (!class_exists($class)) {
return [
"status" => false,
"data" => null,
"error" => "Classe $class non esiste",
];
}
if (!method_exists($class, $method)) {
return [
"status" => false,
"data" => null,
"error" => "Metodo $method non esiste in $class",
];
}
$reflection = new ReflectionMethod($class, $method);
if (count($params) < $reflection->getNumberOfRequiredParameters()) {
return [
"status" => false,
"data" => null,
"error" => "Parametri insufficienti",
];
}
try {
$result = $reflection->isStatic() ? $class::$method(...$params) : (new $class())->$method(...$params);
return [
"status" => true,
"data" => $result,
"error" => null,
];
} catch (Throwable $e) {
return [
"status" => false,
"data" => null,
"error" => $e->getMessage(),
];
}
}
Un esempio di utilizzo:
$json = json_encode([
'class' => \namespace\services\MyService::class,
'method' => 'getsOccupazione',
'params' => ['D'],
]);
$genericHelpers = new GenericHelpers();
$result = $genericHelpers->executeFromJson($json);
if ($result['status']) {
dump($result['data']);
} else {
echo $result['error'];
}
Enjoy!
php reflection json
Commentami!