【问题标题】:How to format SQL string from array data through a function如何通过函数从数组数据中格式化 SQL 字符串
【发布时间】:2019-02-16 19:17:35
【问题描述】:

我正在尝试创建一种动态函数,该函数将返回一个格式化字符串,该字符串将被添加到 SQL 查询中。该函数将获取一个数据数组,并根据数据将其格式化为将添加到 SQL 查询中的字符串,该字符串将包括 WHEREORDER BYLIMIT查询。

目前我有一组工作 if 语句,它获取数组中的数据并创建字符串。这是输出:

WHERE status != 2 AND category_id = 3 ORDER BY views ASC , date DESC

这就是它最终应该显示的方式(我没有添加limit),但我想创建一个函数来动态完成这一切,而不是每个数组类型的所有 if 语句。

目前,我正在使用这样的数组:

Array
(
    [where] => Array
        (
            [status] => Array
                (
                    [op] => !=
                    [value] => 2
                )

            [category_id] => Array
                (
                    [op] => =
                    [value] => 3
                )

        )

    [orderBy] => Array
        (
            [views] => ASC
            [date] => DESC
        )

    [offsetLimit] => Array
        (
            [offset] => 
            [limit] => 
            [full] => LIMIT 0, 12
        )

)

它现在的结构方式是: where 是一个包含选项的数组,所以 statuscategory_id 是我想要显示为 WHERE status.. 等的项目。 每个都有一个op,这是要执行的操作,然后是值,所以它最终会是Where status != 2

orderBy 只输出键和值,例如views ASC.

offsetLimit 允许您单独发送偏移量和限制,函数会将其放在一起输出,或者您可以在full 设置中发送它的字符串。

我确信可以创建一个函数来处理这个问题并且动态地支持更多选项,我现在出于某种原因无法理解它。

谢谢!

编辑: 需要明确的是,我不想使用该函数从数据库中获取任何数据,该函数的唯一目的是格式化给它的数据。 发送给函数的数组将包含表名和函数格式化字符串所需的所有内容。

【问题讨论】:

  • 所以,创建一个查询模板,然后用实际值替换一些占位符。
  • 实际上并没有那么难,但要确保它的安全性要困难得多。客户可以编辑密钥,因此您必须了解表中的所有字段并对其进行清理。 SELECT $value FROM $table WHERE $something = $value 这些变量中的任何一个都可用于执行 SQLInjection,如果未正确清理。事实上,刚刚在新闻中出现了一个存在密钥注入漏洞的 wordpress 插件。
  • 我想要结束的是对函数的调用,例如,$string = setQueryString($array)。该函数将根据我发送的数据返回一个字符串。
  • 单个函数写很多代码,只是说。要做到这一点,它可能需要超过 500 行代码。我的意思是使用SHOW COLUMNS FROM table 动态地从数据库中获取字段名称...。一旦添加了安全性,这个话题就太宽泛了。我过去也写过类似的东西。
  • 我可能还不清楚,但我不会从数据库中获取数据,我将发送给函数的数组将包含所有数据,函数只会返回一个字符串,其中包含格式化的所有数据。我将发送给它的数组将已经包含表名,函数的目的只是将数据构造为要在 SQL 查询中使用的字符串

标签: php sql arrays


【解决方案1】:

我有一个可用的函数“原型”,我确信这可以改进和清理,但目前它可以正常工作并以正确的方式格式化提供给它的数据。

函数如下:

function formatQueryClauseString($querySettings){

    //This is the string placeholder
    $stringBuild = "";

    //Array containing the clause option separators
    $separators = array(
        "where" =>      " AND",
        "order by" =>   ",",
        "limit" =>      ","
    );

    //Loop through the data
    foreach($querySettings AS $clause => $data){

        //Add the clause to the string
        $stringBuild .= " ".$clause;

        //Start an itiration counter
        $i = 0;

        //Loop through the clause settings
        foreach($data AS $key => $value){

            //Add the separators if not first iteration
            if($i > 0){
                $stringBuild .= $separators[strtolower($clause)];
            }

            //Start another iteration counter (used for the limit clause)
            $x = 0;

            //Loop through the clause setting values
            foreach($value AS $val){

                //If its a limit clause, add the separator here
                if(strtolower($clause) == "limit" && $x == 1){
                    $stringBuild .= $separators[strtolower($clause)];
                }

                //Add the value to the string
                $stringBuild .= " ".$val;
                $x = 1;
            }
            $i = 1;
        }
    }

    //Return the formatted string
    return $stringBuild;
}

当给定以下数组时:

Array
(
    [WHERE] => Array
        (
            [1] => Array
                (
                    [column] => status
                    [op] => !=
                    [value] => 2
                )

            [2] => Array
                (
                    [column] => category_id
                    [op] => =
                    [value] => 3
                )

        )

    [ORDER BY] => Array
        (
            [1] => Array
                (
                    [by] => views
                    [order] => ASC
                )

            [2] => Array
                (
                    [by] => date
                    [order] => DESC
                )

        )

    [LIMIT] => Array
        (
            [1] => Array
                (
                    [offset] => 0
                    [limit] => 12
                )
        )
)

它返回这个:

WHERE status != 2 AND category_id = 3 ORDER BY views ASC, date DESC LIMIT 0, 12

因此,总体而言,它应该正常工作。 我会尝试改进它,但也许它对其他人有用,也许其他人也可以帮助改进它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-09
    • 2021-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多