格式化SQL"IN"子句的PHP数组

And*_*rew 4 php mysql codeigniter

我正在尝试在数据库中查询"product_id"包含在产品ID数组中的记录.

数组是多选输入(<select>)的结果,如下所示:

$clients = 
  Array ( 
    [0] => 80000016-1302638679
    [1] => 8000003B-1329924004
  )
Run Code Online (Sandbox Code Playgroud)

我想将该数组传递给SQL语句的"IN"子句,例如:

$sql = "SELECT * FROM sales WHERE product_id IN (".$clients.")";
Run Code Online (Sandbox Code Playgroud)

...但这不起作用(错误:) Message: Array to string conversion.

一些帖子建议使用此函数以适合SQL的方式格式化数组:

function format_array($array){
    return implode(', ', $array);
  }
}
Run Code Online (Sandbox Code Playgroud)

如 ...

$sql = "SELECT * FROM sales WHERE product_id IN (".format_array($clients).")";
Run Code Online (Sandbox Code Playgroud)

这导致了这个查询:

SELECT * FROM sales WHERE product_id IN (80000016-1302638679, 8000003B-132992400)

......而且这个错误:

Unknown column '8000003B' in 'where clause'

我究竟做错了什么?任何帮助是极大的赞赏!如果需要,我可以澄清这个问题:)

Dan*_*ams 7

试试这个把你的id放在引号中:

function format_array($array){
    return "'" . implode("', '", $array) . "'";
  }
}
Run Code Online (Sandbox Code Playgroud)

正如cwallenpoole指出的那样,如果你还没有,你应该逃避弦.不转义字符串是非常危险的,特别是如果你有一个公共应用程序.


cwa*_*ole 5

有一个更好的方法

您在评论中提到您正在使用CodeIgniter.除非你制作一些非常复杂的东西,否则当你where_in内置时,你应该建立自己的自制查询是没有实际意义的.

如果这不起作用,那么就会有很好的风格escape.


好的,所以,你有大多数人说你需要引用这些项目并给你这个:

function createInClause($arr)
{
    return '\'' . implode( '\', \'', $arr ) . '\'';
}
Run Code Online (Sandbox Code Playgroud)

但是,如果您有可能输入有问题(例如,'); DROP TABLE STUDENTS; --为了防止这种情况,那么这确实是不够的.您需要确保检查SQL注入:

function createInClause($arr)
{
    $tmp = array();
    foreach($arr as $item)
    {
        // this line makes sure you don't risk a sql injection attack
        // $connection is your current connection
        $tmp[] = mysqli_escape_string($connection, $item);
    }
    return '\'' . implode( '\', \'', $tmp ) . '\'';
}
Run Code Online (Sandbox Code Playgroud)