Php $\u会话对sql注入是否安全?

Php $\u会话对sql注入是否安全?,php,mysql,pdo,Php,Mysql,Pdo,我使用PDO访问我的MySQL数据库,并希望在中使用。但遗憾的是,它不能与prepare一起工作,所以我编写了这个函数 function is_numeric_array($array){ if(!is_array($array)) return is_numeric($array); if(is_array($array)) foreach($array as $int) if(!is_numeric($int))

我使用PDO访问我的MySQL数据库,并希望在中使用。但遗憾的是,它不能与prepare一起工作,所以我编写了这个函数

function is_numeric_array($array){
    if(!is_array($array))
        return is_numeric($array);

    if(is_array($array))
        foreach($array as $int)
            if(!is_numeric($int))
                return false;
    return true;
}
然后像这样使用它

    if(!is_numeric_array($_SESSION['story'])){
        die("Error, array contains non-integers");
    }

    $query = "(";
    for($i = 0; $i<count($_SESSION['story']); $i++)
        $query .= $_SESSION['story'][$i].(count($_SESSION['story'])-1 != $i ? "," : "");
    $query .= ")";

    //Collect all data needed
    $stories = openConnection() -> query("SELECT * FROM `stories` WHERE `id` IN {$query}") -> fetchAll();
如果(!是数值数组($\会话['story'])){
die(“错误,数组包含非整数”);
}
$query=“(”;
对于($i=0;$i query(“从{$query}中的`stories`WHERE`id`中选择*)->fetchAll();

我知道,看起来很难看。但我不想要任何SQL注入。

即使是cookie或会话,出于安全目的,我存储的哈希值仅为字母数字。当我检查cookie/会话是否有任何类型的注入/修改时,我使用:


这样,无论是谁设置会话值(您或客户机,如果您允许的话),在任何情况下都不会插入非字母数字字符,如
逗号
引号
双引号
,或任何将被插入的字符。

您实际上不必测试输入是否为数字,因为在MySQL中,任何字符串(例如
'123abc'
)都是数字上下文(就像与整数列比较一样,
id
)隐式地只接受数字,而忽略其余部分。像
'abc'
这样的非数字字符串只具有整数值0,因为没有前导数字

关键是,如果使用查询参数,值就不会被SQL注入。输入是否来自$\u会话或其他源无关紧要。$\u会话对于SQL注入既不安全也不不安全,重要的是如何将数据传递给查询

我还将简化代码以设置参数占位符列表的格式:

$placeholders = implode(',', array_fill(1, count((array)$_SESSION['story']), '?'));
忘记bindParam(),只需将数组传递给
execute()


请回复您的评论:

在PDO中,您可以使用命名参数,如
:id
,也可以使用位置参数,它们总是
(但不要在给定查询中混合使用这两种类型,请使用一种或另一种)

将数组传递给
execute()
会自动将数组元素绑定到参数。简单数组(即通过整数索引)很容易绑定到位置参数

如果使用命名参数,则必须传递一个关联数组,其中数组的键与参数名称匹配。数组键可以选择前缀为
,但这不是必需的


如果您是PDO新手,阅读代码是值得的。这里有代码示例和所有内容!

$\u会话只是通过会话在服务器上存储数据的一种方式。它与SQL注入没有直接关系。

为什么不在语句的IN子句中构建一系列?、数组中的每个条目一个?、然后您仍然可以使用绑定变量from数组中的值以生成带有提示的语句:在条件和循环周围使用大括号。最终会遇到麻烦,这取决于$\u会话变量来自何处。如果它只能由您设置,则可以设置,但如果涉及任何用户输入,则它是不安全的…该变量看起来更干净,但有两件事我不明白。那就是
和为什么
(数组)$\u会话['story']
在执行中。(我是PDO新手)现在我明白了,它只是将数组设置为
?,?,?
,然后在执行时,它获取一个数组并填充这些值,对吗?是的,它保证创建正确数量的
占位符,因为我使用了
count()
的数组。非常感谢。我的问题是阅读不是我的学习方式。但我会看一看。我使用youtube做一些东西,其他的我只是尝试一个错误。所以如果我更改这行
$\u SESSION['story'][=$\u POST['action']
使用它会安全吗?@Yemto我认为重点是,无论您如何检索要存储的数据(从内存、常量、会话数据、用户输入),重要的是您如何将其传递到数据库查询。是的,是的。您必须检查长度。会话作为存储空间受到限制。
$placeholders = implode(',', array_fill(1, count((array)$_SESSION['story']), '?'));
//Collect all data needed
$storyQuery = openConnection() -> prepare("SELECT * FROM `stories` 
    WHERE `id` IN ({$placeholders})");
$storyQuery -> execute((array)$_SESSION['story']);
$story = $storyQuery -> fetchAll();