如何在Joomla 3的查询中使用准备语句/绑定值


How to use prepare statements / bind values in a query in Joomla 3?

我想知道如何在where子句中绑定值。我明白这是出于安全原因必须做的事情。

$db = JFactory::getDbo();
$query = $db->getQuery(true);
$query
    ->select("*")
    ->from($db->quoteName("food"))
    ->where("taste = :taste")
    ->bind(':taste', 'sweet');
$db->setQuery($query);
$rows = $db->loadAssocList();

我得到这个错误:

你的SQL语法有错误;查看手册对应于MySQL服务器版本,以便使用正确的语法SQL=SELECT * FROM food WHERE taste =:taste

我的代码是基于这篇文章。它说,在Joomla 3.1只有"PDO/Sqlite和PDO/Oracle支持准备语句",我使用的是Joomla 3.2.1和MySQL,在我的Joomla配置MySQLi。这可能是问题所在吗?

我很困惑,因为我不知道什么API/类必须遵循。

  • JDatabase for Joomlax 没有绑定方法,而且信息很少,好像没有完成。
  • JDatabase for Joomla 2.5有更多信息,但显然不是我的版本。没有bind方法。
  • jdatabasquerery for Joomlax没有绑定方法
  • JDatabaseQuerySqlite for Joomlax 绑定方法
  • JDatabaseQueryPdo for Joomlax没有绑定方法
  • JTable for Joomlax 绑定方法

甚至我开始怀疑我是否必须使用JFactory::getDbo()来选择/插入/更新/删除Joomla数据库中的数据。

据我所知,您不能使用预处理语句,也不能与Joomla绑定值。

如果你阅读Joomla文档(http://docs.joomla.org/Secure_coding_guidelines#Constructing_SQL_queries)中的安全编码指南,他们没有讨论准备好的语句,只讨论使用类型转换或引用来避免SQL注入。

在Joomla中,通常有来自JTable的check(), bind(), store()三重,以防止注入。

JDatabaseQueryPreparable有一个bind方法,你可能想看看。您可能还想查看JDatabaseQueryLimitable的docblock。

我建议的一件事是,当你得到这个错误时,通常是因为你在查询中确实有问题(通常是错误的引用或空的东西,不需要为空)。要查看生成的查询,可以使用

echo $query->dump();

,然后尝试直接在sql中运行。

一般来说,使用$db->quote()$db->quoteName()是明智的,如果你使用API,你不会遇到引用问题。我认为你可能有引号问题,但如果不知道字段名,很难知道

在Joomla4中,可以使用bind()方法将数据绑定到命名参数。这是多年来一直要求的,最终它来到了CMS。

  • Joomla Docs的早期参考:https://docs.joomla.org/J4.x:Moving_Joomla_To_Prepared_Statements
  • 正确的Joomla文档:https://docs.joomla.org/J4.x:Selecting_data_using_JDatabase
  • 这里有一个很好的教程:https://www.techfry.com/joomla/prepared-statements-in-joomla-4

语法与post

中的代码段所预言的完全一致
$taste = "sweet";
$db = JFactory::getDbo();
$query = $db->getQuery(true)
    ->select("*")
    ->from($db->quoteName("food"))
    ->where($db->quoteName("taste") . " = :taste")
    ->bind(":taste", $taste);
$db->setQuery($query);
$rows = $db->loadAssocList();