Когда использовать подготовленные выражения в PDO?

Печать RSS
496

L
Автор
Землянин
0
Вот решил проект переписать с использованием PDO и возник вопрос озвученный в названии темы.
К примеру, есть у меня класс в котором есть метод get_value(), его можно описать используя подготовленные выражения, вот так:
function get_value($value) {
        if ($this->id == 0)
            return 'error';
        else {
            global $db;
            try {
                
                $smtp = $db->prepare("SELECT '".$value."' FROM `user` WHERE `id`=:id");
                $smtp->bindParam(':id', $this->id, PDO::PARAM_STR);
                $smtp->execute();
                $a = $smtp->fetch(PDO::FETCH_ASSOC);
                return $a[$value];
            } catch (PDOException $e) {
                msg('error', $e->getMessage());
            }
        }
    }

Или вот так:
function get_value($value) {
        if ($this->id == 0)
            return 'error';
        else {
            global $db;
            try {
                $smtp = $db->query("SELECT '".$value."' FROM `user` WHERE `id`='".$this->id."'");
                $a = $smtp->fetch(PDO::FETCH_ASSOC);
                return $a[$value];
            } catch (PDOException $e) {
                msg('error', $e->getMessage());
            }
        }
    }

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

Пришелец
0
Во втором примере у тебя нет prepareStatement() выражений. конечно первый лучше. Подготовленные выражения используются как замена mysql_real . .. итд. И там в твом случае обработка должна стоять PARAM_INT
L
Автор
Землянин
0
Stanislav-WEB, ну например в этом методе по большому счету не нужна фильтрация, id приходит в конструктор из $_SESSION['id'] при создании объекта, на который юзер не имеет влияния, оно приходит из базы при авторизации, то есть подменить его нельзя.

Чатланин
0
1. lekt, по поводу прибавки скорости...
тут немного о другом.
например
foreach($arr as $val)
{
$db->query('UPDATE `user` SET `time`='.time().' WHERE `id`="'.$val.'"');
}
1000 юзеров - 1000 запросов. Не есть гуд.
вот тут придет на помощь подготовленый шаблон
$template = prepare('UPDATE `user` SET `time`='.time().' WHERE `id`=:id');
foreach($arr as $val)
{
                $template->bindParam(':id', $val, PDO::PARAM_INT); 
                $template->execute(); 
}
Изменил: Александр (22.09.2013 / 17:34)
A

Пришелец
0
Всегда используй. Хуже не будет.
L
Автор
Землянин
0
4. rastoman, то есть в данном методе можно спокойно обойтись и без подготовленных выражений ?
M

Пацак
0
lekt (22 Сентября 2013 / 13:42)
4. rastoman, то есть в данном методе можно спокойно обойтись и без подготовленных выражений ?
Абсолютно согласен.
Если запрос используется однократно и параметром является число (INT), то подготовленные выражения не нужны.

Пришелец
0
Применяй тогда фильтрацию там где она нужна - на входе. Это тоже можно ускорить  SET `time`='.time().' . Не стоит использовать функции в запросе, встроенный sql кэш не работает с NOW(). php rand() итп . . . Все то что динамически меняет свое поведение. Лучше будет вынести в обычную переменную
L
Автор
Землянин
0
Появилась проблемка, не имеет отношения непосредственно к вопросу темы, но задам тут ибо тоже связано с pdo
есть такой код:
$id = text::num($_GET['id']);
try{
    $query = $db->query("SELECT * FROM `Server` WHERE `id`='".$id."'");
    if ($query->fetchColumn() !== 0){
        $x = $query->fetch(PDO::FETCH_ASSOC);
        include_once '' . $x['type'] . '_server.php';
    }else {
        msg('error', 'Сервер недоступен');
    }
}catch (PDOException $e){
    msg('error', $e->getMessage());
}
и вот почему-то массив $x пустой

а если например написать так:
$id = text::num($_GET['id']);
try{
    $query = $db->query("SELECT * FROM `Server` WHERE `id`='".$id."'");
    $x = $query->fetch(PDO::FETCH_ASSOC);
    include_once '' . $x['type'] . '_server.php';
    
}catch (PDOException $e){
    msg('error', $e->getMessage());
}

все норм.

даже если написать так:
$id = text::num($_GET['id']);
try{
    $query = $db->query("SELECT * FROM `Server` WHERE `id`='".$id."'");
    $count = $query->fetchColumn;
    $x = $query->fetch(PDO::FETCH_ASSOC);
    include_once '' . $x['type'] . '_server.php';
    
}catch (PDOException $e){
    msg('error', $e->getMessage());
}

массив тоже пуст.

никаких ошибок при этом нет, кроме
Warning: include_once(_server.php) [function.include-once]: failed to open stream: No such file or directory
из-за пустого массива.
Кто-то знает в чем дело?

Чатланин
0
fetchColumn() или fetchColumn(0).
!== 0 это не правильно в данной ситуации. Нужно !=

Добавлено через 05:01 сек.
так же если тебе нужен только type, зачем вызывать всю таблицу?
$query = $db->query("SELECT `type` FROM `Server` WHERE `id`='".$id."'"); 
    if ($type=$query->fetchColumn(0) && file_exists($type . '_server.php')){ 
        include_once $type . '_server.php';
Изменил: Александр (22.09.2013 / 23:09)
Стикеры / Теги / Правила / Топ тем / Топ постов / Поиск