Вывод данных из MySQL

Фанат

oncle terrible
Команда форума
блин, какой жуткий легаси этот mysqli_stmt::bind_param()
написано, что параметры он принимает по ссылке, но в примере передача константы
Гриша, эта константа какая надо константа!
прочти уже один раз документацию на эту функцию :)
Первый параметр - это не сами данные, а их типы. Близко к тому что я говнякал в safemysql.

И причина по которой оно существует - это то что mysqli традиционно является тонюсенькой прослойкой между пхп и сишным апи :)
То есть все вопросы - к мускули си апи
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
блин, охренеть не встать константа

решение проблемы ссылок, в принципе, в 1 строку
PHP:
$stmt = mysqli_prepare("INSERT INTO `table` (name,city,age) VALUES (?,?,?)";
$bind_value = fn(...$v)=>$stmt->bind_param(...$v);
$bind_value('ssi',$name,$city,$age)
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Никита догоняет джаву, Дима ускоряет jit, а тут маской в строковой константе кодируются типы данных при передаче по ссылке. Эх ... возьмите уже какую-нибудь вменяемую либу для работы с базой.
 

max74max

Новичок
Получается addslashes() тоже можно не использовать, если в БД данные добавляются с помощью подготовленных запросов?
 

max74max

Новичок
И еще вопрос. Нашел такую информацию в одной статье про подготовленные запросы

В подготовленные запросы нельзя подставлять названия столбцов и таблиц.

PHP:
// Так делать нельзя
$stmt = $pdo->prepare('SELECT ? FROM ?);

Могли бы вы объяснить почему?
Получается вместо ? они явным образом должны быть прописаны так?

PHP:
$stmt = $pdo->prepare('SELECT ? FROM `table`);
 

max74max

Новичок
И еще подскажите, пожалуйста, как из данного запроса для UPDATE
PHP:
$result = $mysqli->query("UPDATE `razdely` SET name= '$name', city= '$city', strana= '$strana' WHERE `id` = '".$id_razdel."' && `id_creatora` = '".$baza_id."'");
сделать подготовленное выражение.
Вот так я делаю для INSERT
PHP:
$stmt = $mysqli->prepare("INSERT INTO `razdely` (name,city,strana) VALUES (?,?,?)");
$stmt->bind_param("sss", $name,$city,$strana);
$stmt->execute();
 

Фанат

oncle terrible
Команда форума
Могли бы вы объяснить почему?
Хороший вопрос.
Дело в том что подготовленные запросы выполняют две функции - защиту от инъекций и еще небольшое ускорение если мы выполняем несколько одинаковых вопросов подряд. Но это ускорение работает только если параметры использовать только для данных. И вот ради этого параметры для имен полей не сделали.

Так что да, надо вручную.
Код:
$allowedValues = ["name, price"];
if(!in_array($column, $allowedValues)){
    throw new \Exception("Unknown columns name");
}
$stmt = $pdo->prepare('SELECT `$column` FROM `table`);
 

max74max

Новичок
Получается я не экранирую кавычки и получаю данные в базу "как есть" в необработанном виде. Например: "Д'артаньян";
Вывожу из базы тоже через подготовленный запрос SELECT
А как тогда мне их обрабатывать чтобы какой-нибудь javascript не выполнился вместо вывода текста?
В головку приходит только htmlentities(), этого будет достаточно?
 

max74max

Новичок
Кстати в bind_param столкнулся с тем, что нельзя сделать так
PHP:
$stmt->bind_param("sss", $name,$city,1);
пришлось делать так

PHP:
$strana = "1";
$stmt->bind_param("sss", $name,$city,$strana);
 

max74max

Новичок
какого текста? вывода куда?
Ок, спрошу по другому.
Можно ли в таблице MySQL хранить текстовые данные с не закомментированными кавычками, например "Д'артаньян", а не \"Д\'артаньян\"
Ведь если я использую подготовленные запросы, тогда mysqli_escape_string уже не нужна? Так получается?
Получается, что я храню в БД данные "как есть", без экранирования, а их обработкой занимаюсь на выводе из БД?
 

max74max

Новичок
с чего ты взял, что в БД лежит \"Д\'артаньян\"?
Там может лежать что угодно. Это пользовательские данные. То что передается пользователем через <textarea> в таблицу text с кодировкой utf8_general_ci
Передается без без фильтрации, но через подготовленный запрос.
 

max74max

Новичок
Получается что экранирование никаких лишних данных не добавляет, оно нужно чтоб отличать некоторые специальные символы (например ' как ограничитель строки) от этого же символа, но как части строки.
А не сломается ли тогда подготовленный запрос через bind_param, если в части строки будет символ ' именно как ччасть троки, а не ограничитель. Ведь mysqli_escape_string я уже не использую?

Метя просто смутил тот момент, что CMS DLE Engine хранит в БД текст с кавычками (как частью строки) ставя перед ними \ Получается \ был добавлен не через mysqli_escape_string, а через addslashes() Тогда получается в таблице данные нужно хранить именно с addslashes(), чтобы разделять где часть строки, а где ограничитель в коде.

Во такое мини-рассуждение у меня получилось. Поправьте, пожалуйста, где я не прав.
 

AnrDaemon

Продвинутый новичок
Получается что экранирование никаких лишних данных не добавляет, оно нужно чтоб отличать некоторые специальные символы (например ' как ограничитель строки) от этого же символа, но как части строки.
А не сломается ли тогда подготовленный запрос через bind_param, если в части строки будет символ ' именно как ччасть троки, а не ограничитель. Ведь mysqli_escape_string я уже не использую?
Экранирование необходимо, чтобы различать данные и команды. Оно имеет смысл ТОЛЬКО когда ты передаёшь (именно передаёшь, не хранишь!!) данные и команды одним потоком.
В случае подготовленных запросов данные НИКОГДА не передаются одновременно с командами.
Ещё раз, читать https://phpdelusions.net/pdo#why

Метя просто смутил тот момент, что CMS DLE Engine хранит в БД текст с кавычками (как частью строки) ставя перед ними \ Получается \ был добавлен не через mysqli_escape_string, а через addslashes() Тогда получается в таблице данные нужно хранить именно с addslashes(), чтобы разделять где часть строки, а где ограничитель в коде.
Вопросы к CMS, не к нам.
 

Фанат

oncle terrible
Команда форума
Метя просто смутил тот момент, что CMS DLE Engine хранит в БД текст с кавычками (как частью строки) ставя перед ними \ Получается \
правильно смутил. Если это действительно так, то значит CMS DLE писали криворукие дебилы, которые не понимают как работать с БД. Не будь как они.

Ведь если я использую подготовленные запросы, тогда mysqli_escape_string уже не нужна? Так получается?
Так.
Получается, что я храню в БД данные "как есть", без экранирования, а их обработкой занимаюсь на выводе из БД?
повторю свой вопрос ещё раз:
Какой обработкой?
Любая обработка данных, полученных из БД, вообще никакого отношения к БД не имеет.
То есть полученные именно из БД данные никак специально обрабатывать не надо.
Если эти данные потом где-то используются так, что их перед использованием надо обрабатывать, то надо обрабатывать независимо от того, пришли они из бд или откуда ещё. Но это уже не будет иметь отношения к тому что данные были получены из БД.

У тебя какая-то в голове дурацкая идея про то что обработка данных для БД как-то связана с другими обработками. Это не так.
Если данные были как-то обработаны для БД, это не делает их автоматически обработанными для дальнейшего использования. Это вообще никак не связанные вещи.

Во общем читай тут https://ru.stackoverflow.com/a/423434/179379
 

max74max

Новичок
правильно смутил. Если это действительно так, то значит CMS DLE писали криворукие дебилы, которые не понимают как работать с БД. Не будь как они.
С вашей помощью, не буду :)

Спасибо, с подготовленными выражениями и как они работают, я разобрался.
Объясню что я имею в виду, когда говорю что нужно обработать данные, видимо я неправильно выразился.

Например, в таблице храниться такая запись varchar или text
"У Д'Артаньяна > яблок чем у Арамиса"

Допустим, по как каким-то причинам, нужно данную запись вывести в пользовательскую часть и отобразить на кнопки

Тогда я вывожу запись через $stmt = $mysqli->prepare("SELECT * FROM ************* и т.д.

заношу в переменную $text_button

и вывожу на сайте в

<input type="submit" value="<?= $text_button; ?>">

Что тогда произойдет? html разметка сломается?
Как это исправить? И достаточно ли будет только htmlentities() ?
 
Сверху