Параметраризированные запросы в PHP и возврат массива из результата

zerkms

TDD infected
Команда форума
Для нас не делай ничего.
Просто задача подготовленных выражений (параметризированных запросов) при любых входных данных результатом выдать валидный и безопасный запрос. А у тебя к входным данным уже предъявляются довольно жёсткие требования.
 

Fortop

Новичок
Просто задача подготовленных выражений (параметризированных запросов) при любых входных данных результатом выдать валидный и безопасный запрос
Омг. Откуда это взято? :D
А варенье они (параметризированные запросы) варить не должны?
 

Fortop

Новичок
цитатку бы? вот про это
zerkms
при любых входных данных результатом выдать валидный и безопасный запрос
и про варенье тоже можете поискать :D с таким же успехом.
 

zerkms

TDD infected
Команда форума
Fortop
если я ошибаюсь - расскажи тогда, о какой безопасности написано по ссылкам.

а заодно - как, следуя твоей идеологии, можно использовать http://ru2.php.net/manual/en/pdostatement.bindparam.php
зачем здесь третий аргумент, если всё так просто, как ты говоришь - или "а мужики-то не знают"?
что подставлять третьим аргументом? или интерфейс метода неправильный?
 

Fortop

Новичок
zerkms
Т.е. цитатки не будет? :) И все было взято
из здравого смысла
?
Вам нравится воевать с ветряными мельницами? :) Выдумали себе сложности и героически их преодолеваете.

Во-первых, третий параметр - необязательный.
Fortop
в большинстве случаев я бы не геморроился, и откавычивал все
Но это неважно.

Во-вторых, кроме самого запроса остальным(в том числе и нижележащим слоям абстракции) должно быть сугубо фиолетово какой и где у него тип. Дальше сами догадаетесь?

Я где-то уже это приводил...
PHP:
$allowed = array('input_name' => 'condition ?');

$params = array_intersect_key($_POST, $allowed);
$conditions = array_intersect_key($allowed, $params);

$sql = 'query' . implode(' AND ', $conditions);
Как сюда в $allowed ввести тип ожидаемого параметра подсказать?
И, да, парсить запрос, как Вы предлагали - не надо :D

Но куда нам "сирым и убогим" до Вас :)
 

zerkms

TDD infected
Команда форума
в большинстве случаев я бы не геморроился, и откавычивал все
прощай, производительность. привет, implicit type casting.
Вам нравится воевать с ветряными мельницами? Выдумали себе сложности и героически их преодолеваете.
у меня сложностей нет никаких, поверь :) не нужно за меня что-то додумывать.

Т.е. цитатки не будет?
... to .gain the security benefits of using prepared statements.
Prepared statements can help increase security by separating SQL logic from the data being supplied. This separation of logic and data can help prevent a very common type of vulnerability called an SQL injection attack. Normally when you are dealing with an ad hoc query, you need to be very careful when handling the data that you received from the user. This entails using functions that escape all of the necessary trouble characters, such as the single quote, double quote, and backslash characters. This is unnecessary when dealing with prepared statements
ps: кстати, давай ты впредь не будешь переходить на личности с попытками подковырнуть а-ля "Но куда нам "сирым и убогим"? честно, раздражает. хочешь выглядеть шутом - иди работать в цирк, окей?
 

Fortop

Новичок
Во-первых, нам сирым и убогим, а не Вам.
Поэтому позвольте мне обращаться со своей личностью, как мне того хочется. Ок?

Во вторых, повторюсь в который раз
при любых входных данных результатом выдать валидный и безопасный запрос
?
Да-да, валидации данных у нас может не быть или быть с ошибками, но запросы то у нас пишутся не людьми (ах, да в рассматриваемом же случае они собираются по частям) и 100% валидны благодаря prepared statemets...
Где можно получить мою банку клубничного варенья от них?

А в-третьих, это уже мелочь, но она есть
прощай, производительность. привет, implicit type casting.
Угу, когда кончаются аргументы выплывает производительность и скорость....
От кого же я это слышал? Не напомните? :D

Это при том что и сами Вы видели вариант, как с этим работать и я предлагал варианты :)
И Вас это
Fortop
в большинстве случаев я бы не геморроился, и откавычивал все
тогда не смутило. Хотя в определенных случаях тоже могут быть проблемы :)
 

zerkms

TDD infected
Команда форума
Да-да, валидации данных у нас может не быть или быть с ошибками, но запросы то у нас пишутся не людьми (ах, да в рассматриваемом же случае они собираются по частям) и 100% валидны благодаря prepared statemets...
не надо придираться к словам - если запрос записан верно, то использование препаред стейтментов гарантирует, что при любых данных он таковым и останется: валидным и безопасным. это задача препаредов, это написано по ссылкам.

повторю ещё раз: задача prepared statement'ов - разделить plain text запрос и данные, для того, чтобы при любых данных запрос был корректным и безопасным.

От кого же я это слышал? Не напомните?
один из аргументов. они у меня не кончились.

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

Fortop

Новичок
это у тебя они собираются по частям
Все верно, в приведенном мной примере так и есть.
Т.е. я могу его считать тоже написанным человеком? В равной степени как и в случае, если
zerkms
запрос задан в виде строкового литерала с плейсхолдерами.
Эти два случая эквивалентны? Верно?

Тогда... (где фанфары?)
если запрос записан верно
Приплыли?

zerkms
Доверие к данным, которые должны были быть провалидированными, но на факте валидация была или недостаточная или вообще опущена
А простите чем для абстракции нижнего уровня (о которой писал ТС) является запрос? Не данными?
На всякий случай напомню, PHP не контролирует валидность и корректность синтаксиса SQL запроса.
Ровно такая же ситуация и с prepared statement.

P.S. Прошу прощения, но я завершаю эту дискуссию.
Можно ли в одной функции производить биндинг и выполнение произвольных запросов с произвольными данными? - можно.
Должна ли эта функция заниматься приведением типов, валидацией и т.д. и т.п.? - на мой взгляд не должна (этим надо заниматься в абстракциях уровнем выше)
 

zerkms

TDD infected
Команда форума
На всякий случай напомню, PHP не контролирует валидность и корректность синтаксиса SQL запроса.
Ровно такая же ситуация и с prepared statement.
не надо приплетать пхп вот только сюда. омг, неужели я непонятно изъясняюсь? повторю в третий раз: задача препаредов - при условии корректности исходного запроса с плейсхолдерами обеспечить его корректность и после подстановки любых данных.

Можно ли в одной функции производить биндинг и выполнение произвольных запросов с произвольными данными? - можно.
можно и по улице голым ходить. ради спорта и чтобы доказать правоту во что бы то ни стало - легко. из практических побуждений - нет смысла.

А простите чем для абстракции нижнего уровня (о которой писал ТС) является запрос? Не данными?
не данными. данные это данные. запрос - это запрос (строка с плейсхолдерами).



Должна ли эта функция заниматься приведением типов, валидацией и т.д. и т.п.? - на мой взгляд не должна (этим надо заниматься в абстракциях уровнем выше)
тогда подготовленные выражения не смогут обеспечить должной безопасности. (разве что все параметры под одну гребёнку будут причёсаны под строки)
 

ru-vadik

Новичок
Не понимаю, зачем вы спорите - проверка входных данных и подстановка параметров в запрос, вещи совершенно не связанные :).

Решил продолжить изыскания ради интереса.
Я почему-то решил, что привязывать параметры можно по одному
PHP:
mysqli_bind_param($stmt, "s", $var1);
mysqli_bind_param($stmt, "s", $var2);
но оказалось, что нет :) - надо писать
PHP:
mysqli_bind_param($stmt, "ss", $var1, $var2);
поэтому пришлось воспользоваться ф-цией eval():
PHP:
function dbGetDataTable()
{
	$numargs = func_num_args();
	if($numargs < 1)
	{
		printf("Неверное количество параметров.");
		exit();
	}
	$link = mysqli_connect(dbHost, dbUser, dbPassword, dbBase);
	if (mysqli_connect_errno())
	{
	   printf("Подключение невозможно: %s\n", mysqli_connect_error());
	   exit();
	}

	$query = func_get_arg(0);
	if ($stmt = mysqli_prepare($link, $query))
	{
		if($numargs > 2)
		{
			$execText = "";
			for($i = 2; $i < $numargs - 1; $i++)
			{
				$execText .= "\$param" . $i . "=" . func_get_arg($i) . "; ";
			}
			$execText .= "mysqli_bind_param(\$stmt, \"" . func_get_arg(1). "\", ";
			for($i = 2; $i < $numargs - 1; $i++)
			{
				$execText .= "\$param" . $i;
				if($i != $numargs - 2)
				{
					$execText .= ", ";
				}
			}
			$execText .= ");";
			eval ($execText);
		}
		mysqli_execute($stmt);

		mysqli_stmt_bind_result($stmt, $data);
		while (mysqli_stmt_fetch($stmt))
		{
			...
		}
		mysqli_stmt_close($stmt);
	}
	mysqli_close($link);

       ....
}
При вызове функции с параметрами:
PHP:
$dataTable = dbGetDataTable("SELECT ? FROM Dual UNION SELECT ? FROM Dual", "ds", 123, "abc", 1);
в eval() выполняется строка:
PHP:
$param2=123; $param3=abc; mysqli_bind_param($stmt, "ds", $param2, $param3);
Последний параметр - кол-во возвращаемых столбцов Он понадобится при вызове mysqli_stmt_bind_result() в eval().
Понятно, что подстановку параметров нужно обернуть в try/catch и т.д.

Вот такой велосипед получился. Все-таки параметраризированные запросы в PHP реализованы, в сравнении с .NET и Java, мягко говоря, неудачно .
 

Fortop

Новичок
Не понимаю, зачем вы спорите - проверка входных данных и подстановка параметров в запрос, вещи совершенно не связанные
[...]
(здесь была клевета, удалено zerkms)

Я почему-то решил, что привязывать параметры можно по одному

mysqli_bind_param($stmt,_"s",_$var1);
mysqli_bind_param($stmt,_"s",_$var2);
Пффф. Так ведь можно таки, правда в [m]PDO[/m] :)

А вместо eval можно использовать [m]call_user_func_array[/m]
 

Fortop

Новичок
zerkms
Я дискуссию с Вами закончил 4мя сообщениями выше. И, прошу прощения, возобновлять ее не собираюсь.
Поэтому, Вас не затруднит самостоятельно найти те 3-4 сообщения, где речь шла о приведении типов, валидации(она же проверка) и еще sanitize'ации(что уж тут подразумевалось, я даже выяснять не буду)?
После чего Вы еще раз будете иметь удовольствие поспорить с моими сообщениями.
 

zerkms

TDD infected
Команда форума
Я дискуссию с Вами закончил 4мя сообщениями выше. И, прошу прощения, возобновлять ее не собираюсь.
Сударь, давайте вы не будете приписывать мне слова, которые я не говорил, ок?

где речь шла о приведении типов, валидации(она же проверка) и еще sanitize'ации(что уж тут подразумевалось, я даже выяснять не буду)?
а вот с этого места поподробнее, в каких сообщениях Я говорил о валидации. А о "sanitize'ации" - если ты не понимаешь смысла термина, то выдумывать его своим больным мозгом не нужно.

Собственно: требую или привести ссылку на те мои слова, которые однозначно можно трактовать как то, что я говорил о валидации данных перед их подстановкой в prepared statement, или удалить из своих сообщений слова, которые несут собой клевету и порочат мой честный ник своей бредовостью.
 

Fortop

Новичок
А о "sanitize'ации" - если ты не понимаешь смысла термина, то выдумывать его своим больным мозгом не нужно
Ваши бы слова, да Вам бы в уши :)

Поскольку я имел уже печальный опыт наблюдать в нескольких топиках плоды Вашего воспаленного сознания, то строить свои догадки о том, что лично Вами подразумевалось под этим термином, я решительно отказываюсь.
Как только Вас не затруднит объяснить каким образом Вы увязали валидацию, "sanitize'ацию" и prepared statements - Вы сразу получите то, что так настойчиво требуете.

А насчет порочат/не порочат - не вертитесь, как уж на сковородке, и не будете порочить свой ник. Я тут причем?

P.S. Есть у меня смутные подозрения, что Вы банально путаете и смешиваете такие вещи как - валидацию, фильтрацию и приведение типов. Но я уж пожалуй, дождусь официальных объяснений :D а то меня опять обвинят в клевете :D
 

zerkms

TDD infected
Команда форума
Fortop
Как только Вас не затруднит объяснить каким образом Вы увязали валидацию, "sanitize'ацию" и prepared statements
я не увязывал валидацию - это твои слова, которые ты опять приписываешь мне. (это я говорил уже раза 3)

тем, что приписываешь мне слова, которых я не говорил. (это я повторяю во второй раз)

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

достаточно официально?

ps: так я дождусь или нет ссылку на мои слова, что метод должен как-то организовывать валидацию (она же - проверка)?

pps: для тех кто в танке, повторю то, что я уже говорил в топике минимум раза 3:
данные в prepared statement'ах валидировать не нужно - их нужно явно приводить к тому типу, в котором они хранятся в субд.
 

Fortop

Новичок
Значит так.
На хромой блохе с того берега моря, которое зайцу не перелететь, орлу не перебежать, хоть море не море, а так лужа посреди города...

А тем смотрим на мои руки - вот они.

Вам зачем-то надо заниматься приведением типов.
Fortop
zerkms
которые нужно приводить к какому-то конкретному типу: float, int
Делать валидацию на этапе формы? не?
Я предложил делать валидацию.
zerkms
Fortop
Делать валидацию на этапе формы? не?
итого логика sanitize'ации запроса разбивается на 2 части ))
Вы отлично приняли его как замену, посчитали частью своей "saniteze'ации", которую ну никак не хотели разбивать на две части. И которая крайне нужна для Вас в контексте обсуждаемых в топике prepared statements

Дальше больше (успеваете следить за моими руками?)
zerkms
Fortop
Да хоть на 15ть.

Кавычки в запросе и mysql_real_escape_string не имеет никакого отношения к валидации. А валидация достаточно часто нужна и без записи в БД.
Доверие к данным, которые должны были быть провалидированными, но на факте валидация была или недостаточная или вообще опущена, что в итоге приведёт к добавлению в запрос данных as-is, не заключая в кавычки и не применяя специальных функций - в итоге может привести сами знаете к чему
А теперь у нас оказывается что если мы не сделаем валидацию или ее не будет, то данные ВНЕЗАПНО окажутся не закавычены и не обработаны, например, mysql_real_escape_string или теми же prepared statements

Я спросил - не подскажете ли, каким образом Вы связали валидацию и обработку данных?
А Вы ответили
zerkms
я не увязывал валидацию
Врем?

Как итог - имеем
Fortop
Есть у меня смутные подозрения, что Вы банально путаете и смешиваете такие вещи как - валидацию, фильтрацию и приведение типов.
Поэтому я бы и рад что-нибудь опровергнуть, да Ваши собственные слова мне не позволяют этого.
 

zerkms

TDD infected
Команда форума
Вы отлично приняли его как замену, посчитали частью своей "saniteze'ации", которую ну никак не хотели разбивать на две части. И которая крайне нужна для Вас в контексте обсуждаемых в топике prepared statements
неправильно. это не замена.
sanitize - процесс "обезопасивания" данных, подставляемых в запрос. валидация - процесс проверки, что данные уже удовлетворяют некоторым критериям.
т.е. валидация может быть частью sanitize - как ты предложил, НО согласно моей идее (и вообще общепринятой работе с препаредами) sanitize содержит только явное приведение типов.

нет, не врём. я валидацию не предлагал. я лишь в одном месте согласился, что в твоём варианте она может быть частью sanitize.

так или иначе - я от топика отписываюсь. свой троллинг можешь считать успешным.
 
Сверху