4

我正在尝试创建一个中间类,它将查询及其执行时间记录在一个数组中。一切都很好,而且效果很好。但是当我尝试访问中间类时,自动完成不起作用。如何让自动完成工作。我正在使用 Netbeans。

中间类名是 Model。

在我的应用程序中,我有一个名为 Users 的类,它扩展了 Model。

class Users extends Model
{
    function __construct() {
        parent::__construct();
        $stmt = $this->prepare('SELECT * FROM users WHERE id=? ');

        $stmt->bindValue(1, 1); //$stmt-> auto-complete is unavailable
        $stmt->execute();

        $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);

        print_r($rows); //i get results
    }
}

我的模型类看起来像这样。

class Model extends PDO
{
    public static $log = array();
    private $query_cache = array();

    public function __construct() {
        parent::__construct(
            "mysql:dbname=".MYSQL_DB.";host=".MYSQL_HOST,
            MYSQL_USER, MYSQL_PASSWORD
        );
    }

    public function query($query) {
        $time = "";
        $query = mysql_real_escape_string(preg_replace( '/\s+/', ' ', $query ));

        if (key_exists($query,$this->query_cache)
            && is_object($this->query_cache[$query]))
        {
            $result = $this->query_cache[$query];
        } else {
            $start = microtime(true);
            $result = parent::query($query);
            $time = microtime(true) - $start;
            $this->query_cache[$query] = $result;
            Logger::$logText['DATABASE'][] = array(
                'QUERY' => $query,
                'TIME'  => number_format($time,4)
            );
        }
        return $result;
    }

    /**
     * @return LoggedPDOStatement
     */
    public function prepare($query) {
        return new LoggedPDOStatement(parent::prepare($query));
    }
}

我的 LoggedPDOStatement 看起来像这样。

class LoggedPDOStatement
{
    /**
     * The PDOStatement we decorate
     */
    private $statement;

    public function __construct(PDOStatement $statement) {
        $this->statement = $statement;
    }

    /**
     * When execute is called record the time it takes and
     * then log the query
     * @return PDO result set
     */
    public function execute() {
        $start = microtime(true);
        $result = $this->statement->execute();
        $time = microtime(true) - $start;
        Model::$log[] = array(
            'query' => '[PS] ' . $this->statement->queryString,
            'time'  => round($time * 1000, 3)
        );
        return $result;
    }
    /**
     * Other than execute pass all other calls to the PDOStatement object
     * @param string $function_name
     * @param array $parameters arguments
     */
    public function __call($function_name, $parameters) {
        return call_user_func_array(
            array($this->statement, $function_name), $parameters
        );
    }
}

他们有更好的方法吗?

4

1 回答 1

1

我已经修复了来自@cilosis 和@Touki 的建议

@Touki,我同意我不应该扩展 PDO 类。@cilosis,感谢您的评论。

这就是我写我的课的方式。我还没有粘贴完整的代码,因为它还没有完成。但我已经检查过它是否有效。我也可以记录我的查询。但是我不确定我是否能够记录执行时间。

class Model
{
    /**
     * The singleton instance
     *
     */
    static private $PDOInstance;

    public function __construct($dsn="", $username = false, $password = false, $driver_options = false) {
        if (!self::$PDOInstance) {
            try {
                self::$PDOInstance = new PDO(
                    "mysql:dbname=".MYSQL_DB.";host=".MYSQL_HOST,
                    MYSQL_USER, MYSQL_PASSWORD
                );
            } catch (PDOException $e) {
                die("PDO CONNECTION ERROR: " . $e->getMessage() . "<br/>");
            }
        }
        return self::$PDOInstance;
    }

    /**
     * Initiates a transaction
     *
     * @return bool
     */
    public function beginTransaction() {
        return self::$PDOInstance->beginTransaction();
    }

    public function prepare($statement, $driver_options = false) {
        //log the $statement
        if (!$driver_options)
            $driver_options = array();
        return self::$PDOInstance->prepare($statement, $driver_options);
    }
}
于 2012-12-19T16:02:20.843 回答