У меня небольшие проблемы с тем, чтобы PDO работал, как мне нужно, чтобы он работал при обработке целочисленного значения 0.
В системе фиктивных заказов final_status 0 представляет собой успешно размещенный заказ. Ошибки в порядке приводят к ненулевому целому числу для final_status, например 14, 5 и т. д. Неполные заказы требуют фактического значения NULL final_status.
Вот пример структуры таблицы:
CREATE TABLE `order_status` (
`order_id` int(10) NOT NULL,
`final_status` int(10) DEFAULT NULL,
`date_status` datetime DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Когда порядок обновляется, я сталкиваюсь с проблемой, когда PDO либо устанавливает final_status из 0 в NULL, либо устанавливает фактические значения NULL / blank в 0 (в зависимости от того, какую константу я объявляю в операторе связывания).
Итак, если предположить:
$final_status = 0000;
$order_id = 123456;
Запрос на обновление:
try
{
$q = "
UPDATE
order_status
SET
final_status = :final_status
WHERE
order_id = :order_id
";
$stmt = $dbx_pdo->prepare($q);
$stmt->bindValue(':final_status', !empty($final_status) ? $final_status : NULL, PDO::PARAM_NULL);
$stmt->bindValue(':order_id', !empty($order_id) ? $order_id : NULL, PDO::PARAM_INT);
$stmt->execute();
$stmt->closeCursor();
} catch(PDOException $err) {
error_handler();
}
Если я использую PARAM_NULL для первой константы bindParam, значения «0000» или пустые значения преобразуются в NULL, что создает ложноотрицательный результат.
Если я использую PARAM_INT, значения «0000» или пустые значения переводятся в 0, что создает ложное срабатывание и является плохим.
Итак, виновато ли определение таблицы или есть способ сделать то, что я хочу, с INT?






Я думаю (не уверен), проблема в том, что вы используете !empty(). Это преобразует 0 в false, что сделает тернарное условие недействительным. Следовательно, если $final_status == 0, ваше тернарное условие вернет null.
Попробуйте изменить его на:
isset($final_status) && $final_status >= 0 ? $final_status : null
или же
is_null($final_status) ? null : (int) $final_status
Если этот ответ не сработает, прокомментируйте, и я удалю его, чтобы избежать путаницы в будущем.
Вот строка bindValue, которая в итоге сработала. Он правильно обрабатывает значения final_status, равные 0, целые числа и пустые значения. $stmt->bindValue(':final_status', isset($final_status) ? $final_status : NULL, PDO::PARAM_INT);
из официальной документации http://php.net/manual/en/function.empty.php Следующие значения считаются пустыми:
Это вернет истину.
<?php
$final_status = 000;
echo empty($final_status);
Вместо этого рассмотрите возможность использования isset.
$stmt->bindValue(':final_status', !isset($final_status) ? $final_status : NULL, PDO::PARAM_NULL);
Вот строка bindValue, которая в итоге сработала. Он правильно обрабатывает значения final_status, равные 0, целые числа и пустые значения. $stmt->bindValue(':final_status', isset($final_status) ? $final_status : NULL, PDO::PARAM_INT);
Завтра во второй половине дня протестирую и продолжу.