За последние 24 часа нас посетили 18503 программиста и 1612 роботов. Сейчас ищет 1891 программист ...

проблемка с bindParam

Тема в разделе "Прочие вопросы по PHP", создана пользователем xfreewindx, 8 апр 2012.

  1. xfreewindx

    xfreewindx Активный пользователь

    С нами с:
    22 фев 2012
    Сообщения:
    55
    Симпатии:
    0
    Здравствуйте!

    Есть функция, делающая update базы данных
    Код (Text):
    1. public function update($query, $args) {
    2.         $pdo = $this->dbConnect();
    3.  
    4.         $stmt = $pdo->prepare($query);
    5.         foreach ($args as $key => $value)
    6.             $stmt->bindParam($key, $value);
    7.  
    8.         return $stmt->execute();
    9.     }
    функция получает следующие параметры
    Код (Text):
    1. $query = "UPDATE `articles` SET `title` = :title, `content` = :content WHERE `id_article` = :id_article";
    Код (Text):
    1. $args = array(':title' => $title, ':content' => $content, ':id_article' => $id_article)
    Вобщем вызов идет так:
    Код (Text):
    1. $result = $this->dbDriver->update($query, array(':title' => $title, ':content' => $content, ':id_article' => $id_article));
    2.         if ($result)
    3.             return true;
    4.         else
    5.             return false;
    Проблема в том, что bindParam, помещенный внутри foreach отрабатывает без ошибок, но неправильно. Вместо :title и :content подставляется $id_article, то есть вместо заголовка и текста статьи вижу айдишник. Если сделать втупую:
    Код (Text):
    1. public function update($query, $args) {
    2.         $pdo = $this->dbConnect();
    3.  
    4.         $stmt = $pdo->prepare($query);
    5.         /*foreach ($args as $key => $value) {
    6.             $stmt->bindParam($key, $value);
    7.         }*/
    8.         $stmt->bindParam(':id_article', $args[':id_article']);
    9.         $stmt->bindParam(':title', $args[':title']);
    10.         $stmt->bindParam(':content', $args[':content']);
    11.  
    12.         return $stmt->execute();
    13.     }
    , то все работает прекрасно. Где ошибка?
     
  2. sobachnik

    sobachnik Старожил

    С нами с:
    20 апр 2007
    Сообщения:
    3.380
    Симпатии:
    13
    Адрес:
    Дмитров, МО
    Код (PHP):
    1. foreach($args as $key => &$value) 
     
  3. xfreewindx

    xfreewindx Активный пользователь

    С нами с:
    22 фев 2012
    Сообщения:
    55
    Симпатии:
    0
    Спасибо, пробовал так уже, но не работает. Видимо дело в другом.
     
  4. sobachnik

    sobachnik Старожил

    С нами с:
    20 апр 2007
    Сообщения:
    3.380
    Симпатии:
    13
    Адрес:
    Дмитров, МО
    Странно...
    Сделал такое у себя - у меня работает.
     
  5. xfreewindx

    xfreewindx Активный пользователь

    С нами с:
    22 фев 2012
    Сообщения:
    55
    Симпатии:
    0
    странно, я пробовал и на 5.2 и на 5.3, у меня не отрабатывает, казалось бы такая простая конструкция. Причем работает одинаково, что так $value, что так &$value. На мой взгляд что здесь передавать по ссылке? $value и так содержит значение массива. Но все равно спасибо.
     
  6. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.116
    Симпатии:
    1.244
    Адрес:
    там-сям
    на взгляд авторов PDO биндится переменная, а не значение. значит правильным синтаксисом будет
    Код (Text):
    1. foreach($args as $key => &$value)
    это и в мануале есть. проверь себя еще раз. может не сохранив текст в редакторе протестировал или типа того
     
  7. xfreewindx

    xfreewindx Активный пользователь

    С нами с:
    22 фев 2012
    Сообщения:
    55
    Симпатии:
    0
    Точно! Не по значению!
    Все получилось. Спасибо, мужики!

    Еще у меня вопрос остался: обязательно ли с точки зрения безопасности указывать третий параметр, типа PDO::pARAM_INT или PDO::pARAM_STR?
    bindParam(':title', $title, PDO::pARAM_STR)
     
  8. Your

    Your Старожил

    С нами с:
    2 июл 2011
    Сообщения:
    4.074
    Симпатии:
    7
    Желательно!
     
  9. xfreewindx

    xfreewindx Активный пользователь

    С нами с:
    22 фев 2012
    Сообщения:
    55
    Симпатии:
    0
    Спасибо!
     
  10. shRED

    shRED Новичок

    С нами с:
    18 мар 2017
    Сообщения:
    7
    Симпатии:
    0
    PHP:
    1.     public static function getLastId($value) {      
    2.         $db = Db::getConnection();
    3.         $sql = 'SELECT * FROM :table ORDER BY id DESC LIMIT 1';
    4.         $result = $db->prepare($sql);
    5.         $result->bindParam(':table', $value, PDO::PARAM_STR); // не работает не пойму почему
    6.         return $result->execute();
    7.     }
    Народ! Подскажите, что не так? Почему не отрабатывает?
     
  11. mahmuzar

    mahmuzar Старожил

    С нами с:
    6 апр 2012
    Сообщения:
    4.631
    Симпатии:
    425
    Адрес:
    РД, г. Махачкала.
    @shRED, execute() не вернет результат, читай документацию по PDO
     
  12. shRED

    shRED Новичок

    С нами с:
    18 мар 2017
    Сообщения:
    7
    Симпатии:
    0
    А более развернутого ответа я не достоин? ;)

    PHP:
    1. public static function getLastId() {    
    2.         $db = Db::getConnection();
    3.         $sql = 'SELECT * FROM post ORDER BY id DESC LIMIT 1';
    4.         $result = $db->prepare($sql);
    5.         return $result->execute();
    6.     }
    Почему тогда это возвращает результат?

    PS: Прошу лесом не отправлять, а доходчиво объяснить глупцу. Реально смотрю в мануал и ни чего не понимаю.
     
  13. mahmuzar

    mahmuzar Старожил

    С нами с:
    6 апр 2012
    Сообщения:
    4.631
    Симпатии:
    425
    Адрес:
    РД, г. Махачкала.
    Результат вернут все методы которые начинаются с fetch
    --- Добавлено ---
    А что он тебе возвращает? Дай скажу TRUE or FALSE
    --- Добавлено ---
    вижу метод называется getLastId. Получение идентификатора последней вставленной записи уже реализован в PDO http://php.net/manual/ru/pdo.lastinsertid
     
    shRED нравится это.
  14. shRED

    shRED Новичок

    С нами с:
    18 мар 2017
    Сообщения:
    7
    Симпатии:
    0
    За fetch благодарю, не знал :)

    Про этот метод я знаю, не подходит он мне, т.к. индификатор нужно узнать в другой сессии. (или я опять что-то путаю).

    Но все-же как так?
    PHP:
    1. public static function getLastId() {
    2.         $db = Db::getConnection();
    3.         $sql = 'SELECT * FROM post ORDER BY id DESC LIMIT 1';
    4.         $result = $db->prepare($sql);
    5.         $result->execute();
    6.         return $result->fetchColumn();
    7.     }
    это работает

    PHP:
    1.     public static function getLastId($value) {
    2.      
    3.         $db = Db::getConnection();
    4.         $sql = 'SELECT * FROM :table ORDER BY id DESC LIMIT 1';
    5.         $result = $db->prepare($sql);
    6.         $result->bindParam(':table', $value, PDO::PARAM_STR);
    7.         $result->execute();
    8.         return $result->fetchColumn();
    9.      
    10.     }
    а это нет!
     
  15. mahmuzar

    mahmuzar Старожил

    С нами с:
    6 апр 2012
    Сообщения:
    4.631
    Симпатии:
    425
    Адрес:
    РД, г. Махачкала.
    Имена столбцов, таблиц не могут быть заменены так. В общем, тебе придется прибегнуть к обычной конкатенации, или же жестко прописать в сам запрос имя таблицы, У меня ни разу не было потребности, чтобы менять имя таблицы, ибо для каждой таблицы свой класс.
     
    shRED нравится это.
  16. shRED

    shRED Новичок

    С нами с:
    18 мар 2017
    Сообщения:
    7
    Симпатии:
    0
    :) Ок, спасибо. Я уже смерился. Просто этот код используется в нескольких местах и с разными таблицами, поэтому хотел вынести в отдельный метод.
     
  17. shRED

    shRED Новичок

    С нами с:
    18 мар 2017
    Сообщения:
    7
    Симпатии:
    0
    PHP:
    1.     /**
    2.      * Возвращает id будущей записи
    3.      * @return <p>id будущей записи</p>
    4.      */
    5.     public static function getNextId($value) {
    6.         if (isset($value) && (strlen($value) > 0)) {
    7.             $db = Db::getConnection();
    8.             $sql = 'SELECT * FROM ' . $value . ' ORDER BY id DESC LIMIT 1';
    9.             $result = $db->prepare($sql);
    10.             $result->execute();
    11.             return $result->fetchColumn() + 1;
    12.         } else {
    13.             return 0;
    14.         }
    15.     }
    Переработал метод, вдруг кому интересно будет.
     
  18. mahmuzar

    mahmuzar Старожил

    С нами с:
    6 апр 2012
    Сообщения:
    4.631
    Симпатии:
    425
    Адрес:
    РД, г. Махачкала.
    вместо
    PHP:
    1. if (isset($value) && (strlen($value) > 0)) {
    Можно
    PHP:
    1. if (!empty($value)) {
    Относительно док-блока, сразу после @return должен идти тип переменной далее описание
    т.е. @return int ид следующей записи. Программист то разберется что ты имел в виду и какой тип вернет метод взглянув на ее реализацию, но если ты в будущем планируешь генерировать документацию на основе этих док-блоков, то у тебя получится не то, что требуется.

    Документация по phpDocumentator

    Мне интересно, зачем знать id будущей записи?
     
  19. shRED

    shRED Новичок

    С нами с:
    18 мар 2017
    Сообщения:
    7
    Симпатии:
    0
    :) Спасибо.

    При определенных условия, необходимо создать директорию с определенным именем для нового поста. (При этом пост еще не записан в базу) Решил привязать к id поста.
     
  20. mahmuzar

    mahmuzar Старожил

    С нами с:
    6 апр 2012
    Сообщения:
    4.631
    Симпатии:
    425
    Адрес:
    РД, г. Махачкала.
    @shRED, я думаю ты сможешь обойтись встроенным функционалом.
     
  21. shRED

    shRED Новичок

    С нами с:
    18 мар 2017
    Сообщения:
    7
    Симпатии:
    0
    @mahmuzar, Возможно, спорить не буду, но это всё на что хватило мозгов. Php для меня пока дремучий лес, многое не знаю.