Domanda

Tutti qui dovrebbero conoscere gli stati 'o', di solito incollati a un comando die ():

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

Il più delle volte vediamo qualcosa come:

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

Tuttavia, non riesco a capire esattamente come funziona questa "o" frase.

Vorrei lanciare una nuova eccezione invece di die (), ma:

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

Non funziona e nemmeno

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

L'unico modo in cui ho scoperto di farlo è questo orribile pensiero:

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();
}

Ma c'è un modo per lanciare una nuova eccezione direttamente dopo l'istruzione 'o'?

O questo tipo di struttura è obbligatoria (non mento affatto la funzione ThrowMe):

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

Modifica : quello che voglio è davvero evitare l'uso di un if () controllare ogni potenziale operazione pericolosa che faccio, ad esempio:

#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.
È stato utile?

Soluzione

o è solo un operatore logico ed è analogo a || .

Il trucco comune di

mysql_query() or die();

potrebbe anche essere scritto

mysql_query() || die();

Quello che succede qui è il " logico o " l'operatore (a seconda di quale si sceglie) sta cercando di determinare se uno degli operandi restituisce VERO. Ciò significa che gli operandi devono essere espressioni che possono essere espressi come booleani.

Quindi, il motivo

bar() or throw new Exception();

è illegale, è perché

(boolean)throw new Exception();

è anche illegale. In sostanza, il processo di generazione di un'eccezione non genera un valore di ritorno che l'operatore può controllare.

Ma chiamando una funzione genera un valore di ritorno che l'operatore deve controllare (nessun valore di ritorno esplicito comporterà la funzione che restituisce NULL che viene lanciato come FALSE ) che è il motivo per cui funziona quando si racchiude l'eccezione che lancia una funzione.

Spero che sia d'aiuto.

Altri suggerimenti

Perché bar () e bb () non generano eccezioni? Nelle eccezioni di PHP si verificano bolle, quindi non è necessario generare l'eccezione nella funzione / metodo in cui si chiama bar () / bb () . Queste eccezioni possono essere generate da bar () / bb () . Nel caso in cui desideri lanciare un'altra eccezione, puoi semplicemente fare:

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

Una soluzione che ho trovato che può sostituire " o die () " ovunque è concludere il tiro con una funzione anonima che viene chiamata immediatamente da call_user_func:

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

Puoi vedere che funziona eseguendo questo su uno script fittizio:

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

Penso che tu voglia usare qualcosa come l'ultima struttura, anche se non ha davvero senso usare le eccezioni per questo:

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

Per commento - Non credo che tu possa farlo in una sola riga (cioè senza il if (! $ foo) check), e sono d'accordo che il metodo di lancio delle eccezioni è piuttosto orribile . Personalmente, preferisco l'esplicitazione di:

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

ma questa è una preferenza personale. Se vuoi la cosa a linea singola, penso che dovrai scegliere l'opzione per la funzione di lancio delle eccezioni.

Immagino che questa limitazione sia probabilmente dovuta alla roba di tipizzazione dinamica di PHP, può trasmettere i risultati di una chiamata di funzione a un condizionale, ma non i risultati di un lancio .

Ecco una soluzione a linea singola senza la funzione aggiuntiva:

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

Per questo ho semplicemente definito la funzione lancio .

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

Poiché le informazioni su file / linea / stack vengono acquisite quando l'eccezione viene costruita ( new ) non generata ( lancio ), ciò non significa ' interferire con lo stack di chiamate.

Quindi puoi semplicemente farlo.

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

Puoi anche creare una classe di eccezione personalizzata e utilizzare il suo metodo di costruzione statico invece di lanciare nuova costruzione Exception () .

Classe di eccezione:

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

Utilizzo:

try {

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

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

Nota

     

Se si utilizza PHP 7 e versioni successive, è possibile rinominare il metodo statico doThrow () semplicemente throw () , poiché in PHP 7 e versioni successive è consentito utilizzare parole chiave riservate come nomi di metodi.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top