Pergunta

Todos aqui devem conhecer os statemens 'ou', normalmente colada a uma die () comando:

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

A maioria das vezes nós vemos algo como:

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

No entanto, eu não consigo entender como exatamente isso 'ou' obras de instrução.

Gostaria de lançar uma nova exceção em vez de die (), mas:

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

não funciona, e nem

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

A única maneira que eu encontrei para fazer isso é esse pensamento horrível:

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

Mas há uma maneira de lançar uma nova exceção logo após o 'ou' declaração?

Ou este tipo de estrutura é obrigatória (eu não liek a função ThrowMe em tudo):

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

Editar : o que eu quero realmente é para evitar o uso de um if () verificar cada potencial operação perigosa eu faço, por exemplo:

#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.
Foi útil?

Solução

or é apenas um lógica operador, e é análoga para ||.

O truque comum de

mysql_query() or die();

poderia muito bem ser escrita

mysql_query() || die();

O que acontece aqui é o operador "ou lógico" (o que você escolher) está tentando determinar se o operando é avaliado como true. Isto significa que os operandos devem ser expressões que podem ser expressos como um boolean.

Assim, a razão

bar() or throw new Exception();

é ilegal, é porque

(boolean)throw new Exception();

também é ilegal. Em essência, o processo de lançar uma exceção não gera um valor de retorno para o operador para verificar.

Mas chamar uma função faz gerar um valor de retorno para o operador verificar (sem valor de retorno explícita resultará int a função retornando NULL que lança como FALSE) é por isso que ele funciona para você quando você envolvê lançando exceção em uma função.

Espero que ajude.

Outras dicas

Por que não bar() e bb() jogar as exceções? Em PHP Exceções borbulhar, por isso não há necessidade de lançar a exceção na função / método onde você chamar bar() / bb(). Essas exceções podem ser lançadas por bar() / bb(). No caso de você querer jogar outra exceção, você pode simplesmente fazer:

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

A solução que eu encontrei que pode substituir "ou die ()" em todos os lugares é envolver o arremesso com uma função anônima que é chamada imediatamente por call_user_func:

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

Você pode ver que ele funciona, executando isso em um script fictício:

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

Eu acho que você quer usar algo como a última estrutura, embora não há realmente nenhum ponto em usar exceções para isso:

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

Por comentário - Eu não acho que você pode fazer isso em uma única linha (ou seja, sem a verificação if(!$foo)), e eu concordo que o método de exceção de arremesso é bastante horrível. Pessoalmente, eu prefiro a explicitação de:

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

mas isso é uma preferência pessoal. Se você quiser a coisa de uma única linha, eu acho que você vai ter que ir com a sua opção de função de arremesso de exceção.

Eu acho que essa limitação é provavelmente baixo para coisas dynamic-digitação de PHP, ele pode lançar os resultados de uma chamada de função para uma condicional, mas não os resultados de um throw.

Aqui está uma solução de linha única, sem a função extra:

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

Eu simplesmente definida a função toss para isso.

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

Porque a linha / informações do arquivo / pilha é capturada quando a exceção é construído (new) não lançada (throw) esta não interfere com a pilha de chamadas.

Assim, você pode simplesmente fazer isso.

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

Você também pode criar uma classe de exceção personalizada e usá-lo de método construtor estático em vez de construção throw new Exception().

classe Exceção:

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

Uso:

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 você estiver usando PHP 7 e superior -. Você pode renomear método doThrow() estática simplesmente throw(), já que em PHP 7 e superior é permitido o uso de palavras-chave reservadas como nomes de métodos

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top