Здравствуйте! Простите, если не сюда пишу. Только изучаю php в универе. Код может быть скорее всего оптимизирован, но мне бы сперва работоспособности добиться. Пытаюсь сделать подготовленные запросы. PHP: <?php mysqli_report(MYSQLI_REPORT_ALL); try { require_once 'connfig.php'; mysqli_set_charset($db, "utf8"); /*$query=$_GET['query']; $array = [ '?' => '$query' ];*/ /*$sql = "SELECT * FROM tovar WHERE content = ?";*/ $query = $_POST['query']; $array = array( '?' => $query, '?' => 'info' ); /* Создаём подготовленное утверждение */ $stmt = mysqli_stmt_init($db); $sql = mysqli_stmt_prepare($stmt, "SELECT * FROM tovar WHERE content = ?"); /* Связываем переменные с метками */ mysqli_stmt_bind_param($stmt, "s", $sql); /* Выполняем запрос */ mysqli_stmt_execute($array); /* Связываем переменные результата */ mysqli_stmt_bind_result($sql, $array); /* Получаем значение */ mysqli_stmt_fetch($sql); printf(" находится в районе %s\n", $query); } catch (Exception $e) { echo $e->getMessage(); } ?> Пишу простой поиск по базе. Пользователь забивает уникальный ID из 12 знаков и получает информацию из столбцов info, content и date_created. Подскажите, пожалуйста, как это реализовать? А то у меня сейчас выводится только тот код, что пользователь забил в поисковую форму. Очень хочу разобраться. Буду благодарен советам.
Прочитайте внимательно, у вас бред нарисован сивой кобылы. https://www.php.net/mysqli_stmt_execute. Там есть такой пример, как у вас.
Переписал: PHP: mysqli_report(MYSQLI_REPORT_ALL); try { require_once 'connfig.php'; mysqli_set_charset($db, "utf8"); /* Подготавливаем утверждение на вставку строк */ $stmt = mysqli_prepare($db, 'SELECT * FROM tovar WHERE content = ?'); mysqli_stmt_bind_param($stmt, "s", $tovar); /* Выполняем утверждение */ mysqli_stmt_execute($stmt, ['info', 'content', 'date_created']); /* Получаем все строки из myCity */ while ($row = mysqli_fetch_assoc($result)) { printf("%s (%s)\n", $row["info"], $row["content"], $row["date_created"]); } } catch (Exception $e) { echo $e->getMessage(); } Подскажите, пожалуйста, где ошибся
1) mysqli:: prepare 2) mysqli_stmt::bind_param 3) mysqli_stmt::execute 4) mysqli_stmt::get_result 5) mysqli_result::fetch_assoc в цикле stmt_init, mysqli_stmt:: prepare, mysqli_stmt::fetch используются значительно реже. --- Добавлено --- P.S. После get_result уже можно закрывать подготовленный запрос. Вся выборка хранится в объекте result. --- Добавлено --- P.P.S. Для поиска «уникального ID» можно просто профильтровать и/или проэкранировать введенное значение с последующим обычным query --- Добавлено --- В MySQLi исключения используются для отладки. Для обычных целей вы сами должны генерировать исключения (на основе возвращаемых методами значений).
PHP: mysqli_report(MYSQLI_REPORT_ALL); try { require_once 'connfig.php'; mysqli_set_charset($db, "utf8"); $stmt = mysqli_prepare($db, 'SELECT * FROM tovar WHERE content = ?'); mysqli_stmt_bind_param($stmt, "s", $tovar); mysqli_stmt_execute($stmt, ['info', 'content', 'date_created']); $result = mysqli_stmt_get_result($stmt); while ($row = mysqli_fetch_assoc($result)) { printf("%s (%s)\n", $row["info"], $row["content"], $row["date_created"]); } } catch (Exception $e) { echo $e->getMessage(); } Поправьте, пожалуйста
Да, параметр $array – это ультра новая фишка. У функции mysqli_stmt_execute первый обязательный параметр – вообще НЕ массив Читайте нормально доки, включая примеры, как вам выше писали.
Надо 3.0 использовать ) А если пытаться понять примеры, а не копировать их? Никак? Вообще всё вместе, и бинд, и передача массива.... И параметры, которые нафиг не нужны в запросе, тоже заодно... --- Добавлено --- И это при том, что дока на русском языке, если что
Да, тяжко, когда бэкграунд никакой. Можно почитать статейку на сайте доков мускула, чтобы лучше понимать суть подготовленных выражений. execute принимает значения для «входного» параметра запроса (это то, что подставляется на место «?»). Причем не обязательно это значение передавать прямо в метод execute. Традиционный (и более общий, т.к. можно уточнить тип) для MySQLi способ – использовать bind_param. Да. Вместо bind_param можно использовать прямую передачу значения параметра в execute, о чем я выше написал. Но этот способ не поддерживается в вашей версии пыха. --- Добавлено --- Обратите внимание, что в bind_param, начиная со второго параметра, передаются по сути не значения, а ссылки на переменные (значения можно записать и после вызова этого метода).
Спасибо за советы. Буду изучать. Правильно заметили, бэкграунд никакой у меня. Фронтендом 5 лет занимался. В бэкграунд вообще никак не лез
Можешь перейти на PDO как самый близкий вариант. Это актуальная версия для программирования ? Что по этому поводу Преподаватель говорил ? --- Добавлено --- Документацию читал ? в PHP самая идеальная документация. Откуда переменной $result взяться в 16 строке ?
бэкграунд - это фон... имеется ввиду общие знания.... вы же путаете с бэкендом... серверной частью)))) либо не понимаете даже этого ))))
PHP: <?php include 'connfig.php'; mysqli_set_charset($db, "utf8"); $zapros=$_POST['query']; $query = "SELECT * FROM tovar WHERE content = ?"; $stmt = mysqli_prepare($db, $query); mysqli_stmt_bind_param($stmt, "s", $zapros); mysqli_stmt_execute($stmt); $result = mysqli_stmt_get_result($stmt); mysqli_stmt_close ($result); if (mb_strlen($zapros) < 12) { echo '<p>Слишком короткий поисковый запрос.</p>'; } else if (mb_strlen($zapros) > 12) { echo '<p>Слишком длинный поисковый запрос.</p>'; } while ($row = mysqli_fetch_assoc($result)) { foreach ($row as $r) { $str=$r['info']; $stra=$r['content']; $strm=$r['date_created']; echo "<p>Ваш ID: " . htmlentities($stra, ENT_QUOTES, 'UTF-8') . "</p>"; echo "<p>Изделие: " . htmlentities($str, ENT_QUOTES, 'UTF-8') . "</p>"; echo "<p>Дата производства: " . htmlentities($strm, ENT_QUOTES, 'UTF-8') . "</p>"; } } ?> Но выводимый результат дублируется. Имеется вид: Ваш ID: Изделие: Дата производства: Ваш ID: f Изделие: f Дата производства: f Ваш ID: 2 Изделие: 2 Дата производства: 2 Ваш ID: h Изделие: h Дата производства: h Подскажите, пожалуйста, в чем проблема. Буду благодарен советам.
Продолжаю совершенствовать код. Включаю протоколирование и перехват ошибок: PHP: <?php mysqli_report(MYSQLI_REPORT_ALL); try { include './svaz/conn.php'; mysqli_set_charset($db, "utf8"); $zapros=$_POST['query']; $query = "SELECT * FROM tovar WHERE content = ?"; $stmt = mysqli_prepare($db, $query); mysqli_stmt_bind_param($stmt, "s", $zapros); mysqli_stmt_execute($stmt); $result = mysqli_stmt_get_result($stmt); mysqli_stmt_close ($result); if (mb_strlen($zapros) < 12) { echo '<p>Слишком короткий поисковый запрос.</p>'; } else if (mb_strlen($zapros) > 12) { echo '<p>Слишком длинный поисковый запрос.</p>'; } while ($row = mysqli_fetch_assoc($result)) { $str=$row['info']; $stra=$row['content']; $strm=$row['date_created']; echo "<p>Ваш ID: " . htmlentities($stra, ENT_QUOTES, 'UTF-8') . "</p>"; echo "<p>Изделие: " . htmlentities($str, ENT_QUOTES, 'UTF-8') . "</p>"; echo "<p>Дата производства: " . htmlentities($strm, ENT_QUOTES, 'UTF-8') . "</p>"; } } catch (Exception $e) { echo $e->getMessage(); } ?> В результате появляется сообщение: No index used in query/prepared statement SELECT * FROM tovar WHERE content = ? Если отключить протоколирование, то все работает. Объясните, пожалуйста, что делаю не так. Или это норма? Буду благодарен советам.
У content надо поменять тип на varchar и создать для него индекс. Уникальный индекс, т.к. у вас в поле «уникальные ID». Название тупое у поля. Назовите артикулом и т.п. Если нет требования, чтобы поле с таким именем обязательно было.
Это я про бэкграунд --- Добавлено --- Учите основы построения БД. --- Добавлено --- Mля, ничего не смущает? PHP: $result = mysqli_stmt_get_result($stmt); mysqli_stmt_close ($result); Вывод обычных ошибок (самого пыха) тоже включите.
Разобрался с таблицей с помощью mysql alter table add index. Но почему-то не ищет: PHP: <?php mysqli_report(MYSQLI_REPORT_ALL); try { include 'connfig.php'; mysqli_set_charset($db, "utf8"); $zapros=$_POST['query']; $query = "SELECT * FROM tovar WHERE content = ?"; $stmt = mysqli_prepare($db, $query); mysqli_stmt_bind_param($stmt, "s", $zapros); mysqli_stmt_execute($stmt); $result = mysqli_stmt_get_result($stmt); if (!empty($query) && trim($query) !=''){ if (mb_strlen($zapros) < 12) { echo '<p>Слишком короткий поисковый запрос.</p>'; } else if (mb_strlen($zapros) > 12) { echo '<p>Слишком длинный поисковый запрос.</p>'; } while ($row = mysqli_fetch_assoc($result)) { $str=$row['info']; $stra=$row['content']; $strm=$row['date_created']; echo "<p>Ваш ID: " . htmlentities($stra, ENT_QUOTES, 'UTF-8') . "</p>"; echo "<p>Изделие: " . htmlentities($str, ENT_QUOTES, 'UTF-8') . "</p>"; echo "<p>Дата производства: " . htmlentities($strm, ENT_QUOTES, 'UTF-8') . "</p>"; } } } catch (mysqli_sql_exception $e) { $fd = fopen("./log/log.txt", 'w') or die("не удалось создать файл"); $logir = $e->__toString(); fwrite($fd, $logir); fclose($fd); } mysqli_close($db); ?> Постоянно выводит, что Слишком короткий поисковый запрос. --- Добавлено --- Подскажите, пожалуйста --- Добавлено --- --- Добавлено ---