Php остановить выполнение при ошибке

(PHP 4, PHP 5, PHP 7, PHP 8)

exitВывести сообщение и прекратить выполнение текущего скрипта

Описание

exit(string $status = ?): void

exit(int $status): void

exit — это конструкция языка, и она может быть вызвана без круглых скобок, если не передаётся параметр status.

Список параметров

status

Если status задан в виде строки, то эта
конструкция выведет содержимое status перед выходом.

Если status задан в виде целого числа (int),
то это значение будет использовано как статус выхода и не будет выведено.
Статусы выхода должны быть в диапазоне от 0 до 254, статус выхода 255 зарезервирован
PHP и не должен использоваться. Статус выхода 0 используется для успешного
завершения программы.

Возвращаемые значения

Функция не возвращает значения после выполнения.

Примеры

Пример #1 Пример использования exit


<?php

$filename

= '/path/to/data-file';
$file = fopen($filename, 'r')
or exit(
"Невозможно открыть файл ($filename)");?>

Пример #2 Пример использования exit со статусом выхода


<?php//обычный выход из программы
exit;
exit();
exit(
0);//выход с кодом ошибки
exit(1);
exit(
0376); //восьмеричный?>

Пример #3 Функции выключения и деструкторы выполняются независимо


<?php
class Foo
{
public function
__destruct()
{
echo
'Деинициализировать: ' . __METHOD__ . '()' . PHP_EOL;
}
}

function

shutdown()
{
echo
'Завершить: ' . __FUNCTION__ . '()' . PHP_EOL;
}
$foo = new Foo();
register_shutdown_function('shutdown');

exit();
echo

'Эта строка не будет выведена.';
?>

Результат выполнения данного примера:

 Завершить: shutdown()
 Деинициализировать: Foo::__destruct()

dexen dot devries at gmail dot com

12 years ago


If you want to avoid calling exit() in FastCGI as per the comments below, but really, positively want to exit cleanly from nested function call or include, consider doing it the Python way:

define an exception named `SystemExit', throw it instead of calling exit() and catch it in index.php with an empty handler to finish script execution cleanly.

<?php// file: index.php
class SystemExit extends Exception {}
try {
  
/* code code */
}
catch (
SystemExit $e) { /* do nothing */ }
// end of file: index.php

// some deeply nested function or .php file   

if (SOME_EXIT_CONDITION)
   throw new
SystemExit(); // instead of exit()?>


albert at removethis dot peschar dot net

14 years ago


jbezorg at gmail proposed the following:

<?phpif($_SERVER['SCRIPT_FILENAME'] == __FILE__ )
 
header('Location: /');?>

After sending the `Location:' header PHP _will_ continue parsing, and all code below the header() call will still be executed.  So instead use:

<?phpif($_SERVER['SCRIPT_FILENAME'] == __FILE__)
{
 
header('Location: /');
  exit;
}
?>


theonenkl at gmail dot com

8 years ago


A side-note for the use of exit with finally: if you exit somewhere in a try block, the finally won't be executed. Could not sound obvious: for instance in Java you never issue an exit, at least a return in your controller; in PHP instead you could find yourself exiting from a controller method (e.g. in case you issue a redirect).

Here follows the POC:

<?php
echo "testing finally wit exitn";

try {
    echo

"In try, exitingn";

    exit;
} catch(

Exception $e) {
    echo
"catchedn";
} finally {
    echo
"in finallyn";
}

echo

"In the endn";
?>

This will print:

testing finally wit exit
In try, exiting


vincent dot laag at gmail dot com

12 years ago


Don't use the  exit() function in the auto prepend file with fastcgi (linux/bsd os).
It has the effect of leaving opened files with for result at least a nice  "Too many open files  ..." error.

void a t informance d o t info

14 years ago


To rich dot lovely at klikzltd dot co dot uk:

Using a "@" before header() to suppress its error, and relying on the "headers already sent" error seems to me a very bad idea while building any serious website.

This is *not* a clean way to prevent a file from being called directly. At least this is not a secure method, as you rely on the presence of an exception sent by the parser at runtime.

I recommend using a more common way as defining a constant or assigning a variable with any value, and checking for its presence in the included script, like:

in index.php:
<?php
define
('INDEX', true);
?>

in your included file:
<?php
if (!defined('INDEX')) {
   die(
'You cannot call this script directly !');
}
?>

BR.

Ninj


emils at tvnet dot lv

19 years ago


Note, that using exit() will explicitly cause Roxen webserver to die, if PHP is used as Roxen SAPI module. There is no known workaround for that, except not to use exit(). CGI versions of PHP are not affected.

alexyam at live dot com

11 years ago


When using php-fpm, fastcgi_finish_request() should be used instead of register_shutdown_function() and exit()

For example, under nginx and php-fpm 5.3+, this will make browsers wait 10 seconds to show output:

<?php
   
echo "You have to wait 10 seconds to see this.<br>";
   
register_shutdown_function('shutdown');
    exit;
    function
shutdown(){
       
sleep(10);
        echo
"Because exit() doesn't terminate php-fpm calls immediately.<br>";
    }
?>

This doesn't:

<?php
   
echo "You can see this from the browser immediately.<br>";
   
fastcgi_finish_request();
   
sleep(10);
    echo
"You can't see this form the browser.";
?>


m dot libergolis at gmail dot com

7 years ago


In addition to "void a t informance d o t info", here's a one-liner that requires no constant:

<?php basename($_SERVER['PHP_SELF']) == basename(__FILE__) && die('Thou shall not pass!'); ?>

Placing it at the beginning of a PHP file will prevent direct access to the script.

To redirect to / instead of dying:

<?php
if (basename($_SERVER['PHP_SELF']) == basename(__FILE__)) {
    if (
ob_get_contents()) ob_clean(); // ob_get_contents() even works without active output buffering
   
header('Location: /');
    die;
}
?>

Doing the same in a one-liner:

<?php basename($_SERVER['PHP_SELF']) == basename(__FILE__) && (!ob_get_contents() || ob_clean()) && header('Location: /') && die; ?>

A note to security: Even though $_SERVER['PHP_SELF'] comes from the user, it's safe to assume its validity, as the "manipulation" takes place _before_ the actual file execution, meaning that the string _must_ have been valid enough to execute the file. Also, basename() is binary safe, so you can safely rely on this function.


devinemke at devinemke dot com

21 years ago


If you are using templates with numerous includes then exit() will end you script and your template will not complete (no </table>, </body>, </html> etc...).  Rather than having complex nested conditional logic within your content, just create a "footer.php" file that closes all of your HTML and if you want to exit out of a script just include() the footer before you exit().

for example:

include ('header.php');
blah blah blah
if (!$mysql_connect) {
echo "unable to connect";
include ('footer.php');
exit;
}
blah blah blah
include ('footer.php');


nicoladinh at gmail dot com

12 years ago


Calling to exit() will flush all buffers started by ob_start() to default output.

tianyiw at vip dot qq dot com

6 months ago


These are the standard error codes in Linux or UNIX.

1 - Catchall for general errors
2 - Misuse of shell builtins (according to Bash documentation)
126 - Command invoked cannot execute
127 - “command not found”
128 - Invalid argument to exit
128+n - Fatal error signal “n”
130 - Script terminated by Control-C
255* - Exit status out of range


powtac at gmx de

4 years ago


When a object is passed as $status and it consists of a __toString() magic method the string value of this method will be used as $status. If the object does not contain a __toString method, exit will throw a catchable fatal error.

sunfundev at gmail dot com

5 years ago


>> Shutdown functions and object destructors will always be executed even if exit is called.

It is false if you call exit into desctructor.

Normal exit:
<?php
class A
{
    public function
__destruct()
    {
        echo
"bye An";
    }
}

class

B
{
    public function
__destruct()
    {
        echo
"bye Bn";
    }
}
$a = new A;
$b = new B;
exit;
// Output:
// bye B
// bye A
?>

// Exit into desctructor:
<?php
class A
{
    public function
__destruct()
    {
        echo
"bye An";
    }
}

class

B
{
    public function
__destruct()
    {
        echo
"bye Bn";
        exit;
    }
}
$a = new A;
$b = new B;// Output:
// bye B
?>


chris at ocproducts dot com

5 years ago


Calling 'exit' will bypass the auto_append_file option.
On some free hosting this risks you getting removed, as they may be using for ads and analytics.

So be a bit careful if using this on the most common output branch.


shaun at NOshatSPAM dot net

20 years ago


return may be preferable to exit in certain situations, especially when dealing with the PHP binary and the shell.

I have a script which is the recipient of a mail alias, i.e. mail sent to that alias is piped to the script instead of being delivered to a mailbox. Using exit in this script resulted in the sender of the email getting a delivery failure notice. This was not the desired behavior, I wanted to silently discard messages which did not satisfy the script's requirements.

After several hours of trying to figure out what integer value I should pass to exit() to satisfy sendmail, I tried using return instead of exit. Worked like a charm. Sendmail didn't like exit but it was perfectly happy with return. So, if you're running into trouble with exit and other system binaries, try using return instead.


matt at serverboy dot net

13 years ago


It should be noted that if building a site that runs on FastCGI, calling exit will generate an error in the server's log file. This can quickly fill up.

Also, using exit will diminish the performance benefit gained on FastCGI setups. Instead, consider using code like this:

<?phpif( /* error case */ )
    echo
"Invalid request";
else {
   
/* The rest of your application */
}
?>

I've also seen developers get around this issue with FastCGI by wrapping their code in a switch statement and using breaks:

index.php:
<?phpswitch(true) {
    case
true:
        require(
'application.php');
}
?>

application.php:
<?phpif($x > $y) {
    echo
"Sorry, that didn't work.";
    break;
}
// ...?>

It does carry some overhead, but compared to the alternative, it does the job well.


marco dot marsala at live dot it

5 years ago


Please note $status is printed to stdout, not stderr.

kehaovista at qq dot com

7 years ago


<?phpclass Foo
{
    public function
__construct()
    {
       
register_shutdown_function([$this, 'shutdown']);
    }

    public function

__destruct()
    {
        echo
'Destruct: ' . __METHOD__ . '()' . PHP_EOL;
    }

    function

shutdown()
    {
        echo
'Shutdown: ' . __FUNCTION__ . '()' . PHP_EOL;
    }
}
$foo = new Foo();
exit();
// output is
//Shutdown: shutdown()
//Destruct: Foo::__destruct()


Alexander Behling

2 years ago


it is also possible to include function calls e.g. logging function to write the error in a log file.

e.g.

function logerror($error){
file_put_contents(__DIR__.'/error_log', 'Error occured: '.$error');
}

die(logerror('error msg here');

This will terminate the script and write "error msg here" to error.log

You could use this for example when query the database to log when the query fails.


You can globally configure this within your php.ini file­Docs.

It can be done by specifying a file that is being included by all PHP processes with the auto_prepend_file directive­Docs:

auto_prepend_file "/full/path/to/a/prepend-file.php"

Doing that inside your global php.ini file will ensure that the code inside the prepend file will be always executed. Use it then to register a global error handler that will turn all errors into exceptions­Docs:

<?php
function exception_error_handler($errno, $errstr, $errfile, $errline ) {
    throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
}
set_error_handler("exception_error_handler");

This little script will turn all errors/warnings/notices etc. into an ErrorException.

This code example is likely too short (will comment further below) so don’t miss the examples on the set_error_handler()­Docs manual page.

Combine it with the error_reporting ini directive­Docs, the values are describe in your php.ini file (or as another option use the second parameter for set_error_handler handle errors by their severity).

Throwing an exception is a very strict thing. Your programmers will be forced to deal with warnings and errors otherwise the code won’t not work (including those in code with the @ error control operator, rendering it void).

Probably this is too much and not socially acceptable within the company. Instead you can also log all errors and add them at the end of the output (or at the top so it’s more visible) by making use of output buffering.

Creating (but not throwing) the error exception already captures a back-trace which can be useful in error handling.

Another alternative to display the errors and warnings is to log them to the log-file and then monitor that file with another process and aggregate the information. You could create a scoreboard that display the number of warnings per application and make this visible in the office so everybody sees how well a team performs or some fun like that.

What I try to say is: Next to the technical problem, it’s a social problem you need to be creative with and actually talk the problem out of your developers. You need to make clear why it’s important to fix warnings and errors and how their coding and skills will benefit from that.

За последние 24 часа нас посетили 12248 программистов и 878 роботов. Сейчас ищут 572 программиста …


  1. machetero

    machetero
    Активный пользователь

    С нами с:
    25 окт 2014
    Сообщения:
    499
    Симпатии:
    21

    При подключении файла в php7 с синтаксической ошибкой, сделанной намерено, выполнение скрипта прекращается. Почему ? Блока try catch нету. Должно вылетать исключение и выполнение должно продолжаться.
    Вызываемый файл:

    1. include __DIR__.‘/new.php’;

    Подключаемый файл:

    1.     public function throwex(){
    2.     echo ‘now ex will be thrown’;
    3.     echo ‘throwing was done’;

    Строка «after error» не выводиться.
    Неужели теперь при любой ошибке в php7 выполнение скрипта будет прекращаться ?


  2. Fell-x27

    Команда форума
    Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.162
    Симпатии:
    1.770
    Адрес:
    :сердА

    1) Деление на ноль — это не синтаксическая ошибка. Это ошибка деления на ноль.
    2) Я не вижу у тебя нигде кода вызова throwex();
    3) Я не вижу у тебя в классе конструктора, а он, если не ошибаюсь, обязан присутствовать в php7. Может, ошибка из-за этого?
    4) Вообще, отображение ошибок не забыл включить?


  3. machetero

    machetero
    Активный пользователь

    С нами с:
    25 окт 2014
    Сообщения:
    499
    Симпатии:
    21

    Там знак бакса пропущен в присвоении. Деление на ноль даёт ворнинг.

    Отображение включено. Выводится parse error. Хотя в мане написано что не перехваченые исключения-ошибки должны превращаться в fatal error.

    Единственное что работает, это перехват try catch’ем этой ошибки.


  4. Fell-x27

    Команда форума
    Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.162
    Симпатии:
    1.770
    Адрес:
    :сердА

    Пардоньте, не заметил. Последние месяца два пишу исключительно на JS, и глаз привык к переменным без доллира.Ну дык Parse error — это тебе для понимания, а по коду ошибки она может проходить как Fatal.

    Далее. Читаем:

    В PHP 7 при возникновении фатальных ошибок (E_ERROR) и фатальных ошибок с возможностью обработки (E_RECOVERABLE_ERROR) будет выброшен exception, а не произойдет завершение скрипта.

    У тебя это и происходит. Это нормальное поведение исключений — если их не перехватывать, приложение аварийно завершается. Просто раньше оно падало в любом случае, а теперь можно обернуть это дело в try/catch, ловить ошибку там, и не бояться, что у тебя все обрушится.
    — Добавлено —
    Вот тебе из доков:


  5. machetero

    machetero
    Активный пользователь

    С нами с:
    25 окт 2014
    Сообщения:
    499
    Симпатии:
    21

    Раньше было лучше тем, что когда случалась не фатальная ошибка, код после неё продолжал выполняться.


  6. Fell-x27

    Команда форума
    Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.162
    Симпатии:
    1.770
    Адрес:
    :сердА

    Протестую. Когда код работает после фатальной ошибки, это нифига не лучше. Вся система в разнос пойти может.


  7. machetero

    machetero
    Активный пользователь

    С нами с:
    25 окт 2014
    Сообщения:
    499
    Симпатии:
    21

    Раньше было лучше тем, что когда случалась не фатальная ошибка, код после неё продолжал выполняться.


  8. mkramer

    Команда форума
    Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.522
    Симпатии:
    1.744

    Исключение бросается, ты его не ловишь. А непойманное исключение — фатальная ошибка. Вот попробуй так:

    1.     include __DIR__ . «/new.php»;
    2.     echo $e->getMessage() . «<br>»;

    Я уже попробовал, всё как задумано

    1. syntax error, unexpected ‘=’

    — Добавлено —
    А такая ошибка синтаксиса всегда вызывала остановку выполнения скрипта раньше.


  9. machetero

    machetero
    Активный пользователь

    С нами с:
    25 окт 2014
    Сообщения:
    499
    Симпатии:
    21

    Просто обычно в try catch не заворачивают какие то мелкие куски кода(а в них может произойти ошибка), а заворачивают целиком весь код, так что после catch уже никаких вызовов нет.


  10. mkramer

    Команда форума
    Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.522
    Симпатии:
    1.744

    А смысл заворачивать весь код? Я как раз-таки относительно небольшие куски кода в try { } catch() {} оборачиваю, особенно там, где ошибка не предполагается, но если произойдёт — её возможно обработать. А ловлей синтаксических ошибок через catch как не занимался, так и не буду заниматься. Их не должно быть в production, а при разработке я хочу их сразу же видеть, так что пусть себе прерывается


  11. machetero

    machetero
    Активный пользователь

    С нами с:
    25 окт 2014
    Сообщения:
    499
    Симпатии:
    21


  12. Fell-x27

    Команда форума
    Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.162
    Симпатии:
    1.770
    Адрес:
    :сердА

    Ты ошибки парсинга ловить собрался чтоль трай-кэчем? По-моему ты решаешь проблему, которую сам себе придумал.


  13. mkramer

    Команда форума
    Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.522
    Симпатии:
    1.744

    Ну вероятно может быть ситуация, когда это может пригодиться, иначе не ввели бы в язык. Например, пригодилось бы в WordPress. Сейчас, если допустить в файле functions.php активной темы синтаксическую ошибку, валится весь сайт вместе с админкой. А если бы подключение functions.php темы было реализовано через новый механизм php 7, можно было бы в админке красивое сообщение показать «Файл functions.php вашей темы содержит синтаксическую ошибку»


  14. Fell-x27

    Команда форума
    Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.162
    Симпатии:
    1.770
    Адрес:
    :сердА

    Я тебе отвечу твоими же словами:


  15. mkramer

    Команда форума
    Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.522
    Симпатии:
    1.744

    Так проблема в том, что темки зачастую пишет пользователь wordpress, а не авторы движка.


  16. Fell-x27

    Команда форума
    Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.162
    Симпатии:
    1.770
    Адрес:
    :сердА

    Ну дык пишешь ты тему для вордпресса — увидел, что все обвалилось к чертовой матери, поправил, заработало.

    Или ты имеешь ввиду случай, когда какой-то мудак выложил тему или модуль с ошибкой, и они вместе, весело и с брызгами положили сайт незадачливому блоггеру?


  17. mkramer

    Команда форума
    Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.522
    Симпатии:
    1.744

    Ну да. И куча пользователей wordPress, которые правят тему методом копипасты с кривых сайтов. Вот недавно я участвовал в написании плагина для wordPress, который массово используется. И имею счастье наблюдать, какие вопросы приходят от пользователей.

Время на прочтение
6 мин

Количество просмотров 31K

В статье описан функционал, который доступен в PHP (актуально для 5.3.х) для обработки ошибок всех типов, включая ошибки интерпретации кода (E_ERROR, E_PARSE, E_WARNING, etc). Эта обработка поможет вам для управляемого отображения страницы в случае возникновения таких проблем. В статье присутствует множество описаний и рабочих примеров(архитектуры) для того, что бы сразу воспользоваться в своем программном продукте. В конце концов, ну немного сломали сайт, ну надо же, об этом сообщить поисковику с заголовком 4хх или 5хх и повеселить пользователя, вместо возврата белого экрана (или что хуже экрана со священной информацией, для хакеров) с ответом 200 Ok.

Идея написать этот топик возникла, когда я на храбре задал 2 вопроса:

  • Вопрос о перехвате предупреждений и вывод ошибок в указанное место шаблона
  • Вопрос о перехвате критических ошибок, заставляющие выполнение скрипт только остановиться

По моей карме и добавление в избранное я понял, что они оказались интересные для PHP хабрасообщества. По этой причине я решил оформить решения этих вопросов в виде статьи, да бы людям и поисковикам было проще и комплексно находить нужную информацию.

Если заинтересовались, то подробности под катом…

Причины использования

Пользователю/поисковику, требуется внятно ответить, что на сервере проблемы. Без использования определенного фен-шуя, этого добиться достаточно трудно, а порой невозможно. Тут я проливаю свет на все это, ну и себе заметочку оставляю, так как еще неделю назад я не знал за что взяться, и, наверное, многие новички тоже будут обескуражены.

Описания функций

Данный функционал доступен в PHP для того, что бы обрабатывать ошибки и контролировать вывод. Вот описание их вкусностей и недостатков. Документацию я приводить не буду, я только сошлюсь её страницы и опишу свое мнение. Все что будет приведено это только малая доля, ссылки на соответствующие разделы документации я приведу в конце статьи. Итак встречаем:

— Контроль некритических ошибок: замечания, предупреждения, пользовательские ошибки. В общем все то, что не завершает интерпретацию аварийно.
set_error_handler — Задает определенный пользователем обработчик ошибок.
Нужен для того, что бы писать в лог все такие ошибки. Если её не задать, то в лог это не пишется, а мне вот всегда хочется узнать при каких боевых ситуациях могут вызываться замечания и предупреждения. То есть позволяет автоматически тестировать продукт пользователем и он даже не будет замечать этого.
Если функция не задана, то PHP лишь пытается вывести данные на экран, а если ему и это не дают, то вообще никаких признаков жизни от этих типов ошибок не возникает.

— Контроль, исключений: является ошибкой типа E_ERROR.
set_exception_handler — Задает пользовательский обработчик исключений
Ну не знаю, зачем это вообще было придумано, когда есть то, что описано ниже и просто обработка ошибки типа Exception. Так что сообщаю что оно просто существует. Она перехватывает критическую ошибку «исключение» и позволяет что-то с ней делать. В любом случае скрипт завершается. Её работы по умолчанию лично для меня достаточно (пишет в логи, пытается вывести на экран). Я бы её вообще не переопределял, а то придется в логи о случившимся исключении самому писать.

— Функции контроля вывода: Тут я опишу 3 функции, которые следует знать по разным причинам. Например, для проблем производительности или для проблем вывода заголовков. В нашем случае требуется выводить заголовки ошибок.

ob_start — Включение буферизации вывода
ob_flush — Сброс (отправка) буфера вывода
ob_end_clean — Очищает (стирает) буфер вывода и отключает буферизацию вывода

Если вкратце, то данные функции позволяют записывать все данные выводимые через echo в некий буфер. Это функционал позволяют отправлять заголовки в любой части кода, а так же многие другие вещи, темы которых не относится к данной статье. А если вдруг случилась беда. То можно сбрасывать весь буфер и весь стек (об этом не в этой статье), писать заголовок ошибки и выводить уведомление пользователю.

— Получение последней произошедшей ошибки: её надо использовать вместе с другими перехватывающими функциями, которые тут описаны.
error_get_last — Получение информации о последней произошедшей ошибке
С помощью нее, возможно вернуть последнюю ошибку. Ей очень удобно ловить критические ошибки и код становится оптимальным (появилась с 5.2.х если что).

— Функция которая запускается после того как все отработало: Барабанная дробь.
register_shutdown_function — Регистрирует функцию, которая выполнится по завершении работы скрипта. Завершение может быть штатным или аварийным, без разницы.
Много плюсов и никаких минусов:

  • Данная функция не переопределяется, а определяется дополнительно, и определить вы её можете много раз
  • Так как она не переопределяется, то все ошибки уже пишутся в лог так или иначе, их не требуется переопределять
  • Данная функция, не еще отправляет контент, о чем написано в документации, и соотвественно можно пользоваться функциями буферизации

Многие Объектно Ориентированные люди обрадуются

Что все вышеизложенные функции можно зарегистрировать даже на методы классов, а также, наверняка, на статические методы классов по той же схеме. Правда способ очень не очевиден для глаза обычного не PHP программиста.
Параметр handler требуется задать через массив, с элементами «название класса|объекта», «метод объекта». Устанавливаемый метод обязательно должен быть public. Пример для функции set_error_handler:

<?php
class BaseErrorCatcher
{
	public function __construct()
	{
		set_error_handler(array($this, 'ErrorCatcher'));
		
		echo "друг, я создалсяn";
		
		$errorVarArray['real index'] = true;
		echo $errorVarArray['error index'];
	}
	
	public function ErrorCatcher($errno, $errstr)
	{
		echo "друг, да ты вероянто напортачил где-то в этом: $errstrn";
	}
}

error_reporting(E_ALL | E_STRICT);	// включаем замечания у кого они выключены
ini_set('display_errors','On');		// ну уж что бы точно вы увидели результат
new BaseErrorCatcher();			// начало теста
?>

Результат:

друг, я создался
друг, да ты вероянто напортачил где-то в этом: Undefined index: error index

Рабочий пример

Пример работы, архитектура класса для универсального и полного контроля ошибок. Я исследовал этот вопрос очень досконально и составил гибридный метод, из ответов на заданные мною вопросы.

Условия

Есть файл с кодом, который запускается первым или перед кодом в котоом может появиться ошибка и этот файл и все файлы до него 100% отлаженные с невозможностью появления ошибки. Вот такое вот условие, что бы было проще — без ошибок до того пока не пройдут все регистрации вышеизложенных функций. В данном файле описаны данные методики контроля ошибок в комплексе. Контролируется буфер, если ошибка, то сбросить буфер и вывести ошибку.

Код с комментариями

От себя добавлю, что код не тестировал, так как это упрощенная схема того, что у меня в коде, замечания принимаются

<?php

class ErrorSupervisor
{
	public function __construct()
	{
		// регистрация ошибок
		set_error_handler(array($this, 'OtherErrorCatcher'));
		
		// перехват критических ошибок
		register_shutdown_function(array($this, 'FatalErrorCatcher'));
		
		// создание буфера вывода
		ob_start();
	}
	
	public function OtherErrorCatcher($errno, $errstr)
	{
		// контроль ошибок:
		// - записать в лог
		return false;
	}
	
	public function FatalErrorCatcher()
	{
		$error = error_get_last();
		if (isset($error))
			if($error['type'] == E_ERROR
				|| $error['type'] == E_PARSE
				|| $error['type'] == E_COMPILE_ERROR
				|| $error['type'] == E_CORE_ERROR)
			{
				ob_end_clean();	// сбросить буфер, завершить работу буфера
			
				// контроль критических ошибок:
				// - записать в лог
				// - вернуть заголовок 500
				// - вернуть после заголовка данные для пользователя
			}
			else
			{
				ob_end_flush();	// вывод буфера, завершить работу буфера
			}
		else
		{
			ob_end_flush();	// вывод буфера, завершить работу буфера
		}
	}
}

// запуск контроллера
$errorController = new ErrorSupervisor();

// генерируем контент
// изменяем заголовки, в обещм делаем много чего
echo "генерация простейшего контента";

// тестируем систему (не тестировал, но у меня в более сложном варианте работает)
include 'null'; // запускается OtherErrorCatcher
// require 'null'; // запустится FatalErrorCatcher
// require 'foobar.php'; // а внутри этого файла вообще ошибка компиляции
?>

Ссылки

Разделы документации

  • Функции обработки ошибок
  • Функции контроля вывода
  • Управление функциями — невзрачно оформлено правда? Без помощи Aco я бы еще очень долго читал документацию и решал задачу.
Другая полезная информация

  • Функция echo в PHP может выполняться более 1 секунды
  • Предопределенные константы — они же типы ошибок

Спасибо за внимание.

UPD: По советам из комментариев, дополнил класс ErrorSupervisor новой функциональностью, исправил пару заблуждений, добавил дополнительную интересную информацию по теме, немного отладил код

UPD2 Внимание: Товарищ по PHP-разуму написал хорошую статью про битовые операции в PHP как раз к теме данной статьи, советую почитать. Эти знания позволяют более элегантно писать код. Менять текст данной статьи уже не стал для того, что бы сохранился смысл.

<?php
     function some_function($arg) {
         if($filter->check_for_safe_input($arg)) {
             throw new Exception("Hacking Attempt");
         }
         do_some_database_stuff($arg);
     }
 ?>

In the above code example, does do_some_database_stuff ever get called if check_for_safe_input fails, or does the exception stop the function running? It’s something I’ve never quite been sure of, and usually I just stick functions like do_some_database_stuff in an else statement to be sure, but this tends to lead to hugely nested functions.

asked Feb 20, 2010 at 12:24

Not Joe Bloggs's user avatar

Not Joe BloggsNot Joe Bloggs

8491 gold badge9 silver badges13 bronze badges

Yes, uncaught exceptions result in fatal errors that stop the execution of the script. So the do_some_database_stuff function will not be called if an exception is thrown. You can read more about exceptions in this article.

Justin Maxwell's user avatar

answered Feb 20, 2010 at 12:26

Darin Dimitrov's user avatar

Darin DimitrovDarin Dimitrov

1.0m270 gold badges3284 silver badges2923 bronze badges

5

Have a look at the PHP manual on exceptions.

When an exception is thrown, code
following the statement will not be
executed, and PHP will attempt to find
the first matching catch block. 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().

php.net/exceptions

So yes, the rest of the function is not being executed, a fatal error occurs instead.
If you catch the exception, execution of the script continues in the corresponding catch block, everything «between» the function which throws an exception and the catch block is not executed.

Mantosh's user avatar

answered Feb 20, 2010 at 12:28

svens's user avatar

An exception, if not catched, will end script execution.

See the PHP manual chapter on Exceptions

answered Feb 20, 2010 at 12:27

Gordon's user avatar

GordonGordon

312k73 gold badges535 silver badges557 bronze badges

Понравилась статья? Поделить с друзьями:
  • Php обработка ошибок на форме
  • Php обработка ошибок и исключений
  • Php номер строки с ошибкой
  • Php не показывать ошибки на странице
  • Php не пишет ошибки в лог