cari

Rumah  >  Soal Jawab  >  teks badan

Gabungkan berbilang jenis pengecualian dalam blok tangkapan

Saya ingin cara yang lebih bersih untuk mendapatkan fungsi berikut untuk ditangkap dalam blok AErrorBError :

try
{
    /* something */
}
catch( AError, BError $e )
{
    handler1( $e )
}
catch( Exception $e )
{
    handler2( $e )
}

Adakah ada cara untuk melakukan ini? Atau adakah saya perlu menangkap mereka secara individu?

AErrorBerror 有一个共享基类,但它们也与我想落入 handler2 dikongsi oleh jenis lain, jadi saya tidak boleh menangkap kelas asas sahaja.

P粉547420474P粉547420474426 hari yang lalu626

membalas semua(2)saya akan balas

  • P粉777458787

    P粉7774587872023-10-15 15:07:15

    Ini mungkin dalam PHP >= 7.1. Lihat ini jawapan.


    Jika anda boleh mengubah suai pengecualian, sila gunakan jawapan ini.

    Kalau belum boleh cuba guna Exception 捕获所有异常,然后使用 instanceof.

    try
    {
        /* something */
    }
    catch( Exception $e )
    {
        if ($e instanceof AError OR $e instanceof BError) {
           // It's either an A or B exception.
        } else {
            // Keep throwing it.
            throw $e;
        }
    }

    Tetapi adalah lebih baik menggunakan berbilang blok tangkapan seperti yang dinyatakan dalam jawapan di atas .

    try
    {
        /* something */
    }
    catch( AError $e )
    {
       handler1( $e );
    }
    catch ( BError $b )
    {
       handler2( $e );
    }

    balas
    0
  • P粉611456309

    P粉6114563092023-10-15 00:46:51

    Kemas kini:

    Ciri ini tersedia bermula dari PHP 7.1.

    Sintaksnya ialah:

    try
    {
        // Some code...
    }
    catch(AError | BError $e)
    {
        // Handle exceptions
    }
    catch(Exception $e)
    {
        // Handle the general case
    }

    Dokumentasi: https://www.php.net/manual/en/language.exceptions.php#example-334

    RFC: https://wiki.php.net/rfc/multiple-catch

    Komit: https://github.com/php/php-src/commit/ 0aed2cc2a440e7be17552cc669d71fdd24d1204a


    Untuk versi sebelum PHP 7.1:

    Walaupun jawapan yang lain ini katakan, anda boleh menangkap AErrorBError dalam blok yang sama (lebih mudah jika anda yang menentukan pengecualian). Walaupun terdapat pengecualian yang ingin anda "kecualikan", anda masih boleh menentukan hierarki untuk memenuhi keperluan anda.

    abstract class MyExceptions extends Exception {}
    
    abstract class LetterError extends MyExceptions {}
    
    class AError extends LetterError {}
    
    class BError extends LetterError {}

    Kemudian:

    catch(LetterError $e){
        //voodoo
    }

    Seperti yang anda boleh lihat di sinidan di sini, walaupun SPLpengecualian lalai mempunyai hierarki yang boleh dieksploitasi. Selain itu, seperti yang dinyatakan dalam Manual PHP:

    Maknanya anda juga boleh memilikinya

    class CError extends LetterError {}

    Anda perlu mengendalikannya secara berbeza daripada AErrorBError jadi kenyataan tangkapan anda akan kelihatan seperti ini:

    catch(CError $e){
        //voodoo
    }
    catch(LetterError $e){
        //voodoo
    }

    Jika anda mempunyai situasi di mana terdapat dua puluh atau lebih pengecualian yang secara sah tergolong dalam kelas super yang sama, dan anda perlu mengendalikan lima daripadanya (atau mana-mana kumpulan besar) sehala dan selebihnya dengan cara lain, anda masih boleh melakukannya.

    interface Group1 {}
    
    class AError extends LetterError implements Group1 {}
    
    class BError extends LetterError implements Group1 {}

    Kemudian:

    catch (Group1 $e) {}

    Menggunakan OOP apabila mengendalikan pengecualian adalah sangat berkuasa. Menggunakan perkara seperti get_classinstanceof adalah penggodaman dan harus dielakkan jika boleh.

    Satu lagi penyelesaian yang saya ingin tambahkan ialah meletakkan fungsi pengendalian pengecualian ke dalam kaedahnya sendiri.

    Anda boleh memilikinya

    function handleExceptionMethod1(Exception $e)
    {
        //voodoo
    }
    
    function handleExceptionMethod2(Exception $e)
    {
        //voodoo
    }

    Dengan mengandaikan bahawa anda sama sekali tidak mempunyai cara untuk mengawal hierarki atau antara muka kelas pengecualian (dan hampir selalu akan ada cara), anda boleh melakukan perkara berikut:

    try
    {
        stuff()
    }
    catch(ExceptionA $e)
    {
        $this->handleExceptionMethod1($e);
    }
    catch(ExceptionB $e)
    {
        $this->handleExceptionMethod1($e);
    }
    catch(ExceptionC $e)
    {
        $this->handleExceptionMethod1($e);
    }
    catch(Exception $e)
    {
        $this->handleExceptionMethod2($e);
    }

    Dengan cara ini, jika mekanisme pengendalian pengecualian anda perlu diubah, anda masih mempunyai satu lokasi kod yang perlu diubah suai dan anda bekerja dalam binaan umum OOP.

    balas
    0
  • Batalbalas