如何使用 mysqli API 制作完全动态的准备语句?

2024-04-02

我需要更改此查询以使用准备好的语句。是否可以?

查询:

$sql = "SELECT id, title, content, priority, date, delivery FROM tasks " . $op . " " . $title . " " . $content . " " . $priority . " " . $date . " " . $delivery . " ORDER BY " . $orderField . " " . $order . " " . $pagination . "";

在查询之前,有代码检查 POST 变量并更改查询中变量的内容。

//For $op makes an INNER JOIN with or without IN clause depending on the content of a $_POST variable
$op = "INNER JOIN ... WHERE opID  IN ('"$.opID."')";
//Or
$op = "INNER JOIN ... ";

//For $title (depends of $op):
$title = "WHERE title LIKE'%".$_POST["title"]."%'";
//Or
$title = "AND title LIKE'%".$_POST["title"]."%'";

//For $content:
$content = "AND content LIKE '%".$_POST["content"]."%'";

//For $priority just a switch:
$priority = "AND priority = DEPENDING_CASE";

//For $date and $delivery another switch 
$d = date("Y-m-d", strtotime($_POST["date"]));
$date = "AND date >= '$d' 00:00:00 AND date <= '$d' 23:59:59";
//Or $date = "AND date >= '$d' 00:00:00";
//Or $date = "AND date <= '$d' 23:59:59";

//For $orderField
$orderField = $_POST["column"];

//For $order
$order= $_POST["order"];

//For $pagination 
$pagination = "LIMIT ".$offset.",". $recordsPerPage;

我如何使用准备好的语句来执行此查询?

  • 查询可以更加静态,但这意味着要制作不同的准备好的语句并根据 $_POST 检查来执行它。
  • 它取决于许多变量,因为此查询在包含搜索字段和要排序的列的表中显示结果。

查询的完整示例如下(取决于 $_POST 检查):

SELECT id, title, content, priority, date, delivery FROM tasks INNER JOIN op ON task.op = op.opId WHERE op IN (4851,8965,78562) AND title LIKE '%PHT%' AND content LIKE '%%' AND priority = '2' ORDER BY date DESC LIMIT 0, 10 

这是一个很好的问题。感谢您转向准备好的发言。看来经过这么多年的奋斗,这个想法终于开始占据主导地位。

免责声明:将会有指向我自己网站的链接,因为我已经帮助人们使用 PHP 20 多年了,并且痴迷于撰写有关最常见问题的文章。

是的,这是完全可能的。看看我的文章,如何为 mysqli 创建搜索过滤器 https://phpdelusions.net/mysqli_examples/search_filter对于功能齐全的示例。

For the WHERE部分,您所需要做的就是创建两个单独的数组 - 一个包含带有占位符的查询条件,另一个包含这些占位符的实际值,即:

WHERE clause

$conditions = [];
$parameters = [];

if (!empty($_POST["content"])) {
    $conditions[] = 'content LIKE ?';
    $parameters[] = '%'.$_POST['content ']."%";
}

等等,适用于所有搜索条件。

那么你可以implode所有条件使用AND以绳为胶,获得一流WHERE clause:

if ($conditions)
{
    $where .= " WHERE ".implode(" AND ", $conditions);
}

所有搜索条件的例程都是相同的,但对于IN()条款。

IN() clause

有点不同,因为您需要添加更多占位符和更多值:

if (!empty($_POST["opID"])) {
    $in  = str_repeat('?,', count($array) - 1) . '?';
    $conditions[] = "opID IN ($in)";
    $parameters = array_merge($parameters, $_POST["opID"]);
}

这段代码将添加尽可能多的?占位符到IN()子句中的多个元素$_POST["opID"]并将所有这些值添加到$parameters大批。可以在我网站同一部分的相邻文章中找到相关解释。

完成后WHERE子句,您可以移至查询的其余部分

ORDER BY clause

您不能参数化 order by 子句,因为字段名称和 SQL 关键字不能用占位符表示。为了解决这个问题,我请求你使用白名单功能 https://phpdelusions.net/pdo_examples/order_by我正是为了这个目的而写的。有了它,您可以使您的 ORDER BY 子句 100% 安全但非常灵活。您所需要的只是预定义一个数组,其中包含 order by 子句中允许的字段名称:

$sortColumns = ["title","content","priority"]; // add your own

然后使用这个方便的函数获取安全值:

$orderField = white_list($_POST["column"], $sortColumns, "Invalid column name");
$order = white_list($_POST["order"], ["ASC","DESC"], "Invalid ORDER BY direction");

这是一个智能功能,涵盖了三种不同的场景

  • 如果未提供任何值(即 $_POST["column"] 为空),将使用白名单中的第一个值,因此它作为默认值
  • 如果提供了正确的值,它将在查询中使用
  • 如果提供的值不正确,则会抛出错误。

LIMIT clause

LIMIT值已完美参数化,因此您只需将它们添加到$parameters array:

$limit = "LIMIT ?, ?";
$parameters[] = $offset;
$parameters[] = $recordsPerPage;

最后组装

最后,你的查询将是这样的

$sql = "SELECT id, title, content, priority, date, delivery 
        FROM tasks INNER JOIN ... $where ORDER BY `$orderField` $order $limit"; 

并且可以使用下面的代码来执行

$stmt = $mysqli->prepare($sql);
$stmt->bind_param(str_repeat("s", count($parameters)), ...$parameters);
$stmt->execute();
$data = $stmt->get_result()->fetch_all(MYSQLI_ASSOC);

where $data是一个常规数组,包含查询返回的所有行。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 mysqli API 制作完全动态的准备语句? 的相关文章

  • Doctrine DQL 从 join 返回平面数组

    我通过 DQL 中的常规 LEFT JOIN 选择 3 个实体 它们通过连接表关联 连接表还定义了实体以及带注释的关系 查询执行没有问题 但我的结果作为平面数组返回 我期望一个包含三个实体作为每个索引的数组元素的数组 SELECT e1 e
  • PHP 正则表达式匹配字符串的最后一次出现

    我的字符串是 text1 A373R12345 我想找到该字符串最后出现的非数字数字 所以我使用这个正则表达式 0 9 然后我得到这个结果 1 A373 2 12345 但我的预期结果是 1 A373R 它有 R 2 12345 另一个例子
  • file_get_contents 大文件上传

    我正在尝试使用 fsockopen 上传 2GB 以上的大文件 但 file get content 出现以下错误 我无法在内存中存储大文件 我需要分块发送数据 但不知道如何执行此操作 请问有人可以指导我吗 致命错误 允许的内存大小 134
  • 自定义帖子类型的 WordPress 自定义字段

    过去有几个人出现过这个问题 但他们的问题的解决方案对我来说不起作用 我已经尝试了很多 在 WordPress 中 我创建了 3 种自定义帖子类型 1 代表 视频 新闻 和 音乐 每个内容都发布到自己的页面 我想添加自定义字段 这样我就可以为
  • 在 Laravel 中的编辑表单上获取选定选项

    我的网站订单有一个可编辑的表单 并且有以下字段 User quantity note status 我在此表单中还有其他选项 但只有这些字段对我来说很重要 以便能够获取默认值 例如 我希望能够查看用户默认订购的数量 然后我可以更改它或保留它
  • Laravel - 急切加载 Eloquent 模型的方法(而不是关系)

    就像我们可以急切加载 Eloquent 模型的关系一样 有没有办法急切加载不是 Eloquent 模型的关系方法的方法 例如 我有一个 Eloquent 模型GradeReport它有以下方法 public function totalSc
  • Zend Framework 中的动态默认模块

    有谁知道在 Zend Framework 中动态设置默认模块并且不会遇到命名空间问题的方法 例如 我想要做的是有一个允许加载的模块表 其中一个设置为默认模块 例如 我可能有 admin blog calendar 作为可以加载的模块 如果我
  • div 中的文本字符有限,添加“阅读更多”链接并在单击链接时显示所有字符

    我有一个 div 里面有文本 使用 PHP 和 MySQL 显示 结构如下 div class description p Here is a lot of text p div 我想在 p 标签内的文本超过 100 个字符时显示 阅读更多
  • Ajax文件上传

    我想使用 Ajax 和 php 上传文件 我有一个表格
  • 如何从脚本中创建新的 Joomla 用户帐户?

    我们正在为 Joomla 创建一个 XML API 允许合作伙伴网站在我们的网站上为其用户创建新帐户 我们已经创建了一个独立的 PHP 脚本来处理和验证 API 请求 但现在我们需要实际创建新帐户 我们最初只想进行 CURL 调用来提交注册
  • 将IP保存到数据库中

    当用户登录时 我想将他们的 IP 保存在数据库中 我该怎么做呢 MySQL 字段最适合使用哪种类型 获取IP的PHP代码是什么样的 我正在考虑将其用作登录 会话内容的额外安全功能 我正在考虑使用用户现在拥有的 IP 检查用户从数据库登录的
  • PHP-docker容器中的环境变量

    我想在我的 docker 容器中显示一个环境变量 PHP 脚本如下所示 我使用 OpenShift 来启动容器 PHP 容器显示 env is 现在我更改容器的 dc 配置 oc env dc envar USER Pieter deplo
  • Composer 无法获取 github

    今天 我尝试通过运行来安装 Laravelcomposer create project laravel laravel 5 1 myproject prefer dist我收到此错误 Could not fetch https api g
  • 如何使用 jQuery Ajax 将 PHP 数组值传递到另一个文件?

    这是我的代码
  • Paypal 将钱从一个帐户转移到另一个帐户

    我知道这个建议如何汇款至任何 PayPal 账户 https stackoverflow com questions 1559808 paypal api send money to any paypal account但到目前为止我所尝试
  • 在 PHP 中接受带有小数点和千位分隔符的国际数字

    对于用户可以输入能量值来计算相应费用的在线计算器 我需要 PHP 脚本来接受各种用户输入 200 万又四分之一焦耳 的值可以输入为 2000000 25 默认表示法 2 000 000 25 带千位分隔符 2000000 25 逗号作为小数
  • 设置大型电子邮件通知系统有哪些方法?

    我的公司有一个用 PHP 构建的网站 我们使用内置的 PHP 电子邮件功能每天向订阅者发送数千封电子邮件 这是一个糟糕的主意 它堵塞了我们的服务器 并且需要几个小时才能完成整个批次 现在我已经研究过像 MailChimp 这样的群发邮件服务
  • PHP 共享标头而不使用服务器端脚本?

    到目前为止我总是通过 PHP 解决简单的问题 您有一个包含页眉 菜单 页脚和内容字段的网站 每个页面的页眉 菜单和页脚通常是相同的 在没有 PHP 或任何其他服务器端语言的情况下 如何使页眉 菜单和页脚数据仅存在于一个文件中 例如 您不会有
  • if/else 简写来定义变量

    我很难理解 if else 的 php 简写是如何描述的here https stackoverflow com questions 20233207 php if shorthand and echo in one line possib
  • 我可以让 swagger-php 在查询字符串上使用数组吗?

    我使用 Swagger php 当我定义查询字符串上的参数时 它可以是一个数组 但据我所知 它不支持这种查询字符串 https api domain tld v1 objects q 1 q 5 q 12 我相信这会被设定in the co

随机推荐