Пожалуйста. Чтобы добавить, fetch () не генерирует исключение независимо от того, какой PDO :: ATTR_ERRMOD используется. Он всегда вернет ложь при неудаче. Даже если вы поместите свой stmt в блок try / catch и после этого вызовете fetch (), он все равно вернет false. fetchAll () также будет возвращать false при сбое, но я никогда не получал его, чтобы возвращать false. Даже в примере этого комментария он вернет пустой массив.

етствует документам php, методу PDOвыборки () возвращает значениеFALSE оба, когда записи не найденыА ТАКЖЕ при сбое (например, когда что-то идет не так в отношении доступа к базе данных).

Предположим, я настроил систему отчетов об ошибках PHP, чтобы она генерировала исключения при сбое:

PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION

Мне нужен случай, ситуация, в которойfetch() Метод сгенерирует исключение. Почему? Потому что я хочу проверить, чтобы быть на 100% уверенным, чтоfetch() выдает исключение при неудаче и не просто возвращаетFALSE на провал.

Если бы это было так, то я бы действительно рассмотрелFALSE вернулсяfetch() в результате не найти никаких записей в таблице БД.

Итак, мой вопрос: знаете ли вы способ имитации ситуации отказа дляfetch() мето, D?

Спасибо.

ПостскриптумОтвет на мой вопрос поможет мне найти ответ на другой мой вопрос:PHP PDO fetch возвращает FALSE, если не найдено ни одной записи И при ошибке

Изменить 1:

Я также подготовил пример, чтобы показать, как я обрабатываю исключения. Это простой SQL-запрос, извлекающий пользователя изusers Таблица:

<?php

// Activate error reporting.
error_reporting(E_ALL);
ini_set('display_errors', 1);

try {

    // Create a PDO instance as db connection to a MySQL db.
    $connection = new PDO(
            'mysql:host=localhost;port=3306;dbname=mydb;charset=utf8'
            , 'myuser'
            , 'mypass'
            , array(
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_EMULATE_PREPARES => FALSE,
        PDO::ATTR_PERSISTENT => TRUE
            )
    );

    // Define the sql statement.
    $sql = 'SELECT * FROM users WHERE name = :name';

    /*
     * Prepare and validate the sql statement.
     * 
     * --------------------------------------------------------------------------------
     * If the database server cannot successfully prepare the statement, PDO::prepare() 
     * returns FALSE or emits PDOException (depending on error handling settings).
     * --------------------------------------------------------------------------------
     */
    $statement = $connection->prepare($sql);

    if (!$statement) {
        throw new UnexpectedValueException('The sql statement could not be prepared!');
    }

    // Bind the input parameter to the prepared statement.
    $bound = $statement->bindValue(':name', 'Sarah', PDO::PARAM_STR);

    // Validate the binding of the input parameter.
    if (!$bound) {
        throw new UnexpectedValueException('An input parameter can not be bound!');
    }

    /*
     * Execute the prepared statement.
     * 
     * ------------------------------------------------------------------
     * PDOStatement::execute returns TRUE on success or FALSE on failure.
     * ------------------------------------------------------------------
     */
    $executed = $statement->execute();

    if (!$executed) {
        throw new UnexpectedValueException('The prepared statement can not be executed!');
    }

    /*
     * Fetch and validate the result set.
     * 
     * =========================================================
     * Note:
     * =========================================================
     * PDOStatement::fetch returns FALSE not only on failure,
     * but ALSO when no record is found!
     * 
     * Instead, PDOStatement::fetchAll returns FALSE on failure,
     * but an empty array if no record is found. This is the
     * natural, desired behaviour.
     * =========================================================
     */
    $resultset = $statement->fetch(PDO::FETCH_ASSOC);

    if ($resultset === FALSE) {
        throw new UnexpectedValueException('Fetching data failed!');
    }

    // Display the result set.
    var_dump($resultset);
    echo '<pre>' . print_r($resultset, TRUE) . '</pre>';

    // Close connection.
    $connection = NULL;
} catch (PDOException $exc) {
    echo '<pre>' . print_r($exc, TRUE) . '</pre>';
    exit();
} catch (Exception $exc) {
    echo '<pre>' . print_r($exc, TRUE) . '</pre>';
    exit();
}

Я использовал следующий синтаксис создания таблицы:

DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=124 DEFAULT CHARSET=utf8;

и следующие значения таблицы:

INSERT INTO `users` (`id`, `name`)
VALUES
    (1,'Sarah'),
    (2,'John');

Итак, таблица выглядит так:

id  name
--------
1   Sarah
2   John
 tereško21 сент. 2017 г., 13:54
Включить отчеты об ошибках на основе исключений
 KIKO Software21 сент. 2017 г., 14:06
Ну, в этом случае обработка исключений - это путь. Попробуй. Это будет работать.
 user794133422 сент. 2017 г., 16:20
@MasivuyeCokile Я наконец-то нашел случай, который позволил мне смоделировать ситуацию с ошибкойPDOStatement::fetch(), Я отправил ответ на это. Еще раз спасибо за ваши комментарии!
 user794133421 сент. 2017 г., 13:57
Спасибо, @teresko. У меня это уже есть. Но, поскольку php.net сообщает, что в случае сбоя возвращается FALSE, я не знаю, если вместо FALSE выдается исключение при сбое.
 KIKO Software21 сент. 2017 г., 13:56
В руководстве говорится: «Возвращаемое значение этой функции в случае успеха зависит от типа выборки. Во всех случаях FALSE возвращается при ошибке». Я ожидаю, что это вернетсяNULL когда нет результатов. Так что возможны два разных теста:if ($result === FALSE) ... проверить на неудачу иif (!isset($result)) .... или жеif (is_null($result)) проверить на отсутствие записей.

Ответы на вопрос(1)

Решение Вопроса

PDOStatement::fetch действительно бросил бы исключение в случае неудачи.

Кредиты:

СтатьяИспользование преимуществ режимов извлечения PDO представляет такую ​​ситуацию. Он основан на использованииPDOStatement::fetchAll с участиемPDO::FETCH_KEY_PAIR константа, переданная в качестве аргумента.

Контрольная работа:

Итак, я провел тест самостоятельно. Но я использовалPDOStatement::fetch метод вместо По определению,PDO::FETCH_KEY_PAIR константа требует, чтобы таблица источника данных содержала только два столбца. В моем тесте я определил три столбца таблицы.PDOStatement::fetch признал эту ситуацию неудачной и выдал исключение:

SQLSTATE [HY000]: общая ошибка: режим извлечения PDO :: FETCH_KEY_PAIR требует, чтобы результирующий набор содержал ровно 2 столбца.

Заключение:PDOStatement::fetch возвращаетсяFALSE, если записи не найдены.PDOStatement::fetch бросает - действительно - исключение в случае неудачи.Примечания:Вместо,PDOStatement::fetchAll возвращает пустой массив, если записи не найдены.PDO::FETCH_KEY_PAIR константа не документирована наPDOStatement :: выборки официальная страница.P.S:

Я хочу поблагодарить всех пользователей, которые пытались помочь мне найти ответ на мой вопрос. Вы имеете мою оценку!

Код, используемый для тестирования:
<?php

// Activate error reporting.
error_reporting(E_ALL);
ini_set('display_errors', 1);

try {

    // Create a PDO instance as db connection to a MySQL db.
    $connection = new PDO(
            'mysql:host=localhost;port=3306;dbname=tests;charset=utf8'
            , 'root'
            , 'root'
            , array(
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_EMULATE_PREPARES => FALSE,
        PDO::ATTR_PERSISTENT => TRUE
            )
    );

    // Define the sql statement.
    $sql = 'SELECT * FROM users WHERE name = :name';

    /*
     * Prepare the sql statement.
     * 
     * --------------------------------------------------------------------------------
     * If the database server cannot successfully prepare the statement, PDO::prepare() 
     * returns FALSE or emits PDOException (depending on error handling settings).
     * --------------------------------------------------------------------------------
     */
    $statement = $connection->prepare($sql);

    // Validate the preparation of the sql statement.
    if (!$statement) {
        throw new UnexpectedValueException('The sql statement could not be prepared!');
    }

    // Bind the input parameter to the prepared statement.
    $bound = $statement->bindValue(':name', 'Sarah', PDO::PARAM_STR);

    // Validate the binding of the input parameter.
    if (!$bound) {
        throw new UnexpectedValueException('An input parameter can not be bound!');
    }

    /*
     * Execute the prepared statement.
     * 
     * ------------------------------------------------------------------
     * PDOStatement::execute returns TRUE on success or FALSE on failure.
     * ------------------------------------------------------------------
     */
    $executed = $statement->execute();

    // Validate the execution of the prepared statement.
    if (!$executed) {
        throw new UnexpectedValueException('The prepared statement can not be executed!');
    }

    // Fetch the result set.
    $resultset = $statement->fetch(PDO::FETCH_KEY_PAIR);

    // If no records found, define the result set as an empty array.
    if ($resultset === FALSE) {
        $resultset = [];
    }

    // Display the result set.
    var_dump($resultset);

    // Close connection.
    $connection = NULL;
} catch (PDOException $exc) {
    echo '<pre>' . print_r($exc->getMessage(), TRUE) . '</pre>';
    exit();
} catch (Exception $exc) {
    echo '<pre>' . print_r($exc->getMessage(), TRUE) . '</pre>';
    exit();
}
Создать синтаксис таблицы:
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(100) DEFAULT NULL,
  `phone` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
Вставьте значения синтаксиса:
INSERT INTO `users` (`id`, `name`, `phone`)
VALUES
    (1,'Sarah','12345'),
    (2,'John','67890');
Табличные значения:
id  name    phone
-----------------
1   Sarah   12345
2   John    67890

Ваш ответ на вопрос