【问题标题】:Any problem with this Mysql Helper class?这个 Mysql Helper 类有什么问题吗?
【发布时间】:2025-12-22 05:05:12
【问题描述】:

我的数据库类中有这个函数。 它接受 3 个参数:

  • 查询
  • 执行它的服务器由存储在配置中的名称标识
  • 在 sql 查询中引用的参数数组

示例调用:

$toplist = MyDbClass->q('SELECT * FROM movies WHERE score > ?','slaveserver1',array(100));

代码来了...

/*
 * @param the sql query. may be pure sql or having ? as placeholders for variables that are passed in the 3rd param, not enquoted
 * @param name of the link (slave or master server or other arbitrary database)
 * @param optional array of vars that will be filled in where the ? signs in the query are
 */
public function q($sql,$name,$vars=false) {
    // lets see if the link to the server with name $name has already been initialised, if not lets do it
    if(!isset($this->links[$name])) {
        $this->initialize($name);
    }
    // if variables have been passed, lets fill them into the query
    if($vars !== false) {
        // first real scape them all according to the correct link
        for($i=0;$i<count($vars);$i++) {
            $vars[$i] = mysql_real_escape_string($vars[$i],$this->links[$name]);
        }
        // now escape all actual % signs so they are not used as placeholders vor vsprintf
        $sql = str_replace('%','%%', $sql);
        // no add '' quotes arround every placeholder and fill in
        $sql = str_replace('?','\'%\'', $sql);
        $sql = vsprintf($sql,$args);
    }
    // now execute the parsed query on the correct server
    return mysql_query($sql,$this->links[$name]) or die(mysql_error($this->links[$name]));
}

现在我的问题是:

我的代码有问题吗?特别是:

  • 在任何情况下,在查询中将 '' 引号括在参数周围会使其不起作用?
  • 是否有一些优雅的方法可以防止我的函数在我的查询中出现像where score &gt; ''100 '' 这样的双引号内容(如果我已经在输入查询中放置了qutoes...)。
  • 你觉得这个函数怎么样?这样做的好方法吗?

【问题讨论】:

    标签: php mysql wrapper helper


    【解决方案1】:

    我不认为,允许一个类操作多个 SQL 连接是一个好主意。应该允许此类的每个实例仅使用一个 SQL 连接。或者,如果您尝试实现某种手动负载平衡,则应该对用户透明地使用它,可能只允许“从”和“主”选择。

    您可能应该将查询分为“读取”和“写入”查询,因为您可以从任何从属设备“读取”,但应该“写入”所有这些。

    另外,如果查询调度是为了负载平衡的目的,你需要在类构造函数中打开连接,而不是在查询中延迟打开它们。一个脚本是一个非常短暂的生物。除非您为长期操作编写 CLI 脚本,否则无需延迟连接直到真正执行查询。

    【讨论】:

    • 我认为你误会了 :) 主要目的是仅在需要时才启动连接,并在服务器上进行第一次查询。主要目的是读/写连接,但也可能有其他连接。例如,一些很少需要的。然后,initialise 从 conflig 类中获取正确的连接信息并按需建立连接。系统工作正常。现在我只通过了完整的查询并通过这个 $args 东西增强了这个类。