Retourner du json avec return dans une function anonyme

Petit nouveau ! | 8 Messages

23 févr. 2016, 22:24

Salut :D
Je bosse sur un site avec beaucoup d'Ajax et tout les fichier php utilisé par les appel doivent retourner du json pour le javascript.
J'utilise une fonction anonyme pour avoir l'avantage du return, qui aide beaucoup pour gérer les erreurs.

J'ai donc trouvé une solution un peu bizarre mais qui marche :
echo json_encode(call_user_func(function() {
    if(empty($_POST['username']) {
        return ["success" => false, "error" => "username not set"];
    }
}));
Mais cette façon de faire avec la fonction anonyme dans un call_user_func dans un json_encode dans un echo me parait compliqué.
Y aurait il un moyen plus simple de faire ce que je veux ? (A savoir pouvoir utiliser return dans un code normal)

ynx
Mammouth du PHP | 586 Messages

24 févr. 2016, 10:44

Salut,

Je ne comprend pas bien l’intérêt du return et de la fonction anonyme. Pourquoi ne pas utiliser directement json_encode ?
if(empty($_POST['username'])) {
    echo json_encode(["success" => false, "error" => "username not set"]);
}
Bonne journée

Petit nouveau ! | 8 Messages

24 févr. 2016, 12:28

C'est pour l'avantage du return qui termine la fonction. par example si on veux verifier si foo et bar sont valide on peut faire ça.
if(isset($foo))
{
    if(isset($bar))
    {
        // code ...
    }
    else
    {
        echo json_encode(["success" => false, "error" => "bar is empty"]);
    }
}
else 
{
    echo json_encode(["success" => false, "error" => "foo is empty"]);
}
Avec la fonction anonyme :
echo json_encode(user_call_func(function() {
    if(!isset($foo))
    {
        return ["success" => false, "error" => "foo is empty"];
    }
    
    if(!isset($bar))
    {
        return ["success" => false, "error" => "bar is empty"];
    }

   // code ..
}));
Mais dans mon code, j'ai besoin de faire beaucoup de ces vérifications. Donc au lieu d'avoir 50 if else j'ai 50 return. Le code est beaucoup plus propre (sauf le echo json_encode(call_user_func(function() {}))).

ynx
Mammouth du PHP | 586 Messages

24 févr. 2016, 12:55

Dans ce cas une solution possible serait de créer ta propre fonction à la place d'une fonction anonyme mais cela est seulement utile si cette fonction est réutilisée, sinon aucun intérêt par rapport à la fonction anonyme (un peu plus lisible éventuellement...) :
function maFonction() {
    if(!isset($_POST['foo'])) {
        return ["success" => false, "error" => "foo is empty"];
    }
    
    if(!isset($_POST['bar'])) {
        return ["success" => false, "error" => "bar is empty"];
    }
    
    // traitement
    
    return ["success" => true, "foo" => $_POST['foo'], "bar" => $_POST['bar']];
}

echo json_encode(maFonction());
Une autre alternative légèrement différente est de définir une variable $errors à laquelle on affecte les éventuels messages d'erreurs lors de la vérification des données, puis on fini simplement par vérifier si des erreurs existent ou non.
Cette solution permet également de gérer plusieurs messages d'erreur, il faut par contre modifier l'affichage (la récupération du json coté client) pour traiter un tableau de chaine de caractères à la place d'une chaine de caractère (élément error du json) :
$errors = array();

if(!isset($_POST['foo'])) {
    $errors[] = "foo is empty";
}

if(!isset($_POST['bar'])) {
    $errors[] = "bar is empty";
}

if ($errors) {
    echo json_encode(["success" => false, "error" => $errors]);
} else {
    // traitement
    
    echo json_encode(["success" => true);
}

Petit nouveau ! | 8 Messages

24 févr. 2016, 16:20

Au début j’utilisai une fonction appelé une seule fois, c'est pour ça que je suis passé a une fonction anonyme.
Et pour la deuxième solution, ça marche pas vraiment bien vu que je peut avoir des exception un peut partout dans le code donc il faudrait que je verifie toute les 10 lignes de code.
La fonction anonyme + call_user_func et la meilleure solution pour ce que j'ai besoin donc ?

ynx
Mammouth du PHP | 586 Messages

24 févr. 2016, 17:33

Une autre alternative avec les exceptions :
try {
    if (!isset($_POST['foo'])) {
        throw new Exception("foo is empty");
    }

    if (!isset($_POST['bar'])) {
        throw new Exception("foo is empty");
    }

    // traitement
    echo json_encode(["success" => true]);
} catch (Exception $e) {
    echo json_encode(["success" => false, "error" => $e->getMessage()]);
}
Sinon, je ne sais pas si la fonction anonyme avec call_user_func est la meilleure solution mais elle ne me semble pas aberrante.