将不推荐使用的函数重定向到较新的函数

时间:2019-04-08 20:08:52

标签: php

我有一个相当复杂的网站,为此我正在将数据库驱动程序升级到MySQLi(是的,我知道..)。我已经编写了20个功能点,重新编写了包含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);
}

这可能吗?

1 个答案:

答案 0 :(得分:1)

如果您升级到现在不再使用mysql_ *方法的PHP的更高版本,则您应该能够重新定义它们,尽管这不是最佳解决方案,但我完全理解为什么人们需要一种限位措施。

我建议使用静态类来跟踪连接对象,就像这样:

<?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就可以安全使用,并且在许多情况下,由于数据库引擎不需要“准备”语句并在返回之前返回句柄/对象,因此在许多情况下速度更快执行。