Stmt php error

The mysqli_stmt_error() function returns the description of the error occurred during the execution of the last statement.

Definition and Usage

The mysqli_stmt_error() function returns the description of the error occurred during the execution of the last statement.

Syntax

mysqli_stmt_error($stmt)

Parameters

Sr.No Parameter & Description
1

stmt(Mandatory)

This is an object representing a statement.

Return Values

PHP mysqli_stmt_error() function returns an string value representing the description of the error occurred during the execution of the last statement. If there are no errors this function returns an empty string.

PHP Version

This function was first introduced in PHP Version 5 and works works in all the later versions.

Example

Following example demonstrates the usage of the mysqli_stmt_error() function (in procedural style) −

<?php
   $con = mysqli_connect("localhost", "root", "password", "mydb");

   mysqli_query($con, "CREATE TABLE myplayers(ID INT, First_Name VARCHAR(255), Last_Name VARCHAR(255), Place_Of_Birth VARCHAR(255), Country VARCHAR(255))");
   print("Table Created.....n");
   mysqli_query($con, "INSERT INTO myplayers values(1, 'Sikhar', 'Dhawan', 'Delhi', 'India')");
   print("Record Inserted.....n");

   $stmt = mysqli_prepare($con, "SELECT * FROM myplayers");

   mysqli_query($con, "DROP TABLE myplayers");

   //Executing the statement
   mysqli_stmt_execute($stmt);

   //Error 
   $error = mysqli_stmt_error($stmt);
   print("Error : ".$error);

   //Closing the statement
   mysqli_stmt_close($stmt);

   //Closing the connection
   mysqli_close($con);
?>

This will produce following result −

Table Created.....
Record Inserted.....
Error : Table 'mydb.myplayers' doesn't exist

Example

In object oriented style the syntax of this function is $con ->error. Following is the example of this function in object oriented style −

<?php
   //Creating a connection
   $con = new mysqli("localhost", "root", "password", "mydb");

   $con -> query("CREATE TABLE myplayers(ID INT, First_Name VARCHAR(255), Last_Name VARCHAR(255), Place_Of_Birth VARCHAR(255), Country VARCHAR(255))");
   print("Table Created.....n");
   $con -> query("INSERT INTO myplayers values(1, 'Sikhar', 'Dhawan', 'Delhi', 'India')");
   print("Record Inserted.....n");

   $stmt = $con ->prepare("SELECT * FROM myplayers");

   $con ->query("DROP TABLE myplayers");

   //Executing the statement
   $stmt->execute();

   //Error
   $error = $stmt ->error;
   print("Error: ".$error);

   //Closing the statement
   $stmt->close();

   //Closing the connection
   $con->close();
?>

This will produce following result −

Table Created.....
Record Inserted.....
Error : Table 'mydb.myplayers' doesn't exist

Example

If there are no errors in the last executed statement object this function returns an empty string −

<?php
   $con = mysqli_connect("localhost", "root", "password", "mydb");

   mysqli_query($con, "CREATE TABLE myplayers(ID INT, First_Name VARCHAR(255), Last_Name VARCHAR(255), Place_Of_Birth VARCHAR(255), Country VARCHAR(255))");
   print("Table Created.....n");

   $query = "INSERT INTO myplayers values(1, 'Sikhar', 'Dhawan', 'Delhi', 'India'),(2, 'Jonathan', 'Trott', 'CapeTown', 'SouthAfrica'),(3, 'Kumara', 'Sangakkara', 'Matale', 'Srilanka')";

   //Preparing a statement
   $stmt = mysqli_prepare($con, $query);

   //Executing the statement
   mysqli_stmt_execute($stmt);
   print("Record Inserted.....n");

   //Error 
   $error = mysqli_stmt_error($stmt);
   print("Error : ".$error);

   //Closing the statement
   mysqli_stmt_close($stmt);

   //Closing the connection
   mysqli_close($con);

?>

This will produce following result −

Table Created.....
Record Inserted.....
Error :

php_function_reference.htm

mysqli_stmt_error

(PHP 5, PHP 7, PHP 8)

mysqli_stmt::$error —mysqli_stmt_error-Возвращает строковое описание ошибки последнего оператора

Description

Object-oriented style

Procedural style

mysqli_stmt_error(mysqli_stmt $statement): string

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

Return Values

Строка,описывающая ошибку.Пустая строка,если ошибка не произошла.

Examples

Пример # 1 Объектно-ориентированный стиль

<?php

$mysqli new mysqli("localhost""my_user""my_password""world");


if (mysqli_connect_errno()) {
    printf("Connect failed: %sn", mysqli_connect_error());
    exit();
}

$mysqli->query("CREATE TABLE myCountry LIKE Country");
$mysqli->query("INSERT INTO myCountry SELECT * FROM Country");


$query "SELECT Name, Code FROM myCountry ORDER BY Name";
if ($stmt $mysqli->prepare($query)) {

    
    $mysqli->query("DROP TABLE myCountry");

    
    $stmt->execute();

    printf("Error: %s.n"$stmt->error);

    
    $stmt->close();
}


$mysqli->close();
?>

Пример # 2 Процедурный стиль

<?php

$link = mysqli_connect("localhost""my_user""my_password""world");


if (mysqli_connect_errno()) {
    printf("Connect failed: %sn", mysqli_connect_error());
    exit();
}

mysqli_query($link"CREATE TABLE myCountry LIKE Country");
mysqli_query($link"INSERT INTO myCountry SELECT * FROM Country");


$query "SELECT Name, Code FROM myCountry ORDER BY Name";
if ($stmt = mysqli_prepare($link$query)) {

    
    mysqli_query($link"DROP TABLE myCountry");

    
    mysqli_stmt_execute($stmt);

    printf("Error: %s.n", mysqli_stmt_error($stmt));

    
    mysqli_stmt_close($stmt);
}


mysqli_close($link);
?>

Приведенные выше примеры будут выведены на экран:

See Also

  • mysqli_stmt_errno () — возвращает код ошибки для последнего вызова оператора
  • mysqli_stmt_sqlstate () — возвращает ошибку SQLSTATE из предыдущей операции оператора

Вступление

Интерфейс mysqli является улучшением (это означает расширение MySQL Improvement) интерфейса mysql , которое устарело в версии 5.5 и удалено в версии 7.0. Расширение mysqli, или, как его иногда называют, улучшенное расширение MySQL, было разработано для использования новых функций, обнаруженных в версиях MySQL версии 4.1.3 и новее. Расширение mysqli включено в версии PHP 5 и более поздних версий.

замечания

Характеристики

Интерфейс mysqli имеет ряд преимуществ: ключевые улучшения над расширением mysql:

  • Объектно-ориентированный интерфейс
  • Поддержка подготовленных заявлений
  • Поддержка нескольких заявлений
  • Поддержка транзакций
  • Расширенные возможности отладки
  • Поддержка встроенного сервера

Он имеет двойной интерфейс : более старый, процедурный стиль и новый, объектно-ориентированный стиль программирования (ООП) . Устаревший mysql имел только процедурный интерфейс, поэтому объектно-ориентированный стиль часто предпочтителен. Тем не менее, новый стиль также благоприятен из-за мощности ООП.

альтернативы

Альтернативой интерфейсу mysqli для доступа к базам данных является новый интерфейс PHP Data Objects (PDO) . Это имеет только программирование в стиле ООП и может иметь доступ только к базам данных MySQL.

MySQLi connect

Объектно-ориентированный стиль

Подключение к серверу

$conn = new mysqli("localhost","my_user","my_password");

Установите базу данных по умолчанию: $conn->select_db("my_db");

Подключение к базе данных

$conn = new mysqli("localhost","my_user","my_password","my_db");

Процедурный стиль

Подключение к серверу

$conn = mysqli_connect("localhost","my_user","my_password");

Задайте базу данных по умолчанию: mysqli_select_db($conn, "my_db");

Подключение к базе данных

$conn = mysqli_connect("localhost","my_user","my_password","my_db");

Проверить подключение к базе данных

Объектно-ориентированный стиль

if ($conn->connect_errno > 0) {
    trigger_error($db->connect_error);
} // else: successfully connected

Процедурный стиль

if (!$conn) {
   trigger_error(mysqli_connect_error());
} // else: successfully connected

Функция query принимает действительную строку SQL и выполняет ее непосредственно против соединения с базой данных $conn

Объектно-ориентированный стиль

$result = $conn->query("SELECT * FROM `people`");

Процедурный стиль

$result = mysqli_query($conn, "SELECT * FROM `people`");

ВНИМАНИЕ

Общей проблемой здесь является то, что люди просто выполняют запрос и ожидают его работы (т. Е. Возвращают объект mysqli_stmt ). Поскольку эта функция принимает только строку, вы сначала создаете запрос. Если в SQL вообще имеются ошибки, компилятор MySQL завершится неудачно, и в этот момент эта функция вернет false .

$result = $conn->query('SELECT * FROM non_existent_table'); // This query will fail
$row = $result->fetch_assoc();

Вышеприведенный код генерирует ошибку E_FATAL потому что $result является false , а не объектом.

PHP Неустранимая ошибка: вызов функции-члена fetch_assoc () для не-объекта

Процедурная ошибка похожа, но не фатальная, потому что мы просто нарушаем ожидания функции.

$row = mysqli_fetch_assoc($result); // same query as previous

Вы получите следующее сообщение от PHP

mysqli_fetch_array () ожидает, что параметр 1 будет mysqli_result, boolean given

Вы можете избежать этого, выполнив сначала тест

if($result) $row = mysqli_fetch_assoc($result);

Цикл через результаты MySQLi

PHP позволяет легко получать данные из ваших результатов и перебирать их с помощью инструкции while . Когда он не может получить следующую строку, он возвращает false , и ваш цикл завершается. Эти примеры работают с

  • mysqli_fetch_assoc — Ассоциативный массив с именами столбцов в виде ключей
  • mysqli_fetch_object — объект stdClass с именами столбцов в качестве переменных
  • mysqli_fetch_array — ассоциативный и числовой массив (могут использовать аргументы для получения того или другого)
  • mysqli_fetch_row — числовой массив

Объектно-ориентированный стиль

while($row = $result->fetch_assoc()) {
    var_dump($row);
}

Процедурный стиль

while($row = mysqli_fetch_assoc($result)) {
    var_dump($row);
}

Чтобы получить точную информацию из результатов, мы можем использовать:

while ($row = $result->fetch_assoc()) {
    echo 'Name and surname: '.$row['name'].' '.$row['surname'].'<br>';
    echo 'Age: '.$row['age'].'<br>'; // Prints info from 'age' column
}

Закрыть соединение

Когда мы закончим запрос к базе данных, рекомендуется закрыть соединение, чтобы освободить ресурсы.

Объектно-ориентированный стиль

$conn->close();

Процедурный стиль

mysqli_close($conn);

Примечание . Соединение с сервером будет закрыто, как только выполнение скрипта закончится, если оно не будет закрыто ранее, явно вызвав функцию закрытия соединения.

Случай использования. Если наш скрипт имеет достаточную сумму обработки для выполнения после получения результата и получил полный набор результатов, мы обязательно должны закрыть соединение. Если бы мы этого не сделали, существует вероятность того, что сервер MySQL достигнет предела соединения, когда веб-сервер находится в тяжелом режиме.

Подготовленные утверждения в MySQLi

Пожалуйста, прочитайте раздел «Предотвращение SQL-инъекции с параметризованными запросами» для полного обсуждения того, почему подготовленные операторы помогают защитить ваши SQL- запросы от атак SQL Injection

Здесь переменная $conn — это объект MySQLi. См. Пример подключения MySQLi для получения более подробной информации.

Для обоих примеров предположим, что $sql

$sql = "SELECT column_1 
    FROM table 
    WHERE column_2 = ? 
        AND column_3 > ?";

? представляет значения, которые мы предоставим позже. Обратите внимание, что нам не нужны котировки для заполнителей, независимо от типа. Мы также можем предоставить только заполнители в частях данных запроса, то есть SET , VALUES и WHERE . Вы не можете использовать заполнители в частях SELECT или FROM .

Объектно-ориентированный стиль

if ($stmt = $conn->prepare($sql)) {
  $stmt->bind_param("si", $column_2_value, $column_3_value);
  $stmt->execute();

  $stmt->bind_result($column_1);
  $stmt->fetch();
  //Now use variable $column_1 one as if it were any other PHP variable
  $stmt->close();
}

Процедурный стиль

if ($stmt = mysqli_prepare($conn, $sql)) {
  mysqli_stmt_bind_param($stmt, "si", $column_2_value, $column_3_value);
  mysqli_stmt_execute($stmt);
  // Fetch data here
  mysqli_stmt_close($stmt);
}

Первый параметр $stmt->bind_param или второй параметр mysqli_stmt_bind_param определяется типом данных соответствующего параметра в SQL-запросе:

параметр Тип данных связанного параметра
i целое число
d двойной
s строка
b капля

Ваш список параметров должен быть в порядке, указанном в вашем запросе. В этом примере si означает, что первый параметр ( column_2 = ? ) Является строкой, а второй параметр ( column_3 > ? ) Является целым числом.

Сведения о получении данных см. В разделе Как получить данные из подготовленного оператора

Исключение строк

Экранирование строк — это более старый ( и менее безопасный ) способ обеспечения безопасности данных для вставки в запрос. Он работает с использованием функции MySQL mysql_real_escape_string () для обработки и дезинфекции данных (другими словами, PHP не выполняет экранирование). API MySQLi обеспечивает прямой доступ к этой функции

$escaped = $conn->real_escape_string($_GET['var']);
// OR
$escaped = mysqli_real_escape_string($conn, $_GET['var']);

На данный момент у вас есть строка, которую MySQL считает безопасной для использования в прямом запросе

$sql = 'SELECT * FROM users WHERE username = "' . $escaped . '"';
$result = $conn->query($sql);

Так почему же это не так безопасно, как подготовленные заявления ? Есть способы обмануть MySQL для создания строки, которую он считает безопасным. Рассмотрим следующий пример

$id = mysqli_real_escape_string("1 OR 1=1");    
$sql = 'SELECT * FROM table WHERE id = ' . $id;

1 OR 1=1 не представляет данные, которые MySQL выйдет, но это все еще представляет SQL-инъекцию. Существуют и другие примеры, которые представляют собой места, где они возвращают небезопасные данные. Проблема заключается в том, что функция ускорения MySQL предназначена для обеспечения соответствия данных синтаксису SQL . Он НЕ предназначен для обеспечения того, чтобы MySQL не мог путать пользовательские данные для инструкций SQL .

Идентификатор ввода MySQLi

Получите последний идентификатор, сгенерированный запросом INSERT в таблице с столбцом AUTO_INCREMENT .

Объектно-ориентированный стиль

$id = $conn->insert_id;

Процедурный стиль

$id = mysqli_insert_id($conn);

Возвращает ноль, если ранее не было запроса на соединение, или если запрос не обновил значение AUTO_INCREMENT.

Вставить идентификатор при обновлении строк

Обычно оператор UPDATE не возвращает идентификатор вставки, поскольку идентификатор AUTO_INCREMENT возвращается только в том случае, когда новая строка была сохранена (или вставлена). Один из способов сделать обновления для нового идентификатора — использовать INSERT ... ON DUPLICATE KEY UPDATE для обновления.

Настройка для следующих примеров:

CREATE TABLE iodku (
    id INT AUTO_INCREMENT NOT NULL,
    name VARCHAR(99) NOT NULL,
    misc INT NOT NULL,
    PRIMARY KEY(id),
    UNIQUE(name)
) ENGINE=InnoDB;

INSERT INTO iodku (name, misc)
    VALUES
    ('Leslie', 123),
    ('Sally', 456);
Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0
+----+--------+------+
| id | name   | misc |
+----+--------+------+
|  1 | Leslie |  123 |
|  2 | Sally  |  456 |
+----+--------+------+

Случай IODKU, выполняющий «обновление» и LAST_INSERT_ID() извлекает соответствующий id :

$sql = "INSERT INTO iodku (name, misc)
    VALUES
    ('Sally', 3333)            -- should update
    ON DUPLICATE KEY UPDATE    -- `name` will trigger "duplicate key"
    id = LAST_INSERT_ID(id),
    misc = VALUES(misc)";
$conn->query($sql);
$id = $conn->insert_id;        -- picking up existing value (2)

Случай, когда IODKU выполняет «вставку», и LAST_INSERT_ID() извлекает новый id :

$sql = "INSERT INTO iodku (name, misc)
    VALUES
    ('Dana', 789)            -- Should insert
    ON DUPLICATE KEY UPDATE
    id = LAST_INSERT_ID(id),
    misc = VALUES(misc);
$conn->query($sql);
$id = $conn->insert_id;      -- picking up new value (3)

Результирующее содержимое таблицы:

SELECT * FROM iodku;
+----+--------+------+
| id | name   | misc |
+----+--------+------+
|  1 | Leslie |  123 |
|  2 | Sally  | 3333 |  -- IODKU changed this
|  3 | Dana   |  789 |  -- IODKU added this
+----+--------+------+

Отладка SQL в MySQLi

Таким образом, ваш запрос не удался (см. MySQLi connect для того, как мы создали $conn )

$result = $conn->query('SELECT * FROM non_existent_table'); // This query will fail

Как мы узнаем, что произошло? $result является false так что это не поможет. К счастью, connect $conn может рассказать нам, что MySQL рассказал нам об ошибке

trigger_error($conn->error);

или процедурный

trigger_error(mysqli_error($conn));

Вы должны получить ошибку, аналогичную

Таблица «my_db.non_existent_table» не существует

Как получить данные из подготовленного заявления

Подготовленные заявления

См. Подготовленные операторы в MySQLi для подготовки и выполнения запроса.

Связывание результатов

Объектно-ориентированный стиль

$stmt->bind_result($forename);

Процедурный стиль

mysqli_stmt_bind_result($stmt, $forename);

Проблема с использованием bind_result заключается в том, что он требует, чтобы оператор указывал столбцы, которые будут использоваться. Это означает, что для выполнения вышеперечисленного запрос должен выглядеть так, как этот SELECT forename FROM users . Чтобы включить больше столбцов, просто добавьте их в качестве параметров в функцию bind_result (и убедитесь, что вы добавили их в SQL-запрос).

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

Затем мы можем выполнить петлю следующим образом:

Объектно-ориентированный стиль

while ($stmt->fetch())
    echo "$forename<br />";

Процедурный стиль

while (mysqli_stmt_fetch($stmt))
    echo "$forename<br />";

Недостатком этого является то, что вы должны сразу назначить множество переменных. Это затрудняет отслеживание больших запросов. Если у вас установлен MySQL Native Driver ( mysqlnd ) , все, что вам нужно сделать, это использовать get_result .

Объектно-ориентированный стиль

$result = $stmt->get_result();

Процедурный стиль

$result = mysqli_stmt_get_result($stmt);

С этим гораздо легче работать, потому что теперь мы получаем объект mysqli_result . Это тот же объект, что и mysqli_query . Это означает, что вы можете использовать регулярный цикл результатов для получения ваших данных.


Что делать, если я не могу установить mysqlnd ?

Если это так, то @Sophivorus вы покрыли этот удивительный ответ .

Эта функция может выполнять задачу get_result без ее установки на сервере. Он просто перебирает результаты и строит ассоциативный массив

function get_result(mysqli_stmt $statement)
{
    $result = array();
    $statement->store_result();
    for ($i = 0; $i < $statement->num_rows; $i++)
    {
        $metadata = $statement->result_metadata();
        $params = array();
        while ($field = $metadata->fetch_field())
        {
            $params[] = &$result[$i][$field->name];
        }
        call_user_func_array(array($statement, 'bind_result'), $params);
        $statement->fetch();
    }
    return $result;
}

Затем мы можем использовать эту функцию для получения таких результатов, как если бы мы использовали mysqli_fetch_assoc()

<?php
$query = $mysqli->prepare("SELECT * FROM users WHERE forename LIKE ?");
$condition = "J%";
$query->bind_param("s", $condition);
$query->execute();
$result = get_result($query);

while ($row = array_shift($result)) {
    echo $row["id"] . ' - ' . $row["forename"] . ' ' . $row["surname"] . '<br>';
}

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

Errors are the most common event a developer faces when programming. Errors can be categorized as syntactical, run-time, or logical: missing the semicolon at the end of a statement is an example of a syntax error; trying to connect to a database when the server is down is an example of a run-time error; providing incorrect data to a variable is an example of a logic error. To help reduce the number of errors in your code, and to mitigate their effects, proper error handling is essential in your web application.

This article is a crash course in PHP error handling. You’ll learn about PHP’s built-in error reporting levels, and how to handle errors with custom error handlers and exception handling.

PHP Error Reporting Levels

All errors and warnings should be logged. Based on the severity of an error, notifications should be sent out to other systems/teams. So that you can better gauge its severity, PHP provides several built-in error levels to describe the nature of an error. Each level is represented by an integer value and named constant which can be used by the programmer. The table below is taken from the official PHP documentation and shows some of the different levels.

error constants

The levels can be masked together with bit-operators to include or subtract them from PHP’s configuration. For example, E_ALL|E_STRICT enables all errors and warnings with the addition of E_STRICT (necessary in versions of PHP prior to 5.4).

PHP provides a few configuration directives related to logging and displaying errors. Their values are generally different depending on whether the system is in a development or a production environment. This table shows some of the error-related directives.

error directives

The configuration directives can be set either in php.ini, in a web server configuration file (httpd.conf or .htaccess file), or at run-time in your script using the ini_set() function. Read the documentation for more information on the directives and how/where to set them.

Creating Custom Error Handlers

It’s also good practice not to display raw errors to the end user. Errors that are displayed should be abstracted with friendly, custom error messages. PHP not only provides built-in functions for logging and displaying errors, but also for raising them. You can pragmatically trigger an error of a specific level using trigger_error(). For example, this code triggers an E_USER_NOTICE warning if the value of $test is greater than 1:

<?php
$test = 5;
if ($test > 1) {
    trigger_error('Value of $test must be 1 or less', E_USER_NOTICE);
}

Triggering errors with trigger_error() is useful when you have an error-handling infrastructure in place, allowing you to unify the handling of both custom errors and the errors and warnings raised by PHP.

If you want to implement customized error handling strategies like sending an email or logging errors to a database based on their severity, then you’ll need to define custom error handlers using set_error_handler(). The function accepts two arguments: a callback function or static method that will be invoked when the error is raised, and optionally the error level the function/method handles. The signature of the callback is:

handler(int $errno, string $errstr, string $errfile, int $errline, array $errcontext)

callback arguments

Let’s take a look at a custom error handler function. The example below records errors to a database table database whenever one is encountered:

<?php
function errorHandler($errno, $errstr, $errfile, $errline) {
    static $db;
    if (empty($db)) {
        $db = new PDO(DSN, DBUSER, DBPASS);
    }

    $query = "INSERT INTO errorlog (severity, message, filename, lineno, time) VALUES (?, ?, ?, ?, NOW())";
    $stmt = $db->prepare($query);

    switch ($errno) {
        case E_NOTICE:
        case E_USER_NOTICE:
        case E_DEPRECATED:
        case E_USER_DEPRECATED:
        case E_STRICT:
            $stmt->execute(array("NOTICE", $errstr, $errfile, $errline));
            break;

        case E_WARNING:
        case E_USER_WARNING:
            $stmt->execute(array("WARNING", $errstr, $errfile, $errline));
            break;

        case E_ERROR:
        case E_USER_ERROR:
            $stmt->execute(array("FATAL", $errstr, $errfile, $errline));
            exit("FATAL error $errstr at $errfile:$errline");

        default:
            exit("Unknown error at $errfile:$errline");
    }
}

set_error_handler("errorHandler");

$test = 5;
if ($test > 1) {
   trigger_error("Value of $test must be 1 or less", E_USER_NOTICE);
}

The above snippet registers an error handler that does the following: when non-fatal errors occur, a record will be inserted into database instead of displaying the error and logging it to a file; When a fatal error occurs, it will be logged in database and terminate your script.

There are some limitations to custom error handlers you should be aware of, however. The error handler bypasses PHP’s standard error handling behavior, so it can’t handle errors that may arise within your handler itself. In the event the database server is down, for example, the above function would fail to record the log. Also, the error handler is not able to catch certain internal errors, like E_CORE_ERROR and E_COMPILE_ERROR, or E_STRICT errors in the same file the handler is defined in since those errors occur before the handler has a chance to be registered.

Handling Errors using Exceptions

However good of an error handling framework you have in place, there will always be problems at run-time. Of course you don’t want these errors to show up in the user’s browser. This is where exception handling enters the picture. Exceptions allows you to handle errors and exceptional situations gracefully.

Exceptions are represented in PHP by the class Excpetion (or any of its subclasses). They can be raised using throw and can be caught using a try/catch block. You can extend Exception to create custom exception types for trapping specific errors.

The code that may trigger an exception is placed within the try block, and the code to handle the exception is placed within the catch block. Consider the following snippet:

<?php
try {
   $data = $this->getDataFromService();
}
catch (Exception $e) {
   echo "Caught exception: " . $e->getMessage() . "n";
}

If an exception is thrown by the fictitious getDataFromService() method, it will be caught in the catch block and a message will be displayed. If getDataFromService() executes successfully then the flow will pass over the catch block and continue through the rest of the script. Any exceptions that are thrown and not caught will generate an E_FATAL error with the message “Uncaught Exception.”

The Exception class offers six different methods to access information about what caused the problem, as shown in the table below.

exception methods

Creating a Custom Exception Handler

PHP will let you throw any object as if it were an exception, but as a rule of thumb the exception should extend PHP’s built-in Exception class. Based on the object’s type, you can handle the exceptions differently. Custom exception handling can perform suitable actions like logging error messages in file, providing exact details about the line on which the error occurred by examining the calling stack, etc.  Have a look at this example:

<?php
class NameException extends Exception { }
class EmailException extends Exception { }

$name = "";
$email= "";

try {
   if (empty($name)) {
       throw new NameException();
   }
   elseif (empty($email)) {
       throw new EmailException();
   }
   else {
       echo "Name is " . $name . "<br>";
       echo "Email is " . $email;
   }
}
catch (NameException $n) {
   echo "A name was not provided.";
   error_log($n->getTraceAsString());
}
catch (EmailException $e) {
   echo "An email address was not provided.";
   error_log($e->getTraceAsString());
}

The code above defines two new custom exception types, NameException and EmailException, which can be used to indicate different errors. Then within the try block, the code checks if values have been supplied for the variables $name and $email. If either is empty, then the appropriate exception is thrown using throw. The corresponding catch block is executed which handles the error.

Re-throwing Exceptions

try/catch blocks can be nested. Sometimes you’ll want to catch an exception, look at some of its properties, and then throw it again to let a parent catch block handle it. This can often be useful to check an error condition and decide whether it should be fatal or not. This example code demonstrates re-throwing an exception:

<?php
class FileExistException extends Exception { }
class FileReadException extends Exception { }

$filename = 'D:Exception.txt';
try {
    try {
        $text = file_get_contents($filename);
        if ($text === false) {
            throw new Exception();
        }
    }
    catch (Exception $e) {
        if (!file_exists($filename)) {
            throw new FileExistException($filename . " does not exist.");
        }
        elseif (!is_readable($filename)) {
            throw new FileReadException($filename . " is not readable.");
        }
        else {
            throw new Exception("Unknown error accessing file.");
        }
    }
}
catch (FileExistException $fe) {
    echo $fe->getMessage();
    error_log($fe->getTraceAsString());
}
catch (FileReadException $fr) {
    echo $fr->getMessage();
    error_log($fr->getTraceAsString());
}

Uncaught Exception Handler

Similar to how set_error_handler() allows you specify a function to handle run-time errors, the set_exception_handler() function allows you to handle exceptions that make it all the way up the call stack without being caught by any catch blocks. For example, if an exception makes it all the way up your stack, it would be a good idea to log it in a log file. You can create a callback function and register it  with set_exception_handler() as shown in the example below.

<?php
set_exception_handler(function ($exception) {
   $file = "var/log/exceptionLog.log";
   file_put_contents($file, $exception->__toString(), FILE_APPEND);
});

throw new Exception();

Summary

PHP offers variety of built-in functions for handling error conditions, including logging and displaying them. It also provides you the flexibility to customize your error handling strategies by registering error handlers and using exceptions. Errors are a fact of life, but hopefully the information I presented in this article will help you handle them more gracefully.

Image via Ilya Andriyanov / Shutterstock

Понравилась статья? Поделить с друзьями:
  • Stm32 uart overrun error
  • Stm32 uart frame error
  • Stm32 error failed to erase memory
  • Stm ide error launching installer
  • Stlink usb communication error