Question

Tout le monde ici devrait connaître les statemens 'ou', généralement collés à une commande die ():

$foo = bar() or die('Error: bar function return false.');

La plupart du temps, nous voyons quelque chose comme:

mysql_query('SELECT ...') or die('Error in during the query');

Cependant, je ne comprends pas comment fonctionne exactement cette "ou" déclaration.

Je voudrais lancer une nouvelle exception à la place de die (), mais:

try{
    $foo = bar() or throw new Exception('We have a problem here');

Ne fonctionne pas, et ni

$foo = bar() or function(){ throw new Exception('We have a problem here'); }

La seule façon pour moi de faire cela est cette pensée horrible:

function ThrowMe($mess, $code){
    throw new Exception($mess, $code);
}
try{
    $foo = bar() or ThrowMe('We have a problem in here', 666);
}catch(Exception $e){
    echo $e->getMessage();
}

Mais il existe un moyen de lancer une nouvelle exception directement après l'instruction 'ou'?

Ou ce type de structure est obligatoire (je ne vois pas du tout la fonction ThrowMe):

try{
    $foo = bar();
    if(!$foo){
        throw new Exception('We have a problem in here');
    }
}catch(Exception $e){
    echo $e->getMessage();
}

Modifier : ce que je veux, c'est vraiment éviter d'utiliser un if () pour vérifier chaque opération potentiellement dangereuse que je fais, par exemple:

#The echo $e->getMessage(); is just an example, in real life this have no sense!
try{
    $foo = bar();
    if(!$foo){
        throw new Exception('Problems with bar()');
    }
    $aa = bb($foo);
    if(!$aa){
        throw new Exception('Problems with bb()');
    }
    //...and so on!
}catch(Exception $e){
    echo $e->getMessage();
}

#But i relly prefer to use something like:

try{
    $foo = bar() or throw new Exception('Problems with bar()');
    $aa = bb($foo) or throw new Exception('Problems with bb()');
    //...and so on!
}catch(Exception $e){
    echo $e->getMessage();
}

#Actually, the only way i figured out is:

try{
    $foo = bar() or throw new ThrowMe('Problems with bar()', 1);
    $aa = bb($foo) or throw new ThrowMe('Problems with bb()', 2);
    //...and so on!
}catch(Exception $e){
    echo $e->getMessage();
}

#But i'll love to thro the exception directly instead of trick it with ThrowMe function.
Était-ce utile?

La solution

ou est simplement un opérateur logique , et c'est analogue à || .

L'astuce commune de

mysql_query() or die();

pourrait tout aussi bien être écrit

mysql_query() || die();

Ce qui se passe ici est le "logique ou" L’opérateur (selon votre choix) essaie de déterminer si l’un des opérandes est évalué à VRAI. Cela signifie que les opérandes doivent être des expressions pouvant être converties en booléens.

Donc, la raison

bar() or throw new Exception();

est illégal, car

(boolean)throw new Exception();

est également illégal. Essentiellement, le processus de génération d'une exception ne génère pas de valeur de retour à vérifier par l'opérateur.

Mais appeler une fonction génère génère une valeur de retour à vérifier par l'opérateur (aucune valeur de retour explicite ne sera générée dans la fonction renvoyant NULL , qui renvoie . FALSE ) c'est pourquoi cela fonctionne pour vous lorsque vous encapsulez une exception en lançant une fonction.

L’espoir que cela aide.

Autres conseils

Pourquoi bar () et bb () ne jettent-ils pas les exceptions? Dans PHP Exceptions bouillonne, il n’est donc pas nécessaire de lancer l’exception dans la fonction / méthode où vous appelez bar () / bb () . Ces exceptions peuvent être levées par bar () / bb () . Si vous souhaitez lancer une autre exception, vous pouvez simplement faire:

function foo() {
    try {
        $bar = bar();
    } catch (BarException) {
        throw new FooException;
    }
}

Une solution que j'ai trouvée qui peut remplacer "ou die ()". partout est de boucler le lancer avec une fonction anonyme appelée immédiatement par call_user_func:

call_user_func(function(){
    throw new Exception("ERROR");
});

Vous pouvez voir que cela fonctionne en l'exécutant sur un script factice:

false or call_user_func(function(){throw new Exception("ERROR");});

Je pense que vous souhaitez utiliser quelque chose comme la dernière structure, même s'il est inutile d'utiliser des exceptions pour cela:

$foo = bar();
if(!$foo){
    echo 'We have a problem in here';
}

Par commentaire - Je ne pense pas que vous puissiez le faire en une seule ligne (c'est-à-dire sans la vérification de si (! $ foo) ), et je conviens que la méthode de projection par exception est assez horrible . Personnellement, je préfère le caractère explicite de:

$foo = bar();
if(!$foo){
    throw new Exception('We have a problem in here');
}

mais c'est une préférence personnelle. Si vous voulez la ligne unique, je pense que vous devrez choisir l'option de la fonction de lancement d'exception.

J'imagine que cette limitation est probablement due à la dactylographie dynamique de PHP: elle peut convertir les résultats d'un appel de fonction en conditionnel, mais pas ceux d'un throw .

Voici une solution à une seule ligne sans la fonction supplémentaire:

if (!($foo = bar())) throw new Exception('We have a problem here');

J'ai simplement défini la fonction lancer pour cela.

function toss(Exception $exception): void
{
    throw $exception;
}

Parce que les informations fichier / ligne / pile sont capturées lorsque l'exception est construite ( nouveau ) non levée ( jeter ) ceci ne ' t interférer avec la pile d'appels.

Donc, vous pouvez simplement faire ceci.

something() or toss(new Exception('something failed'));

Vous pouvez également créer une classe d'exceptions personnalisée et utiliser sa méthode de constructeur statique au lieu de jeter une nouvelle construction Exception () .

Classe d'exception:

class CustomException extends Exception {
  static public function doThrow($message = "", $code = 0, Exception $previous = null) {
    throw new Exception($message, $code, $previous);
  }
}

Utilisation:

try {

  $foo = bar() or CustomException::doThrow('Problems with bar()');
  $aa = bb($foo) or CustomException::doThrow('Problems with bb()');

} catch(Exception $e){
  echo $e->getMessage();
}
  

Remarque

     

Si vous utilisez PHP 7 et versions supérieures, vous pouvez renommer la méthode statique doThrow () en throw () , car en PHP 7 et versions supérieures, il est autorisé à utiliser mots clés réservés en tant que noms de méthodes.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top