【问题标题】:Using placeholders in MySQL 'COOPERATIVE' LOCK queries [duplicate]在 MySQL 'COOPERATIVE' LOCK 查询中使用占位符
【发布时间】:2020-06-16 20:48:41
【问题描述】:

我过去在MySQL中成功使用过所谓的协同LOCK。我的 PHP 代码中有自定义函数,可以获取锁定、释放锁定和检查锁定是否有效。例如,要锁定,我做了类似的事情:

//code
"SELECT GET_LOCK( 'unique_string', -1 ) AS acquired"
// code
return ( $row['acquired'] == 1);

为了解锁,我做了类似的事情:

// code
"SELECT RELEASE_LOCK( 'unique_string' ) AS released"
// code
return ( $row['released'] == 1 );

最后,为了检查锁是否生效,我做了:

//code
"SELECT IS_USED_LOCK( 'unique_string' ) AS connection_id"
//code
return ( NULL != $row['connection_id'] );

在所有这些情况下,我都使用了PDO::query() 方法(即没有准备好的语句),因为我的 SELECT 语句不包含任何参数

现在,需要将用户的输入连接到unique_string。有没有办法让unique_string 包含一个占位符以便使用PDO::prepare() 并避免可能的SQL 注入攻击?

谢谢。

【问题讨论】:

  • 据我所知,这是一个常规的 SELECT 查询 ant 没有理由不使用占位符
  • @YourCommonSense,您是否建议在这种情况下注入攻击不起作用?例如,如果我将一个变量连接到unique_string,例如unique_string.$variable。如果 $variable 包含;DROP *.* -- 怎么办?我不确定,我只是想安全一点。
  • 我建议 占位符在 SELECT 查询中起作用。 并且不知道你从哪里得到其他任何东西
  • @YourCommonSense,我的错!我没有在您的评论中看到“不”。我很抱歉。
  • @YourCommonSense,我已经诚实地查看了您链接到的问题。我不认为这是重复的。请再仔细看看,请重新打开这个问题。

标签: mysql pdo prepared-statement


【解决方案1】:

使用准备好的语句应该没有问题,只需使用

$statement = PDO::prepare("SELECT GET_LOCK( ?, -1 ) AS acquired");
$statement->execute([$uniqueString]);

您也可以使用命名参数,建议查看 PDO 的准备好的语句文档。

【讨论】:

  • 我也是这么想的。我会执行您的建议并在必要时接受您的回答。
  • 占位符必须不加引号,并且参数必须作为数组传递给execute,正如已经注释的那样。
  • @deceze,请看一下锁的语法,字符串被引用了,那为什么要取消引用占位符呢?只是想知道。不幸的是,stackoverflow 是一个社区,几乎所有真诚的问题都被视为挑战。好吧,你可能不是那样,但我很沮丧!
  • @Stephen 因为这就是占位符的工作方式:php.net/manual/en/pdo.prepared-statements.php。它不像字符串中的搜索和替换那样工作。数据库在句法级别理解? 是一个占位符。 '?' 是一个带问号的字符串,? 是一个占位符。
  • @Stephen Nope,没有看到这里发生了什么。如果您传递一个字符串作为该占位符的值,那么它将是一个字符串。 SELECT ? + execute(['foo']) → 相当于SELECT 'foo'。无论您使用 named 占位符还是 positional 占位符 (?) 都无关紧要。
猜你喜欢
  • 2021-11-07
  • 1970-01-01
  • 1970-01-01
  • 2023-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-17
相关资源
最近更新 更多