如何使用 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 制作完全动态的准备语句? 的相关文章

  • 从数据库填充复选框

    我有两个表 第一个由与名称关联的 id 组成 1 汽车 2 火车 3 普通 ETC 第二个表由两个字段 user id 和第一个表中的 id 组成 例如 1 1 2 1 3 当用户转到该页面时 我试图重新填充选定的复选框 首先 您查询数据库
  • 保存多对多关系,同步/附加不存在?

    我有以下两个多对多关系的模型 use Illuminate Database Eloquent Model class Permission extends Model The database table used by the mode
  • Laravel leftJoin 仅右表的最后一条记录

    我是 Laravel 的新手 我有两张桌子 1 产品 2 价格 products id product int p key name varchar prices id price int p key id product int
  • php 数组中出现意外的 json 输出结构

    我正在尝试转换动态数据 如何从 PHP 获取此 JSON JSON 122240cb 253c 4046 adcd ae81266709a6 item 0 3 这就是我所做的 但它不起作用 PHP json array 122240cb 2
  • 是否可以将路由参数传递给 Laravel 中的控制器构造函数?

    是否可以将路由参数 或路由段 注入到控制器构造函数中 您找到一些代码来澄清我的问题 class TestController protected param public function construct paramFromRoute
  • PHP:读取所有传入 HTTP 请求的类 [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 如何在 GitHub Action 中使用不同版本的 PHP 进行测试

    我有一些 PHP 代码 其中包含使用以下命令运行的测试PHPUnit并想对其进行测试GitHub Actions 我在他们的文档中找不到测试 PHP 包的方法 我想使用不同版本的 PHP 进行测试 但他们只有最新的版本7 3安装 您可以添加
  • 如何在 PHP 的 HTML 页面中显示错误消息?

    我有以下登录表单 login php 其中要求输入用户名和密码
  • PDO PHP 连接,致命错误

    我的连接类 firstcode php class DB functions public db function construct try db new PDO mysql localhost dbname xxx charset ut
  • 在哪里可以获得 PHP 5.3+ 的 runkit DLL 扩展?

    这是一个简单的问题 我在哪里可以获得 PHP 5 3 版本的 runkit 扩展 它的手册 http php net manual en book runkit php http php net manual en book runkit
  • 覆盖 FOS 用户包中的“更改密码”模板

    我做了一些研究 遗憾的是找不到任何帮助 因此 我将 FOSUserBundle ChangePasswordAction 渲染到我的模板中 但它显示供应商提供的默认模板 我的渲染控制器的模板 block body h2 Einstellun
  • 使用值填充的 Symfony2 自定义字段类型

    这是先前问题的后续问题Symfony2 自定义表单类型或扩展 https stackoverflow com questions 24079288 symfony2 custom form type or extension 我正在尝试为订
  • 是否可以用 PHP 编写电子邮件解析器? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • Facebook PHP-SDK 页面刷新后似乎丢失了 userID

    我似乎登录工作正常 我可以登录 接受应用程序 第一次 然后显示用户信息 例如姓名 图片 等 然而 当我刷新页面时 userid 又回到 0 我必须再次登录 我不确定问题是什么 我必须在每次页面加载时重新启动它还是什么 我不知道 我会发布一些
  • 如何在codeigniter中将上传图片比例限制为16:9?

    这是我用来上传图像的代码 this gt load gt library upload ext pathinfo file name PATHINFO EXTENSION img name now ext imgConfig upload
  • 从 Laravel 4 输入生成新数组

    我使用 Input all 从动态生成的表单中获取一些输入 我使用 jQuery 来允许用户添加字段 字段名称为 first names last names 和 emails input 变量现在看起来像这样 array size 4 t
  • php - 解析html页面

    div divbox div p para1 p p para2 p p para3 p table class table tr td td tr table p para4 p p para5 p 有人可以告诉我如何解析这个 html
  • session_start():无法解码会话对象

    我有时在使用 CodeIgniter 时遇到以下问题 错误 2019 03 05 19 57 26 gt 严重性 警告 gt session start 无法解码会话对象 会话已被销毁 system libraries Session Se
  • PHP 表单 - 带验证蜜罐

    我有以下内容 效果很好 但对垃圾邮件机器人开放 我想放入蜜罐 而不是验证码 下面的代码适用于验证姓名 电子邮件 消息 但我无法让它与蜜罐一起工作 任何人都可以查看 蜜罐 代码并告诉我如何修复它吗 我希望表单给出 success2 不允许垃圾
  • PHPUnit - 模拟 S3Client 无法正常工作

    库 aws aws sdk php 2 PHP 版本 PHP 5 4 24 cli 作曲家 json require php gt 5 3 1 aws aws sdk php 2 require dev phpunit phpunit 4

随机推荐