Подтвердить что ты не робот

Mysqli_multi_query не работает надежно с запросами условного комментария mysql

У меня возникла проблема с запросами условного комментария mysql, где сообщаются ошибки без синтаксической ошибки. Он работает в том случае, если по крайней мере один из запросов выполняется с условным.

Я использую php 5.6.24 и mysql 5.5.52-cll

Пример 1 (Успех):

<?php
$conn = mysqli_connect("127.0.0.1", "aaatex_phppos", "phppos", "aaatex_phppos2");

$test1 = "
/*!40000 REPLACE INTO `phppos_app_config` (`key`, `value`) VALUES ('supports_full_text', '0') */;
/*!50604 REPLACE INTO `phppos_app_config` (`key`, `value`) VALUES ('supports_full_text', '1') */;";

mysqli_multi_query($conn,$test1);
print_r(mysqli_error_list($conn));
?>
Значение

supports_full_text равно 0, как ожидалось.

Пример 2 (Отказ):

<?php
$conn = mysqli_connect("127.0.0.1", "aaatex_phppos", "phppos", "aaatex_phppos2");

$test2 = "
/*!50604 REPLACE INTO `phppos_app_config` (`key`, `value`) VALUES ('test', '0') */;
/*!50604 REPLACE INTO `phppos_app_config` (`key`, `value`) VALUES ('test', '1') */;";

mysqli_multi_query($conn,$test2);
print_r(mysqli_error_list($conn));

Полученные ошибки:

Array
(
    [0] => Array
        (
            [errno] => 1064
            [sqlstate] => 42000
            [error] => You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ';
    /*!50604 REPLACE INTO `phppos_app_config` (`key`, `value`) VALUES ('test', '1' at line 1
        )

)

Пример 3 (Отказ, но выглядит как успех (см. ниже сообщение):

<?php
$conn = mysqli_connect("127.0.0.1", "aaatex_phppos", "phppos", "aaatex_phppos2");

$test3 = "
/*!40000 REPLACE INTO `phppos_app_config` (`key`, `value`) VALUES ('test', '0') */;
/*!50604 REPLACE INTO `phppos_app_config` (`key`, `value`) VALUES ('test', '0') */;
/*!50604 REPLACE INTO `phppos_app_config` (`key`, `value`) VALUES ('test', '1') */;";

mysqli_multi_query($conn,$test3);
print_r(mysqli_error_list($conn));

Значение теста равно 0. Как и ожидалось.

Является ли это ошибкой в ​​php или чем-то, что я делаю неправильно?

EDIT:

ПРИМЕЧАНИЕ. Я обнаружил, что когда запрос не выполняется, STOPS обрабатывает остальную часть файла. Таким образом, пример 3 все еще имеет ошибки во 2-м и 3-м запросах; Я просто не поймал все ошибки. Выполняется запрос 40000; но все, что НЕ запускается для текущей версии mysql, терпит неудачу как синтаксическая ошибка.

4b9b3361

Ответ 1

У вас есть недоразумение здесь. Ваша версия mysql 5.5.52. Это означает, что результаты, которые вы получаете, верны.

Когда вы скажете /*!40000 ... */ в своем запросе, вы говорите, что этот запрос должен выполняться только в версиях mysql выше 4.0.0. Аналогично, /*!50604 ... */ означает, что версия mysql должна быть выше, чем 5.6.04, чтобы этот запрос выполнялся. Помните, что эти цифры относятся к версии mysql. Не для версии php.

В первом тесте ваш первый запрос выполняется отлично, так как ваша версия mysql больше 4.0.0. Но второй запрос пропущен, так как ваша версия mysql ниже 5.6.04. Это то, что происходит и в двух других тестах.

Но я не могу объяснить, почему вы получаете синтаксические ошибки, например,

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ';
    /*!50604 REPLACE INTO `phppos_app_config` (`key`, `value`) VALUES ('test', '1' at line 1

во втором тесте. Может быть, запрос, который вы здесь задаете, - это не фактический запрос, который вы выполнили. Вы можете это проверить? Поскольку я также делал все эти тесты (у меня есть mysql 5.5, а также php 5.6), я не обнаружил никаких ошибок. Я только видел, что запросы с более высокими требованиями к версии не выполняются.

Для дополнительного чтения см. в этой статье. Надеюсь, мой ответ вам помог.

Обновление

Посмотрев на другие ответы, похоже, вы столкнулись с редкой ошибкой. Попробуйте обновить версию mysql. Если проблема все еще сохраняется, это может быть ошибка с API mysql.

Ответ 2

Да, похоже, что это ошибка в multi_query(). Кажется, эта функция не любит неуместную точку с запятой.

$mysqli->multi_query(";SELECT 1;");

даст вам ту же синтаксическую ошибку. Также как и запрос SELECT 1;;SELECT 2;.

Что делает любой условный комментарий, оцененный как false, выдает дополнительную точку с запятой, что приводит к синтаксической ошибке.

Update.
Похоже, что это не mysqli, а mysql API очень разборчивы по точкам с запятой: эта проблема может быть воспроизведена и в PDO. Похоже, я напишу ошибку на трекер mysql.

Ответ 3

Multi-statement - опасный инструмент; избегайте этого.

В любом случае, вам это действительно нужно? Вы можете сделать несколько строк в одном выражении:

REPLACE INTO `phppos_app_config` (`key`, `value`)
     VALUES
         ('test', '0'),
         ('test', '1')

BTW, REPLACE - старая команда; INSERT ... ON DUPLICATE KEY UPDATE ... в основном заменил его. Подумайте об этом.

Или, может быть, вы можете просто использовать INSERT IGNORE ....

Пожалуйста, объясните свою цель использования /*!50604 ... */. Он в основном существует, чтобы дать некоторую форму обратной совместимости в инструментах; он редко используется в производственной среде.