Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Форумы портала PHP.SU :: Версия для печати :: PDO exec() не выполняется
Форумы портала PHP.SU » PHP » SQL и Архитектура БД » PDO exec() не выполняется

Страниц (1): [1]
 

1. Le0_Nard - 10 Января, 2017 - 01:21:30 - перейти к сообщению
Доброй ночи, хабровча... Пхпсушники!

Возникла одна странная проблема, и я ума не приложу, что не так...
CODE (SQL):
скопировать код в буфер обмена
  1. CREATE TABLE `logs` (
  2.   `type` tinyint(1) NOT NULL COMMENT '0 - лог авторизации, 1 лог банов, 2 - лог действий',
  3.   `ip` varchar(23) DEFAULT NULL,
  4.   `status` tinyint(1) DEFAULT NULL COMMENT '0 - ошибка, 1 - успех, 2 - автомат после регистрации, 3 - автомат после смены имейла',
  5.   `email` varchar(50) DEFAULT NULL,
  6.   `password` varchar(40) DEFAULT NULL,
  7.   `ban_action` tinyint(1) DEFAULT NULL COMMENT '0 - забанен, 1 - разбанен',
  8.   `user_target_id` int(11) NOT NULL,
  9.   `till` int(11) DEFAULT NULL,
  10.   `isPerm` tinyint(1) DEFAULT NULL,
  11.   `user_init_id` int(11) DEFAULT NULL,
  12.   `text` text,
  13.   `date` int(11) NOT NULL
  14. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT;

Работаю через PDO, всё стандартно: $db = new PDO(и далее по тексту);
Проблемная функция:
PHP:
скопировать код в буфер обмена
  1. function log_ban($id, $reason, $till=null, $isPerm=null){
  2.   global $db;
  3.   $ban_action = (!is_null($till)) ? 0 : 1; //0 - забанен, 1 - разбанен
  4.   $db->exec('INSERT INTO `logs` (`type`, `ban_action`, `user_target_id`, `till`, `isPerm`,  `user_init_id`, `text`, `date`) VALUES (1, '.$ban_action.', '.$id.', '.$till.', '.$_SESSION['id'].', "'.$reason.'", '.time().')');
  5.  }

Запрос может быть, например, таким:
CODE (SQL):
скопировать код в буфер обмена
  1. INSERT INTO `logs` (`type`, `ban_action`, `user_target_id`, `till`, `isPerm`, `user_init_id`, `text`, `date`) VALUES (1, 0, 3, 1486682564, 0, 1, "Безо всякой причины", 1484004164)

И проблема в том, что этот запрос абсолютно корректен. Он выполняется в любом MySQL-менеджере (я, например, юзаю HeidiSQL). Affected rows: 1 Найденные строки: 0 Предупреждения: 0 Длительность 1 query: 0,172 sec.
Но при вызове самой функции этот запрос не выполняется. Не, может он и выполняется, но ничего не происходит, а сам запрос возвращает (bool) false.
Подскажите, пожалуйста, в чём дело?

P.S. Да, датувремя я храню таймштампом в поле INT, ибо так при выборке получаю тот же таймштамп, а не дату 'YmdHis', которую нужно парсить. Если есть варианты лучше - с радостью посмотрю Улыбка
(Добавление)
Всё, нашёл: количество полей и вставляемых значений не совпадало ("`isPerm`" есть, а "'.$isPerm.', " - нет). Удивительно, почему не выдавалась ошибка...
2. Sail - 10 Января, 2017 - 08:26:55 - перейти к сообщению
Le0_Nard пишет:
а сам запрос возвращает (bool) false
...
Удивительно, почему не выдавалась ошибка...

(bool) false - и есть признак ошибки. При отсутствии оной - возвращается число [0..)
При отладке можно, например, делать так:
PHP:
скопировать код в буфер обмена
  1. $result = $db->exec($someParameters);
  2. if($result === FALSE){
  3.     exit(print_r($db->errorInfo(), true));
  4. }
3. Мелкий - 10 Января, 2017 - 08:51:07 - перейти к сообщению
Le0_Nard пишет:
Удивительно, почему не выдавалась ошибка...

http://php.net/manual/en/pdo.error-handling.php
Видимо, у вас отключен вывод ошибок PDO. Переключите в единственный адекватный PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION

Le0_Nard пишет:
а не дату 'YmdHis', которую нужно парсить

А нафига её парсить? Где-то дёрнуть date_format сразу в запросе, где-то: (new \Datetime($datefromdb))->format('...');
4. Le0_Nard - 22 Января, 2017 - 01:45:06 - перейти к сообщению
Мелкий пишет:
Le0_Nard пишет:
а не дату 'YmdHis', которую нужно парсить

А нафига её парсить? Где-то дёрнуть date_format сразу в запросе, где-то: (new \Datetime($datefromdb))->format('...');

Пока для меня это самый простой способ работы с датой. Можно быстро делать всякие
CODE (PHP):
скопировать код в буфер обмена
  1. $db->exec('DELETE FROM `on_confirmation` WHERE `till`<'.time());

И не только. Например, я работаю с часовыми поясами пользователей. И так намного проще: беру время, прибавляю часовой пояс (таймштамп. Отрицательный или положительный), и после этого загоняю в dsteparser (DateTime с плюшками). И это, в моем виденьи, самый короткий путь.
Единственный минус: хранить нужно в bigint, ибо время в int "закончится" где-то в 2038 году.

 

Powered by ExBB FM 1.0 RC1