【问题标题】:Determine MySQL query type in Zend Framework在 Zend Framework 中确定 MySQL 查询类型
【发布时间】:2011-07-29 20:45:40
【问题描述】:

谁能告诉我如何确定查询类型,即在通过 MySQL 执行之前选择、更新、删除或插入

我坚信 Zend Framework 内部可能正在使用 mysql*_query 函数来执行它们。

我需要一个集中式函数,它会在执行前返回查询类型。

我为每个数据库表使用三个文件

我给你举个例子。

假设我想为类别表创建模型。

所以我将创建以下文件

DbTable/Categories.php

class Application_Model_DbTable_Categories extends Zend_Db_Table_Abstract {
    protected $_name = 'categories';
    protected $_dependentTables = array('Application_Model_DbTable_Videos');
}

Categories.php

class Application_Model_Categories extends Application_Model_CommonGetterSetter {
    protected $_type = array('id' => 'int', 'name' => 'string', 'slug' => 'string', 'status' => 'int');

    public function __construct(array $options = null) {
        parent::__construct($options, __CLASS__);
    }
}

CategoriesMapper.php

class Application_Model_CategoriesMapper {

    protected $_dbTable;

    public function setDbTable($dbTable) {

        if (is_string($dbTable)) {
            $dbTable = new $dbTable();
        }

        if (!$dbTable instanceof Zend_Db_Table_Abstract) {
            throw new Exception('Invalid table data gateway provided');
        }

        $this->_dbTable = $dbTable;
        return $this;
    }



    public function getDbTable() {
        if (null === $this->_dbTable) {
            $this->setDbTable('Application_Model_DbTable_Categories');
        }
        return $this->_dbTable;
    }



    public function save(Application_Model_Categories $categories) {
        $data = array(
                'name'      => $categories->name,
                'slug'      => $categories->slug,
                'status'    => $categories->status,
        );

        if (@$categories->id <= 0) {
            return $this->getDbTable()->insert($data);
        } else {
            $this->getDbTable()->update($data, array('id = ?' => $categories->id));
            return $categories->id;
        }
    }

CommonGetterSetter.php

class Application_Model_CommonGetterSetter {

    protected $_data = array();
    private $_class_name;

    public function __construct(array $options = null, $class_name = null) {
        if (is_array($options)) {
            foreach ($options as $key => $value) {
                $this->$key = $value;
            }
            $this->_class_name = $class_name;
        }
    }

    public function __set($name, $value) {
        if (!array_key_exists($name, $this->_type)) {
            throw new Exception("Invalid {$this->_class_name} property". $name);
        }
        else {
            settype($value, $this->_type[$name]);
            $this->_data[$name] = $value;
        }
    }

    public function __get($name) {
        if (!array_key_exists($name, $this->_type)) {
            throw new Exception("Invalid {$this->_class_name} property". $name);
        }
        else {
            return $this->_data[$name];
        }
    }
}

所以我想知道执行了哪个查询,我应该在哪里写什么?

非常感谢。

我知道代码有点长,但这是为了给出一个完整的想法。

【问题讨论】:

  • 你不应该坚信,你应该阅读代码!

标签: php zend-framework


【解决方案1】:

我坚信 Zend Framework 内部可能正在使用 mysql*_query 函数来执行它们。

ZF 的数据库类不支持老旧的 mysql 扩展。 It has adapters for PDO and mysqli。你会知道你使用的是哪一个,因为你必须在你的代码或配置中明确指定一个

所以我想知道执行了哪个查询

我认为,重新思考您的设计会为您提供更好的服务。不清楚这里发生了什么,也不清楚为什么您认为您需要知道查询类型,也不清楚您希望在哪里知道查询类型。

Please review the Zend_Db_Table documentation,因为看起来您可能在途中的某个地方错过了重点。

具体来说,Zend_Db_Table 已经提供了用于插入、删除和更新的方法。如果您需要更改相应方法的行为,请通过simply overriding it in your class 进行。

此外,您似乎正在尝试构建某种智能列类型定义系统。您不需要这样做,同样,Zend_Db_Table 已经向您提供了此信息,如果您不希望它自动确定此信息,even lets you hard-code it

ZF 是一只复杂的野兽。如果你要使用它,我建议你完全理解它所能做的一切。构建非标准的冗余架构只会让您以后的事情变得复杂。

【讨论】:

  • 嗨,查尔斯!感谢您的建议。对不起!我错过了 PDO 部分。现在就 WHY TO KNOW THE QUERY 类型而言,让我解释一下。我们正在一个典型的主从场景中工作。我正在使用 Zend Multidb 模式。我想将所有 SELECT 查询重定向到从属服务器,并将所有 INSERT、UPDATE、DELETE 查询重定向到主服务器。对元数据进行硬编码不是首选,因为它是耗时且乏味的过程之王:-)。那么你能指导我如何实现我的目标吗?
  • @Jatin,在这种情况下,你最好的选择是编写一个自定义 Zend_Db_Adapter 来处理这种精神错乱。您可以通过扩展您当前选择的适配器并覆盖所需的方法来做到这一点,或者在Zend_Db_Adapter_Abstract 之上实施您自己的解决方案。
  • 你好,查尔斯。感谢您提供此链接。我会试一试。但是您不认为这是任何开发人员在开发过程中都可能面临的合法要求吗?我们如何向 Zend 报告此类问题?
  • MySQL 不能处理这个吗?某事。像 MySQL 服务器代理一样,它将根据类型将查询发送到不同的服务器......?
  • @Tomáš,虽然有一个 MySQL 代理,但它的负载平衡部分被明确标记为实验性的,尚未准备好用于生产。 @Jatin,您可能应该前往 ZF 的网站和 find an appropriate place to leave that feedback
【解决方案2】:

编辑:我正在查看 Zend_Db_Table 和 Zend_Db_Table_Abstract 的代码,现在我的第二个解决方案似乎更加困难。

大家好,

如果你想让自己有点头疼,你可以做的是继续使用 multidb 资源创建两个连接,一个连接到从站,一个连接到主站。

将默认连接设置为最常用的连接。

然后,通过另一个连接,您可以在每次需要使用它时手动获取它,并直接处理适配器而不是通过 DbTable 类。

例如,为获取另一个适配器的映射器类创建另一个名为 getOtherDbAdapter() 的方法。然后,您可以从那里使用适配器执行选择或插入。

哦!

另一个解决方案是您可以扩展 Zend_Db_Table 或 Zend_Db_Table_Abstract 类并为第二个数据库连接创建另一个变量。

然后,复制并粘贴 Zend_Db_Table_Abstract 类中所有 fetch/select/insert/update 方法的实现代码,并让它在您看到执行您希望重定向到另一个的操作的代码时使用另一个适配器分贝。

【讨论】:

  • 我所做的是编写了我自己定制的 PDO 扩展 mysqli pdo 并覆盖了查询方法。 IT 运行良好。
猜你喜欢
  • 1970-01-01
  • 2012-02-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多