Разношерстные вызовы в mysql

В объекте Model столкнулся с тем, что в одном sql-запросе применялось 2 разных способа "вписывания" переменных в тело запроса:

SELECT * FROM $tableName where id = :id

Прокомментируйте, пожалуйста, почему в одном случае мы используем переменную напрямую - $tableName, а в другом через функцию bindValue - :id;

Пример выше взят из функции getById из этого файла (строка 86): https://github.com/it-for-free/SimpleMVC...

Key Words for FKN + antitotal forum (CS VSU):

vedro-compota's picture

просьба поправить ключевые слова

_____________
матфак вгу и остальная классика =)

Voronve's picture

Поправил (извините, что-то часто начал забывать)

vedro-compota's picture

Не страшно. Просьба также дать ссылку на строку, где запрос выполняется с прямой подстановкой (без привязки параметра).

_____________
матфак вгу и остальная классика =)

vedro-compota's picture

сейчас так:

        $tableName = !empty($tableName) ? $tableName : $this->tableName;
        
        $sql = "SELECT * FROM $tableName where id = :id";      
        $modelClassName = static::class;
        
        $st = $this->pdo->prepare($sql); 
        
        $st->bindValue(":id", $id, \PDO::PARAM_INT);

действительно лучше писать однообразно, если это не пользовательский ввод — то тут проблема только в однообразности, а вот если бы переменная $tableName прилетала от пользователя, то могли бы бы проблемы с безопасностью, по-идее тут лучше переделать аналогично id, только прикручивать параметр как строковый, а не int

_____________
матфак вгу и остальная классика =)

Voronve's picture

У вопроса появилось неожиданное продолжение. В своем файле модели статьи - CMSArticle, в методе getById я попытался заменить вызовы переменной в соответствии с предыдущими постами. Но оказалось, что если заменить вызов $tableName на :tableName и использовать bindValue, в браузере выводится следующая ошибка - "Fatal error: Uncaught PDOException: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''articles' WHERE id = 16' at line 1 in /var/www/FromCMStoMVC/application/models/CMSArticle.php on line 88"

Ссылка на файл в гитхабе:
https://github.com/Voronve/FromCMStoMVC/...

vedro-compota's picture

for the right syntax to use near ''articles' WHERE id = 16' a

распечатайте все переменные, которые, которые вы подставляете в запрос - что там в них.

_____________
матфак вгу и остальная классика =)

vedro-compota's picture

to use near ''articles'

не очень понятно что это за одинарная кавычка, нужна распечатка переменных

_____________
матфак вгу и остальная классика =)

Voronve's picture

Я передаю в метод 2 параметра - названиие таблицы и id статьи. Непосредственно перед загрузкой в sql запрос, значения этих переменных таковы(вывожу при помощи echo): StableName - articles (gettype определяет тип данных как string), Sid - 20 (или другой id статьи) (gettype определяет тип данных как string).
S я поставил вместо знака доллара

vedro-compota's picture

echo): StableName - articles (gettype определяет тип данных как string), Sid - 20 (или другой id статьи) (gettype определяет тип данных как string).

Дайте сюда полную распечатку, print_r() для обих переменных, далее сообщение об ошибки так как оно идёт в браузере, подсветите это как синтаксис.

_____________
матфак вгу и остальная классика =)

Voronve's picture

Результат вызова print_r() для переменных Sid и StableName - 20 articles

Fatal error: Uncaught PDOException: SQLSTATE[42000]: Syntax error 
or access violation: 1064 You have an error in your SQL syntax; 
check the manual that corresponds to your MySQL server version 
for the right syntax to use near ''articles' WHERE id = 20' 
at line 1 in /var/www/FromCMStoMVC/application/models/CMSArticle.php on line 91
PDOException: SQLSTATE[42000]: Syntax error or access violation: 
1064 You have an error in your SQL syntax; check the manual that 
corresponds to your MySQL server version for the right syntax to 
use near ''articles' WHERE id = 20' at line 1 in 
/var/www/FromCMStoMVC/application/models/CMSArticle.php on line 91
Voronve's picture

Подключил логирование запросов вот по этой инструкции http://fkn.ktu10.com/?q=node/9123, чтобы попробовать взглянуть на значения переменных перед запросом, но видимо невыполненные запросы не логируются...

vedro-compota's picture

залоггировать запросы с ошибками вроде бы не очень просто, я так и не доходил до это проще было отладить: http://fkn.ktu10.com/?q=node/10071

_____________
матфак вгу и остальная классика =)

Voronve's picture

Мне кажется я нашел ответ на поставленный самим же собой вопрос - почему имя таблицы передано напрямую а не через bindValue? Нашел следующую заметку:

Please note this:
Won't work:

$sth = $dbh->prepare('SELECT name, colour, calories FROM ?  
WHERE calories < ?');

THIS WORKS!

$sth = $dbh->prepare('SELECT name, colour, calories FROM fruit 
WHERE calories < ?');

The parameter cannot be applied on table names!!

Переводя на наш язык - параметры не могут применяться к именам таблиц! (Поправьте, если я что-то не так понял)
Информация взята отсюда http://us3.php.net/manual/en/book.pdo.ph... (самая первая пользовательская заметка)
А также упоминается другим пользователем здесь http://qaru.site/questions/34714/can-php...

vedro-compota's picture

параметры не могут применяться к именам таблиц

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

Ваше замечание верно.

_____________
матфак вгу и остальная классика =)