PHP.mk документација

Исклучоци

Почист и полокален преглед на PHP референцата, со задржана структура од PHP.net и подобра читливост за примери, секции и белешки.

language.exceptions.php PHP.net прокси Преводот се освежува
Оригинал на PHP.net
Патека language.exceptions.php Локална патека за оваа страница.
Извор php.net/manual/en Оригиналниот HTML се реупотребува и локално се стилизира.
Режим Прокси + превод во позадина Кодовите, табелите и белешките остануваат читливи во истиот тек.
Исклучоци

Референца за `language.exceptions.php` со подобрена типографија и навигација.

language.exceptions.php

Исклучоци

Содржина

PHP has an exception model similar to that of other programming languages. An exception can be thrown, and caught ("catched") within PHP. Code may be surrounded in a try block, to facilitate the catching of potential exceptions. Each try must have at least one corresponding catch or finally block.

If an exception is thrown and its current function scope has no catch block, the exception will "bubble up" the call stack to the calling function until it finds a matching catch block. All finally blocks it encounters along the way will be executed. If the call stack is unwound all the way to the global scope without encountering a matching catch block, the program will terminate with a fatal error unless a global exception handler has been set.

The thrown object must be an instanceof Проверува тврдење. Trying to throw an object that is not will result in a PHP Fatal Error.

Од PHP 8.0.0, throw keyword is an expression and may be used in any expression context. In prior versions it was a statement and was required to be on its own line.

catch

А catch block defines how to respond to a thrown exception. A catch block defines one or more types of exception or error it can handle, and optionally a variable to which to assign the exception. (The variable was required prior to PHP 8.0.0.) The first catch block a thrown exception or error encounters that matches the type of the thrown object will handle the object.

Multiple catch blocks can be used to catch different classes of exceptions. Normal execution (when no exception is thrown within the try block) will continue after that last catch блок дефиниран во секвенца. Може да се појават исклучоци throwн (или повторно фрлен) во рамките на catch блок. Ако не, извршувањето ќе продолжи по catch блок што беше активиран.

Кога ќе се фрли исклучок, кодот што следи по изјавата нема да се изврши, а PHP ќе се обиде да го најде првиот соодветен catch блок. Ако исклучокот не е фатен, ќе се издаде PHP Fatal Error со порака "Uncaught Exception ..." порака, освен ако не е дефиниран ракувач со set_exception_handler().

Од PHP 7.1.0, а catch блок може да специфицира повеќе исклучоци користејќи ја цевката (|) карактер. Ова е корисно кога различни исклучоци од различни хиерархии на класи се третираат на ист начин.

Од PHP 8.0.0, името на променливата за фатен исклучок е опционално. Ако не е специфицирано, catch блокот сепак ќе се изврши, но нема да има пристап до фрлениот објект.

finally

А finally блокот исто така може да биде специфициран по или наместо catch блокови. Кодот во рамките на finally блокот секогаш ќе се извршува по try and catch блокови, без оглед на тоа дали е фрлен исклучок, и пред да продолжи нормалното извршување.

Една забележлива интеракција е помеѓу finally блокот и return изјава. Ако return изјава се сретне внатре во било кој од try или catch блокови, а finally блокот сепак ќе се изврши. Покрај тоа, return изјавата се проценува кога ќе се наиде на неа, но резултатот ќе биде вратен по finally блокот се извршува. Дополнително, ако finally блокот исто така содржи return изјава, вредноста од finally блокот се враќа.

Друга забележлива интеракција е помеѓу исклучок фрлен од внатрешноста на try блок, и исклучок фрлен од внатрешноста на finally блок. Ако и двата блока фрлат исклучок, тогаш исклучокот фрлен од finally блокот ќе биде оној што се шири, а исклучокот фрлен од try блокот ќе се користи како негов претходен исклучок.

Глобален ракувач со исклучоци

Ако на исклучокот му е дозволено да се искачи до глобалниот опсег, тој може да биде фатен од глобален ракувач со исклучоци ако е поставен. На set_exception_handler() функцијата може да постави функција што ќе се повика наместо catch блок ако не е повикан друг блок. Ефектот е суштински ист како ако целата програма беше завиткана во try-catch блок со таа функција како catch.

Белешки

Забелешка:

Внатрешните PHP функции главно користат Пријавување грешки, само модерно Object-oriented екстензиите користат исклучоци. Сепак, грешките лесно можат да се преведат во исклучоци со ErrorException. Оваа техника работи само со нефатални грешки, сепак.

Пример #1 Претворање на известувањето за грешки во исклучоци

<?php
function exceptions_error_handler($severity, $message, $filename, $lineno) {
throw new
ErrorException($message, 0, $severity, $filename, $lineno);
}

set_error_handler('exceptions_error_handler');
?>
Совети

На Стандардна PHP библиотека (SPL) обезбедува добар број на вградени исклучоци.

Примери

Пример #2 Фрлање исклучок

<?php
function inverse($x) {
if (!
$x) {
throw new
Exception('Division by zero.');
}
return
1/$x;
}

try {
echo
inverse(5) . "\n";
echo
inverse(0) . "\n";
} catch (
Exception $e) {
echo
'Caught exception: ', $e->getMessage(), "\n";
}

// Continue execution
echo "Hello World\n";
?>

Пример #1 Пример што покажува затворачка ознака што го опфаќа последниот нов ред

0.2
Caught exception: Division by zero.
Hello World

Пример #3 Ракување со исклучоци со finally block

<?php
function inverse($x) {
if (!
$x) {
throw new
Exception('Division by zero.');
}
return
1/$x;
}

try {
echo
inverse(5) . "\n";
} catch (
Exception $e) {
echo
'Caught exception: ', $e->getMessage(), "\n";
} finally {
echo
"First finally.\n";
}

try {
echo
inverse(0) . "\n";
} catch (
Exception $e) {
echo
'Caught exception: ', $e->getMessage(), "\n";
} finally {
echo
"Second finally.\n";
}

// Continue execution
echo "Hello World\n";
?>

Пример #1 Пример што покажува затворачка ознака што го опфаќа последниот нов ред

0.2
First finally.
Caught exception: Division by zero.
Second finally.
Hello World

Пример #4 Интеракција помеѓу finally блок и return

<?php

function test() {
try {
throw new
Exception('foo');
} catch (
Exception $e) {
return
'catch';
} finally {
return
'finally';
}
}

echo
test();
?>

Пример #1 Пример што покажува затворачка ознака што го опфаќа последниот нов ред

finally

Пример #5 Вгнезден исклучок

<?php

class MyException extends Exception { }

class
Test {
public function
testing() {
try {
try {
throw new
MyException('foo!');
} catch (
MyException $e) {
// rethrow it
throw $e;
}
} catch (
Exception $e) {
var_dump($e->getMessage());
}
}
}

$foo = new Test;
$foo->testing();

?>

Пример #1 Пример што покажува затворачка ознака што го опфаќа последниот нов ред

string(4) "foo!"

Пример #6 Ракување со повеќекратни исклучоци

<?php

class MyException extends Exception { }

class
MyOtherException extends Exception { }

class
Test {
public function
testing() {
try {
throw new
MyException();
} catch (
MyException | MyOtherException $e) {
var_dump(get_class($e));
}
}
}

$foo = new Test;
$foo->testing();

?>

Пример #1 Пример што покажува затворачка ознака што го опфаќа последниот нов ред

string(11) "MyException"

Пример #7 Изоставување на фатената променлива

Дозволено само во PHP 8.0.0 и понови.

<?php

class SpecificException extends Exception {}

function
test() {
throw new
SpecificException('Oopsie');
}

try {
test();
} catch (
SpecificException) {
print
"A SpecificException was thrown, but we don't care about the details.";
}
?>

Пример #1 Пример што покажува затворачка ознака што го опфаќа последниот нов ред

A SpecificException was thrown, but we don't care about the details.

Пример #8 Фрлање како израз

Дозволено само во PHP 8.0.0 и понови.

<?php

function test() {
do_something_risky() or throw new Exception('It did not work');
}

function
do_something_risky() {
return
false; // Simulate failure
}

try {
test();
} catch (
Exception $e) {
print
$e->getMessage();
}
?>

Пример #1 Пример што покажува затворачка ознака што го опфаќа последниот нов ред

It did not work

Пример #9 Исклучок во try и во finally

<?php

try {
try {
throw new
Exception(message: 'Third', previous: new Exception('Fourth'));
} finally {
throw new
Exception(message: 'First', previous: new Exception('Second'));
}
} catch (
Exception $e) {
var_dump(
$e->getMessage(),
$e->getPrevious()->getMessage(),
$e->getPrevious()->getPrevious()->getMessage(),
$e->getPrevious()->getPrevious()->getPrevious()->getMessage(),
);
}

Пример #1 Пример што покажува затворачка ознака што го опфаќа последниот нов ред

string(5) "First"
string(6) "Second"
string(5) "Third"
string(6) "Fourth"

Белешки од корисници 13 белешки

прашајте на nilpo dot com
пред 16 години
If you intend on creating a lot of custom exceptions, you may find this code useful.  I've created an interface and an abstract exception class that ensures that all parts of the built-in Exception class are preserved in child classes.  It also properly pushes all information back to the parent constructor ensuring that nothing is lost.  This allows you to quickly create new exceptions on the fly.  It also overrides the default __toString method with a more thorough one.

<?php
interface IException
{
    /* Protected methods inherited from Exception class */
    public function getMessage();                 // Exception message 
    public function getCode();                    // User-defined Exception code
    public function getFile();                    // Source filename
    public function getLine();                    // Source line
    public function getTrace();                   // An array of the backtrace()
    public function getTraceAsString();           // Formated string of trace
    
    /* Overrideable methods inherited from Exception class */
    public function __toString();                 // formated string for display
    public function __construct($message = null, $code = 0);
}

abstract class CustomException extends Exception implements IException
{
    protected $message = 'Unknown exception';     // Exception message
    private   $string;                            // Unknown
    protected $code    = 0;                       // User-defined exception code
    protected $file;                              // Source filename of exception
    protected $line;                              // Source line of exception
    private   $trace;                             // Unknown

    public function __construct($message = null, $code = 0)
    {
        if (!$message) {
            throw new $this('Unknown '. get_class($this));
        }
        parent::__construct($message, $code);
    }
    
    public function __toString()
    {
        return get_class($this) . " '{$this->message}' in {$this->file}({$this->line})\n"
                                . "{$this->getTraceAsString()}";
    }
}
?>

Now you can create new exceptions in one line:

<?php
class TestException extends CustomException {}
?>

Here's a test that shows that all information is properly preserved throughout the backtrace.

<?php
function exceptionTest()
{
    try {
        throw new TestException();
    }
    catch (TestException $e) {
        echo "Caught TestException ('{$e->getMessage()}')\n{$e}\n";
    }
    catch (Exception $e) {
        echo "Caught Exception ('{$e->getMessage()}')\n{$e}\n";
    }
}

echo '<pre>' . exceptionTest() . '</pre>';
?>

Here's a sample output:

Caught TestException ('Unknown TestException')
TestException 'Unknown TestException' in C:\xampp\htdocs\CustomException\CustomException.php(31)
#0 C:\xampp\htdocs\CustomException\ExceptionTest.php(19): CustomException->__construct()
#1 C:\xampp\htdocs\CustomException\ExceptionTest.php(43): exceptionTest()
#2 {main}
Јохан
пред 14 години
Custom error handling on entire pages can avoid half rendered pages for the users:

<?php
ob_start();
try {
    /*contains all page logic 
    and throws error if needed*/
    ...
} catch (Exception $e) {
  ob_end_clean();
  displayErrorPage($e->getMessage());
}
?>
tianyiw на vip dot qq dot com
пред 2 години
Easy to understand `finally`.
<?php
try {
    try {
        echo "before\n";
        1 / 0;
        echo "after\n";
    } finally {
        echo "finally\n";
    }
} catch (\Throwable) {
    echo "exception\n";
}
?>
# Print:
before
finally
exception
Еду
12 години пред
The "finally" block can change the exception that has been throw by the catch block.

<?php
try{
        try {
                throw new \Exception("Hello");
        } catch(\Exception $e) {
                echo $e->getMessage()." catch in\n";
                throw $e;
        } finally {
                echo $e->getMessage()." finally \n";
                throw new \Exception("Bye");
        }
} catch (\Exception $e) {
        echo $e->getMessage()." catch out\n";
}
?>

The output is:

Hello catch in
Hello finally 
Bye catch out
Шот (Пјотр Шотковски)
пред 17 години
‘Normal execution (when no exception is thrown within the try block, *or when a catch matching the thrown exception’s class is not present*) will continue after that last catch block defined in sequence.’

‘If an exception is not caught, a PHP Fatal Error will be issued with an “Uncaught Exception …” message, unless a handler has been defined with set_exception_handler().’

These two sentences seem a bit contradicting about what happens ‘when a catch matching the thrown exception’s class is not present’ (and the second sentence is actually correct).
telefoontoestel at nospam dot org
пред 11 години
When using finally keep in mind that when a exit/die statement is used in the catch block it will NOT go through the finally block. 

<?php
try {
    echo "try block<br />";
    throw new Exception("test");
} catch (Exception $ex) {
    echo "catch block<br />";
} finally {
    echo "finally block<br />";
}

// try block
// catch block
// finally block
?>

<?php
try {
    echo "try block<br />";
    throw new Exception("test");
} catch (Exception $ex) {
    echo "catch block<br />";
    exit(1);
} finally {
    echo "finally block<br />";
}

// try block
// catch block
?>
daviddlowe точка flimm на gmail точка com
пред 8 години
Starting in PHP 7, the classes Exception and Error both implement the Throwable interface. This means, if you want to catch both Error instances and Exception instances, you should catch Throwable objects, like this:

<?php

try {
    throw new Error( "foobar" );
    // or:
    // throw new Exception( "foobar" );
}
catch (Throwable $e) {
    var_export( $e );
}

?>
christof+php[AT]insypro.com
пред 8 години
In case your E_WARNING type of errors aren't catchable with try/catch you can change them to another type of error like this:

<?php 
    set_error_handler(function($errno, $errstr, $errfile, $errline){
            if($errno === E_WARNING){
                // make it more serious than a warning so it can be caught
                trigger_error($errstr, E_ERROR);
                return true;
            } else {
                // fallback to default php error handler
                return false;
            }
    });

    try {
            // code that might result in a E_WARNING
    } catch(Exception $e){
            // code to handle the E_WARNING (it's actually changed to E_ERROR at this point)
    } finally {
            restore_error_handler();
    }
?>
Симо
пред 10 години
#3 is not a good example. inverse("0a") would not be caught since (bool) "0a" returns true, yet 1/"0a" casts the string to integer zero and attempts to perform the calculation.
jlherren
пред 2 години
As noted elsewhere, throwing an exception from the `finally` block will replace a previously thrown exception. But the original exception is magically available from the new exception's `getPrevious()`.

<?php
try {
    try {
        throw new RuntimeException('Exception A');
    } finally {
        throw new RuntimeException('Exception B');
    }
}
catch (Throwable $exception) {
    echo $exception->getMessage(), "\n";
    // 'previous' is magically available!
    echo $exception->getPrevious()->getMessage(), "\n";
}
?>

Will print:

Exception B
Exception A
mlaopane на gmail точка com
пред 8 години
<?php

/**
 * You can catch exceptions thrown in a deep level function
 */

function employee()
{
    throw new \Exception("I am just an employee !");
}

function manager()
{
    employee();
}

function boss()
{
    try {
        manager();
    } catch (\Exception $e) {
        echo $e->getMessage();
    }
}

boss(); // output: "I am just an employee !"
Том Поломск
пред 11 години
Contrary to the documentation it is possible in PHP 5.5 and higher use only try-finally blocks without any catch block.
Савсан
пред 14 години
the following is an example of a re-thrown exception and the using of getPrevious function:

<?php

$name = "Name";

//check if the name contains only letters, and does not contain the word name

try
   {
   try
     {
      if (preg_match('/[^a-z]/i', $name)) 
       {
           throw new Exception("$name contains character other than a-z A-Z");
       }   
       if(strpos(strtolower($name), 'name') !== FALSE)
       {
          throw new Exception("$name contains the word name");
       }
       echo "The Name is valid";
     }
   catch(Exception $e)
     {
     throw new Exception("insert name again",0,$e);
     }
   }
 
catch (Exception $e)
   {
   if ($e->getPrevious())
   {
    echo "The Previous Exception is: ".$e->getPrevious()->getMessage()."<br/>";
   }
   echo "The Exception is: ".$e->getMessage()."<br/>";
   }

 ?>
На оваа страница

Автоматски outline од активната документација.

Насловите ќе се појават тука по вчитување.

Попрегледно читање

Примерите, changelog табелите и user notes се визуелно издвоени за да не се губат во долгата содржина.

Брз совет Користи го outline-от Скокни директно на главните секции од активната страница.
Извор Оригиналниот линк останува достапен Кога ти треба целосен upstream context, отвори го PHP.net во нов tab.