首页 > 解决方案 > 将不推荐使用的函数调用重定向到较新的函数

问题描述

我有一个相当复杂的网站,为此我将数据库驱动程序升级到 MySQLi(是的,我知道..)。我有一些 20-ish 功能点,我重写了包含 mysql_real_escape_string 的查询代码,但这对于整个站点来说已经变得非常繁琐。

有没有办法将任何对 mysql_real_escape_string 的调用“重定向”到另一个函数:mysqli_real_escape_string,包括进行调用的当前对象/类?

<?php
  class foo {
    private $_sql;

    public function __construct() {
      $this->_sql = new db();
    }

    public function get_posts($id) {
      $this->_sql->query = 'select * from posts where id = ' . mysql_real_escape_string($id);
    }
  }
?>

每个类都包含一个 sql 属性,它包含一个 db 连接,但由于 mysqli_real_escape_string 需要作为第一个参数传递的连接,我需要一个“获取”机制来重定向mysql_real_escape_string到类似的东西:

function custom_mres($caller, $param) {
  return mysqli_real_escape_string($caller->_sql->connection, $param);
}

这可能吗?

标签: php

解决方案


如果您升级到更高版本的 PHP,其中 mysql_* 方法现在已经消失,您应该能够重新定义它们,虽然这不是最佳解决方案,但我完全理解为什么需要一个权宜之计。

我建议使用静态类来跟踪连接对象,如下所示:

<?PHP
  class DBWrapper {
    static private $dbc;

    static public escape($str) {
      return mysqli_real_escape_string(self::$dbc, $str);
    }
  }

  if (!function_exists('mysql_real_escape_string'))
    function mysql_real_escape_string($str) { return DBWrapper::escape($str); }      
?>

注意:我不主张保留此解决方法,您确实应该更新您的应用程序以使用现代方法

另一个建议是error_log在那里调用以标记已弃用,以便您以后轻松识别和更正它,例如:

<?PHP
  define('LOG_DEPRECATED', 1);

  class DBWrapper {
    static private $dbc;

    static public escape($str) {
      if (defined('LOG_DEPRECATED'))
      {
        ob_start();
        print_r(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS));
        error_log("Deprecated call:\n", ob_get_clean());
      }
      return mysqli_real_escape_string(self::$dbc, $str);
    }
  }      
?>

此外,虽然@Dharman 建议使用准备好的语句很好,但如果操作正确,手动转义也不是不安全的。只需确保将连接和数据库编码设置为合理的值并且mysqli_real_escape_string可以安全使用,并且在许多情况下更快,因为数据库引擎不需要“准备”语句并在执行之前返回句柄/对象。


推荐阅读