【问题标题】:sprintf and % signs in textsprintf 和 % 在文本中签名
【发布时间】:2010-04-07 16:14:38
【问题描述】:

我最近遇到的一个问题是,尝试使用此代码更新数据库中的字段时不起作用。我将其追溯到正在更新的文本中有一个% 登录($note,然后是$note_escaped)......虽然用sprintf 插入它效果很好。

我不应该使用sprintf 进行更新,还是应该使用不同的格式?

我做了一些搜索,但找不到任何东西。

$id = mysql_real_escape_string($id);
$note_escaped = mysql_real_escape_string($note);
$editedby = mysql_real_escape_string($author);
$editdate = mysql_real_escape_string($date);
//insert info from form into database
$query= sprintf("UPDATE notes_$suffix SET note='$note_escaped', editedby='$editedby', editdate='$editdate' WHERE id='$id' LIMIT 1");

非常感谢!

【问题讨论】:

  • 谢谢大家:当我接受实际查询并将其卡在 Sequel Pro 中并运行它时,真正让我感到困惑的是 - 它正确更新了数据库。

标签: php mysql printf mysql-escape-string


【解决方案1】:

您使用 sprintf 完全错误。删除代码中的函数调用仍然会做同样的事情。应该是:

sprintf("UPDATE notes_%s SET note='%s', editedby='%s', editdate='%s' WHERE id=%d LIMIT 1", $suffix, $note_escaped, $editedby, $editdate, $id);

您应该阅读手册。

【讨论】:

  • 删除函数调用?你的意思是mysql_real_escape_string?这是一个愚蠢的建议
  • @knittl - 不,删除 sprintf 会给出相同的代码。我到底在哪里提到了 mysql_real_escape_string?
  • 从您的回答中听起来像是,您谈论删除函数调用-什么函数调用?-啊,您在谈论 sprintf-并且不在代码中显示转义函数调用。这可能有点误导
  • 谢谢。顺便说一句,我确实阅读了手册。这不是很清楚..当我试图弄清楚如何将我完美工作的 INSERT sprintf 代码转换为 UPDATE 代码时,我得到了我的代码,我试图让它工作但不能..
【解决方案2】:

首先你应该使用prepared statements而不是sprintf-call

但如果你绝对必须这样做,你必须使用:

$id = mysql_real_escape_string($id);
$note_escaped = mysql_real_escape_string($note);
$editedby = mysql_real_escape_string($author);
$editdate = mysql_real_escape_string($date);
//insert info from form into database
$query= sprintf("
  UPDATE notes_%s /* this is still open for injection, and cannot be properly escaped with mysql_real_escape_string */
  SET note='%s', 
  editedby='%s', 
  editdate='%s' 
  WHERE id='%d'
  LIMIT 1",
$suffix,
$note_escaped, $editedby, $editdate, $id);

【讨论】:

    【解决方案3】:

    您可以通过在mysql中将%替换为\%来转义源文本中的%

    【讨论】:

    【解决方案4】:

    sprintf() 在 PHP 中使用不多,除非您需要以某种方式格式化数据。这两个语句在 PHP 中的工作方式相同:

    $num = 42;
    $char = 'q';
    
    $text = sprintf('The number is %d and the character is %s', $num, $char);
    $text = "The number is $num and the character is $char";
    

    sprintf 在 C 中更多地用于将可变数据“打印”到字符串中。但是 PHP 已经可以用双引号字符串做到这一点,所以除非你需要使用 sprintf 的特殊格式化函数(例如,%0.2f 用于 2 位小数的浮点数),否则使用常规字符串方法更容易。

    【讨论】:

    • 如果在双引号字符串中创建带有变量替换的 sql 字符串,地狱将冻结
    • 只有在您不知道 SQL 注入和/或不在乎的情况下,手动构建查询才是危险的。从屋顶上大喊手动查询很危险无助于教育初学者。
    • 似乎我在某处读到 sprintf() 是一种比普通变量字符串更快的执行 mysql 查询的方法。
    • 不。双引号字符串实际上要快得多。没有格式解析开销:judebert.com/progress/archives/…
    【解决方案5】:

    来自http://php.net/manual/en/function.mysql-real-escape-string.php

    注意:mysql_real_escape_string() 不会转义 % 和 _。如果与 LIKE、GRANT 或 REVOKE 组合,这些是 MySQL 中的通配符。

    您需要使用 \% 和 _ 手动转义 % 和 _。我不建议使用 sprintf,而只是改进您的转义功能。

    【讨论】:

      猜你喜欢
      • 2014-08-15
      • 2020-10-05
      • 2015-05-16
      • 1970-01-01
      • 2023-03-08
      • 1970-01-01
      • 2021-06-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多