Farewell наглядным запросам.

yugene

Отошел от дел
Почему бы для наглядности запросов делать не:

$query = "SELECT ... WHERE id='" . my_addslashes($id) . "'";

,а:

$id = my_addslashes($id);
$query = "SELECT ... WHERE id ='$id'";

?

Кстати, так реализовывалось бы и то, о чем Фанат говорил, что не только внешние переменные надо эддслэшить...
 

lovchy

nacido para cifrar
yugene
Потому что это те же плейсхолдеры, только вне функции. Если есть некая последовательность действий, которую можно выполнять как в контексте, так и вне контекста процедуры, она должна выполняться в контексте.
 

yugene

Отошел от дел
Originally posted by lovchy
yugene
Потому что это те же плейсхолдеры, только вне функции. Если есть некая последовательность действий, которую можно выполнять как в контексте, так и вне контекста процедуры, она должна выполняться в контексте.
Я согласен. Только тема топика-то "Привет наглядным запросам" :) Так что если кому нужны наглядные запросы, можно и вне контекста. А так я сторонник выполнения в контексте.
 

CMHungry

Guest
Плейсхолдеры, говорите... Это, вообще-то, не плейсхолдеры, а bind variables.
И на Оракле, например, запросы вида
select * from table where id = ?
в итоге будут выполняться быстрее, так как такие запросы будут храниться в памяти сервера, распарсенные и с построенным планом выполнения. Соответственно, при выполнении подобного запроса он берет готовый план, подставляет нужный параметр и отдает данные.
 

CMHungry

Guest
Yurik, а что это?
Оракл, правда, предпочитает :var вид.

А на постгресе работает такой код:
$passwd = md5($passwd);
$r = $conn -> SelectLimit('select * from users where login=? and password=? and deleted = \'f\'', 1, 0, array('login'=>$login, 'password'=>$passwd));

Причем дальше это разворачивается в постгресовский биндинг:
$sqlarr = explode('?',$sql);
//print_r($sqlarr);
$sql = '';
$i = 1;
foreach($sqlarr as $v) {
$sql .= $v.' $'.$i;
$i++;
}
$s = "PREPARE $plan ($params) AS ".substr($sql,0,strlen($sql)-2);
//adodb_pr($s);
pg_exec($this->_connectionID,$s);
 

Yurik

/dev/null
Это - bindы, но этот топик к ним отношения не имеет

-~{}~ 17.02.05 04:42:

Речь идёт не об использовании фич client api отдельных СУБД а о наглядном написании SQL запросов
 

Sam

Новичок
возвращаясь к теме..

может данные в запрос ставить можно, если они проверены.

например в селекты часто идут айдишники, так почему мне не написать

$this->db->query("SELECT * FROM tablename WHERE id=".$_REQUEST['id'])

если я к этому моменту выполняя метод модели уже проверил что is_numeric($_REQUEST['id'])

или я чего-то не понимаю?
 

Фанат

oncle terrible
Команда форума
можно.
правильно понимаешь.

только, в данном случае, не is_numeric, а что-нибудь гарантирующее, что число именно целое.

причём относится это только к числам.
строки надо обрабатывать в любом случае.
 

Screjet

Новичок
кстати есть ф-ция sprintf, которой в качестве аргументов можно указывать %d - целое число, т.д...
Для постоения SQL'ей очень удобно.
Добавить в эту ф-цию специальный параметр, типа %S для callback'ов, чтобы эскейпить SQL на лету, то ей цены не будет.
 

Screjet

Новичок
Нечто, точно. Только это был бы уже стандартный placeholder, встроенный в пхп. Новички бы изначально знали как избавить свой код от SQL-injection, даже не понимая что это такое.
(все имхо)
 

Wicked

Новичок
может я что-то пропустил, но кто мешает эскейпить все параметры?

делаем функцию sprintf_sql("string", $arg1, $arg2, ...).
внутри нее берем аргументы с #2 и записываем в $args, эскейпим в цикле и внутри вызываем sprintf("string", (array)$args);
 

fixxxer

К.О.
Партнер клуба
>А на постгресе работает такой код:

Недавно появились:
[m]pg_prepare[/m]
[m]pg_execute[/m]
[m]pg_query_params[/m]
Надеюсь, оно все же появится в очередном релизе 4-й ветки. Пока что cvs only
 

ONK

Пассивист PHPСluba
Screjet, идея, которую ты предложил в точности повторяет ту к которой я пришел пол года назад. :)

Небольшая цитата из заготовки к некой документации:

PHP:
 $SQL_pattern = "SELECT IF('test \' test' = '%1$s','YES','NO'),IF('1111' = '%2$d','YES','NO')";

$oResult = $db->safe_query($SQL_pattern,"test ' test","1111'\\");

// SELECT IF('test \' test' = 'test \' test','YES','NO'),IF('1111' = '1111','YES','NO')
//Результат YES YES
Дополнительно объект $db реализует полиморфизм экранирования специальных символов для текущей базы данных.

.....
 

Нечто

Психолог РНРClub
Screjet
Новички бы изначально знали как избавить свой код от SQL-injection, даже не понимая что это такое.
В незнании и есть, имхо, серьезный минус. ДК, кстати, в последней книжке занялся популяризацией плейсхолдеров, так что за адекватных новичков можно не волноваться ;-)
 

docker

Новичок
попытка в очередной раз подвести итоги... ;)
не пинайте сильно: читал все посты, достойно пытался вникнуть в суть проблемы ;)

так какое же лекарство будет наименее болезненным и независимым от настроек хостера...?

Если можем менять настройки php через htaccess, ini_set - то выключаем magic_quotes_gpc, magic_quotes_runtime и просто используем плейсхолдеры: хотя они и делают элементарную работу, которую с теми же addslashes можно более компактно сделать, но основной довод - они предотвращают против лени и забивчивости программиста.

Если не можем менять настройки, то на стадии инициализации приложения в случае успешного get_magic_quotes_gpc() - стрипим get, post, cookie, request массивы, и также уже в процессе работы в случае успешного get_magic_quotes_runtime() стрипим данные поступающие из внешних источников.

И потом в базе просто используем плейсхолдеры.

Как насчет такой схемы?
Причем, поэкспериментировал, и во втором случае - вроде можно даже не учитывать во что уставлен magic_quotes_sybase, т.к. stripslashes просто делает обратное тому, что делается в addslashes, не зависимо от того - экранируются ли обратными слешами(sybase off), либо просто апострофы дублируются(sybase on).
 

SiMM

Новичок
> и также уже в процессе работы в случае успешного get_magic_quotes_runtime() стрипим данные поступающие из внешних источников
Если
PHP:
var_dump(set_magic_quotes_runtime(false))
возвращает false, то нужно обратиться к хостеру, и по результату либо юзать эту функцию, либо бежать от такого хостера без оглядки.

> Как насчет такой схемы?
Вообще-то такая схема напрашивается сама-собой после прочтения FAQ slashes
 

diamond_krnl

pure-php
PHP:
function query_format($format)
  {
    $args = func_get_args();
    $args[0] = '';
    foreach($args as $k=>$v) { $args[$k] = mysql_real_escape_string($v); }
    $args[0] = $format;
    return mysql_query(call_user_func_array('sprintf', $args));
  }
и потом просто счастье
query_format("SELECT * FROM t WHERE id='%d'", $_GET['id']);
 
Сверху