PHP - Zend说避免魔术方法?

时间:2010-09-03 10:10:02

标签: php performance magic-methods

我正在阅读此页面 - http://deaduseful.com/blog/posts/50-php-optimisation-tips-revisited

其中一个建议是避免使用Zend Performance PDF引用的Magic Methods,它没有理由建议避免使用它们。

经过一些谷歌搜索(并在这里结束一个无关的问题),我想知道是否有人在这方面有任何推荐?

我在代码中使用了__get(),通常用于保存我并不总是使用的变量,例如。

我可能有一个名为desc,category_id,time_added

的表

我的看法会是这样的:

public function __get($name) {
    switch($name) {
        case 'name':
        case 'desc':
        case 'category':
        case 'time_added':
            $result = do_mysql_query();
            $this->name = $result['name'];
            $this->desc = $result['desc'];
            $this->category = $result['category'];
            $this->time_added = $result['time_added'];
            return $this->{$name};
        break;
        default:
            throw Exception("Attempted to access non existant or private property - ".$name);
    }
}

这似乎是一种很好的做事方式,因为我只需要从数据库中获取一些东西,如果需要的话,我可以放弃像$ article-> time_added这样的东西而不是摆弄数组。

这会被视为不良做法以及服务器上的额外负载吗?

通常我会使用魔术方法扩展类,如果子类与get中的某些内容不匹配,则执行类似的操作。

public function __get($name) {
    switch($name) {
        case 'name':
        case 'desc':
        case 'category':
        case 'time_added':
            $result = do_mysql_query();
            $this->name = $result['name'];
            $this->desc = $result['desc'];
            $this->category = $result['category'];
            $this->time_added = $result['time_added'];
            return $this->{$name};
        break;
        default:
            return parent::__get($name);
    }
}

这会是不好的做法而且对性能有害吗?扩展魔术方法时的最大级别数为3。

3 个答案:

答案 0 :(得分:16)

确实如此,它们的速度较慢......但差异非常小,速度与代码是一个因素。是否值得担心快速开发和维护的差异?

有关统计信息,请参阅magic benchmarks

答案 1 :(得分:1)

考虑使用array accessors

class Record implements ArrayAccess {

    /**
     * @see ArrayAccess::offsetExists()
     *
     * @param offset $offset
     */
    public function offsetExists($offset) {

    }

    /**
     * @see ArrayAccess::offsetGet()
     *
     * @param offset $offset
     */
    public function offsetGet($offset) {
        //fetch and cache $result

        return $result[$offset];
    }

    /**
     * @see ArrayAccess::offsetSet()
     *
     * @param offset $offset
     * @param value $value
     */
    public function offsetSet($offset, $value) {

    }

    /**
     * @see ArrayAccess::offsetUnset()
     *
     * @param offset $offset
     */
    public function offsetUnset($offset) {

    }

答案 2 :(得分:1)

我使用PHP魔术方法和本机get / set操作(在公共属性上)进行了一些测试

结果:

魔术方法比本机访问慢得多。但访问时间仍然很短,在99.9%的情况下不会产生差异。

即使您在一个请求中进行了1百万次魔术方法访问,它仍然只需要大约0.1秒...

“只读”表示通过魔术方法进行访问。  该图显示了PHP 5.5.9和PHP 7.0结果。

benchmark results

以下是基准脚本: https://github.com/stracker-phil/php-benchmark/blob/master/benchmark.php