下划线方法前缀

时间:2010-09-21 08:44:19

标签: php naming-conventions

我一直在研究CodeIgniter和CakePHP的代码,我注意到它们类中的一些方法以下划线_或双下划线__作为前缀。

这是为了什么目的?

7 个答案:

答案 0 :(得分:12)

如果它不是PHP's magic methods中的任何一个,则表示Visibility缺少适当的可见性关键字:

Cake Coding Conventions:

  

由于我们无法将PHP5的私有和受保护关键字用于方法或变量,因此我们同意以下规则:

     
      
  • 受保护的方法或变量名称以单个下划线(“_”)开头。
  •   
  • 私有方法或变量名称以双下划线(“__”)开头。
  •   

CodeIgniter conventions

  

只有您的类在内部访问的方法和变量,例如公共方法用于代码抽象的实用程序和辅助函数,应该以下划线为前缀。

答案 1 :(得分:1)

这些是PHP类中的Magic Methods

  

函数名__construct, __destruct, __call, __callStatic, __get, __set, __isset, __unset, __sleep, __wakeup, __toString, __invoke, __set_state__clone在PHP类中是神奇的。除非您想要与它们相关联的魔术功能,否则您不能在任何类中使用这些名称的函数。

使用一个下划线的方法没有特殊含义。这更可能是项目的一些编码惯例。

答案 2 :(得分:1)

他们可能是magic methods。有许多方法用于特定目的(对象构造函数,对象析构函数,getter,setter ......)

PHP在这些神奇函数的函数名中保留__前缀。为了任何其他目的,建议不要使用该前缀定义函数。

更新:两个框架似乎也使用__前缀用于自己的目的。请参阅@ Gordon的回答。

答案 3 :(得分:1)

在Codeigniter中,控制器中的方法通常可以作为url的一部分进行调用,因此您可以在控制器“main”中调用方法“index”,如下所示:

mysite.com/main/index。

你可能在你的控制器中有一个方法,你不希望有人能够在网址中作为一个段进行调用,所以你要在它前面添加一个“_”(单个下划线)..这是不同的而不是私人。私有方法只能在定义它的类中调用。因此,控制器方法可以使用下划线作为前缀,这将使其不可用作为url段,并且它也可以被声明为private,这将使其无法从其他类中调用。

答案 4 :(得分:0)

我不熟悉CakePHP或CodeIgniter,但我认为对于非CakePHP类,它们应被视为protectedprivate。它们可能是public,因为它们可以从其他类调用,从而产生某种黑客攻击。请注意,PHP中存在__get__construct和其他魔术方法(如上所述)。

答案 5 :(得分:0)

以__开头的方法是在php中自动调用的魔术方法。 有关更多参考,请检查,

http://php.net/manual/en/language.oop5.magic.php

答案 6 :(得分:0)

我有一个用例,这是我自己的偏好。我会经常编写旨在表达特定接口的特性,虽然由于特征不能直接实现接口,我将指定特征在doc块注释中满足哪个接口,并且前缀与接口无关的受保护和私有方法用一个下划线。这使您可以非常轻松地遵循提供哪些方法来满足合同(接口),以及哪些是支持方法。例如:

interface Foo {
    public function bar(array $args = null, array $flags = null);
}

以下特征的目的是满足Foo接口的要求,但这样做只需要其中一种方法。为清楚起见,受保护的方法是前缀的。即使它们稍后通过扩展公开,这仍然表明它们不是合同依赖于接口,并且不应该被认为是任何相关的。

/**
 * @satifies Foo
 */
trait FooTrait {

    public function bar(array $args = null, array $flags = null) {
        $this->_handleArgs($args);
        $this->_handleFlags($flags);
    }

    protected function _handleArgs(array $args = null) {
        if (is_null($args) {
            return;
        }
        //do something with the args
    }

    protected function _handleFlags(array $flags = null) {
        if (is_null($flags) {
            return;
        }
        //do something with the flags
    }
}

然后,您可以通过在类上实现它并使用相应的特征而不需要额外的工作来满足该接口。

final class ConcreteFoo implements Foo {
    use FooTrait;
}

这使得事物保持松散耦合,并且可以非常容易地与其他需要继承链的库或框架中的其他类集成,而不必使用一堆适配器类来卷积逻辑。

我的IDE(Netbeans)抱怨这是违反PSR-1的行为。由于PSR-1并不直接影响执行,并且可以说这是否是一种更具可读性的方法,我真的可以少关心。我确实尝试遵循直接影响执行的所有PSR。