如何在 PHP 中实现类似 printf 的函数?

发布于 2024-12-26 10:30:14 字数 229 浏览 4 评论 0原文

我想为我的数据库抽象创建一个 db_queryf 函数。它的工作方式有点像 SQLite 中的 sqlite3_mprintfdb_queryf('select * from pages where name=%q', $_GET['name']),其中 %q 将生成正确转义的字符串。在 PHP 中创建类似 printf 的函数的正确方法是什么?是否有任何辅助函数,或者我应该自己解析它?

I want to make a db_queryf function for my database abstraction. It will work somewhat like sqlite3_mprintf from SQLite: db_queryf('select * from pages where name=%q', $_GET['name']), where %q will produce a properly escaped string. What is the proper way of making printf-like functions in PHP? Is there any helper functions for that or I should parse it myself?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

Saygoodbye 2025-01-02 10:30:14

我很困惑... (s)printf 显然已经存在,并且您可能想使用 SQLite3Stmt::bindValue 更多信息,除非你想最终陷入逃避/sql注入地狱。

I am confused... (s)printf plainly allready exists, and you probably want to use SQLite3Stmt::bindValue more for this, unless you want to end up in escaping / sql-injection hell..

樱娆 2025-01-02 10:30:14

使用PDO 准备好的语句。替换为字符串还不够好,您应该进行清理。

Use PDO prepared statements. Replacing into the string isn't good enough, you should be sanitizing.

盗心人 2025-01-02 10:30:14

sprintf()

sprintf('select * from pages where name=\'%s\'', $_GET['name']);

清理所有内容非常很重要在使用之前,在 $_GET 中!

sprintf()

sprintf('select * from pages where name=\'%s\'', $_GET['name']);

Its very important, that you sanitize everything in $_GET, before you use it!

林空鹿饮溪 2025-01-02 10:30:14

好吧,由于我遇到了完全相同的问题,所以我尝试了一下,看起来效果很好。

以下函数位于数据库包装类中,并期望像 printf 一样被调用,其中 %% 被转换为文字 %,%e 将字符串参数标记为转义,并且 %u 标记要按原样获取的字符串参数。

LOGDB 是第二个数据库包装类,负责捕获和记录各种错误。

  public static function query($format)
  {
    $query = $format . ' ';

    $argc = func_num_args();
    $argv = func_get_args();

    $index_query = 0;
    $index_args = 1;

    while (($index_query = strpos($query, '%', $index_query)) !== false)
      {
        switch ($query[$index_query + 1])
          {
          case '%':
            $query = substr_replace($query, '', $index_query, 1);
            $index_query++;
            break;
          case 'e':
            if ($index_args >= $argc)
              {
                LOG::failedQuery($format, "not enough arguments for format");
                return false;
              }
            $query = substr_replace($query, DB::escape($argv[$index_args]), $index_query, 2);
            $index_query += strlen($argv[$index_args]);
            $index_args++;
            break;
          case 'u':
            if ($index_args >= $argc)
              {
                LOG::failedQuery($format, "not enough arguments for format");
                return false;
              }
            $query = substr_replace($query, $argv[$index_args], $index_query, 2);
            $index_query += strlen($argv[$index_args]);
            $index_args++;
            break;
          default:
            LOG::failedQuery($format, "unknown control sequence '%" . $query[$index_query + 1] . "'");
            return false;
          }
      }

    if ($index_args != $argc)
      {
        LOG::failedQuery($format, "too many arguments for format");
        return false;
      }

    $res = mysqli_query(self::$handle, $query);
    if (!$res)
      LOGDB::failedQuery($query, mysqli_error(self::$handle));

    return $res;
  }

注意:代码大部分未经测试,很可能包含一堆错误。谨慎使用:)

okay, since I had exactly the same problem, I gave it a shot, and it seems to work quite nicely.

The following function sits inside a database wrapping class, and expects to be called like printf, where %% is transformed to a literal %, %e marks a string argument to be escaped, and %u marks a string argument to taken as-is.

LOGDB is a second database wrapping class, that is responsible for catching and logging all kinds of errors.

  public static function query($format)
  {
    $query = $format . ' ';

    $argc = func_num_args();
    $argv = func_get_args();

    $index_query = 0;
    $index_args = 1;

    while (($index_query = strpos($query, '%', $index_query)) !== false)
      {
        switch ($query[$index_query + 1])
          {
          case '%':
            $query = substr_replace($query, '', $index_query, 1);
            $index_query++;
            break;
          case 'e':
            if ($index_args >= $argc)
              {
                LOG::failedQuery($format, "not enough arguments for format");
                return false;
              }
            $query = substr_replace($query, DB::escape($argv[$index_args]), $index_query, 2);
            $index_query += strlen($argv[$index_args]);
            $index_args++;
            break;
          case 'u':
            if ($index_args >= $argc)
              {
                LOG::failedQuery($format, "not enough arguments for format");
                return false;
              }
            $query = substr_replace($query, $argv[$index_args], $index_query, 2);
            $index_query += strlen($argv[$index_args]);
            $index_args++;
            break;
          default:
            LOG::failedQuery($format, "unknown control sequence '%" . $query[$index_query + 1] . "'");
            return false;
          }
      }

    if ($index_args != $argc)
      {
        LOG::failedQuery($format, "too many arguments for format");
        return false;
      }

    $res = mysqli_query(self::$handle, $query);
    if (!$res)
      LOGDB::failedQuery($query, mysqli_error(self::$handle));

    return $res;
  }

Note: the code is mostly untested, chances are, it contains a bunch of bugs. use with caution :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文