当前位置:

首页 > 编程开发 > DevExtreme过滤器转MySQL WHERE子句PHP教程

DevExtreme过滤器转MySQL WHERE子句PHP教程

本文旨在提供一套PHP解决方案,将DevExtreme等前端框架生成的类NoSQL过滤数组结构动态转换为标准的MySQLWHERE子句。教程将详细介绍如何使用PDO和MySQLi两种方式构建安全的SQL查询,包括参数化查询的实现和数据转义的最佳实践,以有效防止SQL注入,确保数据库操作的安全性与灵活性。

本文目录

    将DevExtreme过滤器转换为MySQL WHERE子句的PHP教程

    本文旨在提供一套PHP解决方案,将DevExtreme等前端框架生成的类NoSQL过滤数组结构动态转换为标准的MySQL WHERE 子句。教程将详细介绍如何使用PDO和MySQLi两种方式构建安全的SQL查询,包括参数化查询的实现和数据转义的最佳实践,以有效防止SQL注入,确保数据库操作的安全性与灵活性。

    1. 理解问题背景与目标

    在现代Web应用开发中,前端框架如DevExtreme常以结构化的JSON或数组形式定义数据过滤条件,例如:

    {
      "from": "get_data",
      "skip": 0,
      "take": 50,
      "requireTotalCount": true,
      "filter": [["SizeCd","=","UNIT"],"or",["SizeCd","=","JOGO"]]
    }

    其中,filter 字段是一个嵌套数组,它清晰地表达了过滤逻辑:[[字段, 运算符, 值], 逻辑运算符, [字段, 运算符, 值], ...]。我们的目标是将这种格式的过滤条件转换成MySQL数据库能够理解的 WHERE 子句,例如:WHERESizeCd= 'UNIT' ORSizeCd= 'JOGO'。转换过程中,必须确保字段名不带引号,而字符串值需要正确地加引号或作为预处理语句的参数。

    2. 使用PDO实现安全的查询转换

    PDO(PHP Data Objects)是PHP连接数据库的推荐方式,它支持预处理语句,能够有效防止SQL注入攻击。我们将创建两个辅助函数:一个用于构建带有占位符的SQL查询字符串,另一个用于提取参数值。

    假设我们有以下过滤数组:

    $filterArray = [
        ["SizeCd","=","UNIT"],
        "or",
        ["SizeCd","=","JOGO"],
        "or",
        ["SizeCd","=","PACOTE"]
    ];

    2.1 构建带有占位符的SQL查询字符串

    arrayToQuery 函数负责遍历过滤数组,将每个条件转换为 \字段` 运算符 ?` 的形式,并拼接逻辑运算符。

    /**
     * 将过滤数组转换为带有占位符的SQL WHERE子句。
     *
     * @param string $tableName 目标表名。
     * @param array $filterArray DevExtreme风格的过滤数组。
     * @return string 包含占位符的SQL查询字符串。
     */
    function arrayToQuery(string $tableName, array $filterArray) : string
    {
        // 确保表名被反引号包围,以处理特殊字符或保留字
        $select = "SELECT * FROM `{$tableName}` WHERE ";
    
        foreach($filterArray as $item) {
            if(is_array($item)) {
                // 条件数组:[字段, 运算符, 值]
                // 字段名用反引号包围,值用问号占位符
                $select .= "`{$item[0]}` {$item[1]} ?";
            } else {
                // 逻辑运算符:"or", "and"
                $select .= " {$item} ";
            }
        }
    
        return $select;
    }

    2.2 提取查询参数值

    arrayToParams 函数负责从过滤数组中提取所有条件的值,这些值将用于PDO的参数绑定。

    /**
     * 从过滤数组中提取所有条件的值。
     *
     * @param array $filterArray DevExtreme风格的过滤数组。
     * @return array 包含所有参数值的数组。
     */
    function arrayToParams(array $filterArray) : array
    {
        $params = [];
        foreach($filterArray as $item) {
            if(is_array($item)) {
                // 提取条件数组中的第三个元素(即值)
                $params[] = $item[2];
            }
        }
        return $params;
    }

    2.3 PDO查询示例

    结合上述函数,我们可以轻松地执行PDO查询:

    // 示例数据
    $filterArray = [
        ["SizeCd","=","UNIT"],
        "or",
        ["SizeCd","=","JOGO"],
        "or",
        ["SizeCd","=","PACOTE"]
    ];
    
    // 假设您已建立PDO连接
    // $dsn = 'mysql:host=localhost;dbname=your_database';
    // $username = 'your_username';
    // $password = 'your_password';
    // try {
    //     $conn = new PDO($dsn, $username, $password);
    //     $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    // } catch (PDOException $e) {
    //     die("数据库连接失败: " . $e->getMessage());
    // }
    // 替换为您的实际PDO连接对象
    $conn = null; // 占位符,请替换为您的实际PDO连接
    
    $tableName = "your_table_name"; // 替换为您的实际表名
    
    // 生成SQL查询字符串和参数数组
    $sql = arrayToQuery($tableName, $filterArray);
    $params = arrayToParams($filterArray);
    
    echo "生成的SQL查询: " . $sql . "\n";
    echo "绑定的参数: " . print_r($params, true) . "\n";
    
    // 实际执行查询
    if ($conn) {
        try {
            $stmt = $conn->prepare($sql);
            $stmt->execute($params);
            $results = $stmt->fetchAll(PDO::FETCH_ASSOC);
            echo "查询结果:\n";
            print_r($results);
        } catch (PDOException $e) {
            echo "查询执行失败: " . $e->getMessage();
        }
    } else {
        echo "请提供有效的PDO连接对象。\n";
    }

    输出示例 (不含实际查询结果):

    生成的SQL查询: SELECT * FROM `your_table_name` WHERE `SizeCd` = ? or `SizeCd` = ? or `SizeCd` = ?
    绑定的参数: Array
    (
        [0] => UNIT
        [1] => JOGO
        [2] => PACOTE
    )

    注意事项:

    • 使用PDO预处理语句和参数绑定是防止SQL注入的最佳实践。
    • 字段名使用反引号 (`) 包裹,可以避免与MySQL保留字冲突。
    • 表名也应使用反引号包裹。

    3. 使用MySQLi实现查询转换(带转义)

    对于使用MySQLi扩展的用户,也可以实现类似的转换。然而,如果不是使用MySQLi的预处理语句,而是直接拼接字符串,则必须手动对值进行转义以防止SQL注入。

    3.1 构建SQL查询字符串(带转义)

    arrayToQueryMysqli 函数在构建SQL字符串时,直接将值通过 mysqli->real_escape_string() 进行转义,并用单引号 ' 包裹。

    /**
     * 将过滤数组转换为MySQLi风格的SQL WHERE子句,并对值进行转义。
     *
     * @param mysqli $mysqli MySQLi连接对象。
     * @param string $tableName 目标表名。
     * @param array $filterArray DevExtreme风格的过滤数组。
     * @return string 完整的SQL查询字符串。
     */
    function arrayToQueryMysqli($mysqli, string $tableName, array $filterArray) : string
    {
        // 确保表名被反引号包围
        $select = "SELECT * FROM `{$tableName}` WHERE ";
        foreach($filterArray as $item) {
            if(is_array($item)) {
                // 条件数组:[字段, 运算符, 值]
                // 字段名用反引号包围,值通过 real_escape_string 转义后用单引号包围
                $escapedValue = $mysqli->real_escape_string($item[2]);
                $select .= "`{$item[0]}` {$item[1]} '{$escapedValue}'";
            } else {
                // 逻辑运算符
                $select .= " {$item} ";
            }
        }
        return $select;
    }

    3.2 MySQLi查询示例

    // 示例数据
    $filterArray = [
        ["SizeCd","=","UNIT"],
        "or",
        ["SizeCd","=","JOGO"],
        "or",
        ["SizeCd","=","PACOTE"]
    ];
    
    // 替换为您的实际MySQLi连接设置
    // $mysqli = new mysqli("localhost", "your_username", "your_password", "your_database");
    // if ($mysqli->connect_errno) {
    //     die("MySQLi 连接失败: " . $mysqli->connect_error);
    // }
    $mysqli = null; // 占位符,请替换为您的实际MySQLi连接
    
    $tableName = "tablename"; // 替换为您的实际表名
    
    // 生成SQL查询字符串
    if ($mysqli) {
        $query = arrayToQueryMysqli($mysqli, $tableName, $filterArray);
        echo "生成的SQL查询: " . $query . "\n";
    
        // 执行查询
        $result = $mysqli->query($query);
    
        if ($result) {
            echo "查询成功,获取到 " . $result->num_rows . " 条记录。\n";
            // 示例:打印第一行数据
            // if ($row = $result->fetch_assoc()) {
            //     print_r($row);
            // }
            $result->free(); // 释放结果集
        } else {
            echo "查询失败: " . $mysqli->error . "\n";
        }
        $mysqli->close(); // 关闭连接
    } else {
        echo "请提供有效的MySQLi连接对象。\n";
    }

    输出示例 (不含实际查询结果):

    生成的SQL查询: SELECT * FROM `tablename` WHERE `SizeCd` = 'UNIT' or `SizeCd` = 'JOGO' or `SizeCd` = 'PACOTE'

    注意事项:

    • 尽管 mysqli->real_escape_string() 可以防止大部分SQL注入,但强烈推荐使用MySQLi的预处理语句 (prepare/bind_param) 来处理参数,因为它比手动转义更安全、更不易出错。
    • 本示例中的 arrayToQueryMysqli 函数直接将转义后的值拼接到SQL字符串中,这不如预处理语句灵活和安全。在实际生产环境中,如果使用MySQLi,应优先考虑其预处理语句功能。

    4. 总结与最佳实践

    本文详细介绍了如何将DevExtreme等前端框架生成的过滤数组转换为MySQL的 WHERE 子句。

    • PDO是首选:使用PDO的预处理语句和参数绑定是构建动态SQL查询的最安全、最推荐的方式,它能有效防止SQL注入。
    • MySQLi的替代方案:如果必须使用MySQLi且不使用其预处理语句,务必使用 mysqli->real_escape_string() 对所有外部输入的值进行转义。但最佳实践仍然是使用MySQLi的预处理语句。
    • 字段与表名处理:始终使用反引号 (`) 包裹字段名和表名,以避免与SQL保留字冲突,并提高代码的健壮性。
    • 灵活性与扩展性:当前的解决方案处理了简单的 AND/OR 逻辑和基本操作符。对于更复杂的嵌套条件(例如 (A AND B) OR C)或更多操作符(LIKE, IN, BETWEEN 等),可能需要更复杂的递归解析逻辑。

    通过这些方法,您可以安全高效地将前端的过滤逻辑无缝集成到后端数据库查询中,提升应用的交互性和数据处理能力。

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发
    相关文章 更多
    GitHub合并故障的已缓解、监控与已解决有什么不同
    GitHub合并故障的已缓解、监控与已解决有什么不同

    GitHub合并故障中的“已缓解并监控”和“已解决”不能互换。前者表示影响已经采取措施缓解,仍在观察稳定性;后者是供应商正式结束这场事故的状态。11月13日的Pull Requests合并超时事件先进入监控,随后于北京时间11月14日02:29标记为已解决。

    llama.cpp v1.0.0的网页聊天分组与Markdown编辑适合哪些场景
    llama.cpp v1.0.0的网页聊天分组与Markdown编辑适合哪些场景

    llama.cpp v1.0.0改善聊天组织、长消息编辑和附件预览;界面变化与底层API迁移、缓存及访问边界需要分别理解。

    Postman 12.36.4 更新后仍报错,怎么判断是哪一层的问题
    Postman 12.36.4 更新后仍报错,怎么判断是哪一层的问题

    Postman 12.36.4 更新后仍有异常时,可按应用、API请求和平台服务区分问题范围,避免把补丁版本当作故障原因。

    n8n 2.47.6、2.48.3 Beta与1.123.96适合哪些部署环境?
    n8n 2.47.6、2.48.3 Beta与1.123.96适合哪些部署环境?

    按正式、预发布和1.x维护渠道对应补丁,再结合Redis、Agent端点和Pinecone索引判断适用范围。

    Codex CLI 0.169.0与0.171.0-alpha.2怎样选择,终端工作区适合哪些任务
    Codex CLI 0.169.0与0.171.0-alpha.2怎样选择,终端工作区适合哪些任务

    Codex CLI 0.169.0提供有明确说明的终端工作区能力;0.171.0-alpha.2为预发布,当前没有功能清单,选用时应分开评估。

    llama.cpp b12345的Hexagon后端支持哪些Q5量化格式?
    llama.cpp b12345的Hexagon后端支持哪些Q5量化格式?

    llama.cpp b12345的预发布构建为Hexagon HTP后端增加Q5_0和Q5_1支持。选择模型时需要核对完整量化名称及实际运行后端,不能只看到“Q5”就视为同一种格式。

    llama.cpp b12344的MCP工具调用在断连或超时后会怎样处理?
    llama.cpp b12344的MCP工具调用在断连或超时后会怎样处理?

    llama.cpp b12344的预发布构建调整了MCP工具调用的取消行为:客户端断连或调用超时时,服务器会向MCP服务发送带请求ID的取消通知。使用服务端工具的Web界面也属于这项变更范围。

    GitHub Actions与Checks同时排队失败时,如何区分平台故障?
    GitHub Actions与Checks同时排队失败时,如何区分平台故障?

    GitHub对11月5日Actions与Checks事件的新增复盘指出:数据库服务在高并发大读请求下耗尽资源,导致部分运行无法排队或执行失败。检查类似问题时,先比对平台事件时间与失败状态,再决定是否重试自己的工作流。

    GitHub Actions运行卡住占用并发时,应检查哪些状态?
    GitHub Actions运行卡住占用并发时,应检查哪些状态?

    GitHub对11月9日Actions事件的新增复盘说明:数据库迁移后,新区域容量与速率限制不足导致请求被拒,部分运行在服务恢复后仍占用并发。排查自己的工作流时,应把平台状态、运行状态与应用代码错误分开核对。

    llama.cpp b12342的CUDA量化计算适用于哪些GPU,如何构建?
    llama.cpp b12342的CUDA量化计算适用于哪些GPU,如何构建?

    llama.cpp b12342新增面向少列矩阵计算的CUDA量化内核,覆盖2至24个src1列等场景,例如推测解码的验证阶段。新增内核针对Ampere及更新的NVIDIA GPU,并限定于发行说明列出的量化类型;它不是所有硬件与模型都会得到相同收益的通用开关。

    查看更多
    精品专题 更多
    装机必备
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows
    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程
    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    Mac软件 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    Aperty macOS版
    Aperty macOS版
    macOS

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    WINDOWS 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    PixTV 网页版
    PixTV 网页版
    Windows

    PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。