【问题标题】:Using $this, self::, parent:: for code readability使用 $this, self::, parent:: 提高代码可读性
【发布时间】:2010-11-11 07:02:26
【问题描述】:

我想知道在 php 类中工作时是否可以接受/更喜欢使用 self::method() 和 parent::method()。

您可以使用 $this->method() 但 $this-> 也可以引用类变量、父类变量或父类中的方法。 self:: 中没有歧义

self:: 是否已贬值和/或使用这种风格是否有任何警告或缺点?

我理解 self:: 和 parent:: 是指类的静态实例,但是在 kohana 中,除非您专门将方法定义为静态,否则似乎没有区别。

谢谢。

添加了一个例子: 假设此应用程序存储来自多个网站的论坛...

class Forum_Controller extends Controller {

    function __construct()
    {
        parent::__construct();
    }

    function index()
    {
        echo self::categories();
    }

/*
 * get a list of categories from a specific site.
 */
    private function categories()
    {
        $db = new Database;
        $categories = $db->query("
            SELECT * FROM
            forum_categories
            WHERE fk_site = '$this->site_id'
        ");
        $view = new View('categories_view');
        $view->categories = $categories;
        return $view;
    }

}

此示例适用于 kohana,错误报告设置为: error_reporting(E_ALL & ~E_STRICT);

$this->site_id 在主 Controller_Core 类(kohana 中的一个库)中定义。

据我所知,$this 不应该可用,因为我以静态方式调用 self::categories(),但只有当我将 categories() 定义为静态时,它才会引发错误。

但正如我所说,我更喜欢使用 self:: 因为从可读性的角度来看,我确切地知道这个函数应该在哪里,而不是使用 $this 会导致歧义,对我来说就是这样。

【问题讨论】:

  • 这段代码起作用的原因是你从来没有在静态调用的 categories 方法中引用对象的 $this 实例。

标签: php coding-style kohana


【解决方案1】:

我认为 self:: 通常用于静态函数和属性。

我用的是 Kohana,也许控制器是静态的。

【讨论】:

    【解决方案2】:

    有区别。

    $this 指的是一个对象的实例。

    parentself 用于静态调用方法。

    This page of PHP's manual 比我现在有时间写的更详细地解释了它。特别是第一个例子应该有助于突出一些差异。我鼓励您复制粘贴第一个示例并搞砸它,因为如果您还不知道其中的区别,我认为这是一个重要的概念。

    【讨论】:

    • 感谢您的回复。文档链接非常有帮助。否则我找不到合适的词来找到它。
    • parent 不(仅)用于静态调用方法。如果它是从一个对象上下文中调用的,它会以对象上下文调用父类中的函数。
    【解决方案3】:

    控制器在 Kohana 中不是静态的,尽管它们可以包含静态成员变量/方法或常量。

    self::ClassName:: 的简写方式,即

    class Animal
    {
        public static $arms = 0;
    }
    
    class Dog extends Animal
    {
        public static $leg = 0;
        const NAME = 'dog';
    
        public static function bark()
        {
            echo 'Woof';
        }
    }
    

    要调用静态函数或从类中获取常量,我们使用范围解析运算符::。静态函数是每个类而不是每个对象。说:: 指的是类的静态实例是错误的,它只是访问静态方法的一种方式——没有具有这些方法的对象实例。

    所以:

    Dog::bark(),
    Dog::$leg, 
    Dog::NAME, 
    

    我们也可以使用

    Animal::$arms
    

    在 Dog 类中,我们可以使用 self::parent::,这样我们就不需要输入完整的类名(因为它可能很长!)

    但在回答您的问题时:不 - self:: 未被弃用,不,使用它不是坏习惯。它没有在 kohana 核心中使用的原因是一个非常不同的原因....(使用eval 的透明类扩展请阅读下文以获取更多信息...)。

    ps 静态调用非静态方法是错误并且不应该被允许 - 如果你设置 error_reporting(E_ALL | E_STRICT)(就像你在开发过程中应该做的那样)你会看到一个错误被引发。

    基本上发生的事情是:

    Core 有一个名为:

    class Controller_Core { 
        public function someMethod(){}
    }
    

    你创造:

    // We can use someMethod of Controller_Core
    Index_Controller extends Controller {}
    

    这实际上是在扩展Controller_Core 除非您创建了 MY_Controller.php,它应该是 class Controller extends Controller_Core

    //MY_Controller.php
    class Controller extends Controller_Core
    {
          // overloads Controller_Core::someMethod without us having to change the core file
          public function someMethod(){}
    }
    

    【讨论】:

    • 感谢您抽出宝贵时间对此进行解释。这是非常有帮助的。我现在明白你所说的“静态函数是每个类而不是每个对象”的意思。我将阅读 benlumley 提供的文档,但我仍然对我的代码仍然有效这一事实感到困惑:我在我的问题中附加了一些示例代码,请看一下。再次感谢。
    【解决方案4】:

    我无法添加评论(显然我没有所需的代表!)

    class Forum_Controller extends Controller {
    
    public function __construct()
    {
        parent::__construct();
    }
    
    public function index()
    {
        echo self::categories();
    }
    
    /*
     * get a list of categories from a specific site.
     */
    private static function categories()
    {
        $db = new Database;
    
        // You cannot use $this in a static function, because static functions are per class 
        // and not per object it doesnt know what $this is :)   (make private static $site_id and use self::$site_id) if this is what you want
    
        $categories = $db->query("
                SELECT * FROM
                forum_categories
                WHERE fk_site = '$this->site_id'
        ");
        $view = new View('categories_view');
        $view->categories = $categories;
        return $view;
    }
    

    }

    就像我说的,你应该使用 error_reporting(E_ALL | E_STRICT); (在 kohana 文件中更改它)

    由于 PHP 中的错误,调用私有函数 categories() 静态工作,你不应该这样做:)

    【讨论】:

      【解决方案5】:

      另外需要注意的一点是,制作返回类别列表的静态控制器函数并不是很好的 MVC 设计。

      控制器用于处理请求,模型用于处理数据(就是这样),视图用于显示。

      制作模型!

      class Category_Model extends Model
      {
            public function categories($site_id)
            {
                  $categories = $this->db->from('forum_categories')->where('fk_site',$site_id)->get();
      
                      return new View('categories_view', array('categories' => $categories)); 
            }
      }
      

      ...

      $cat = new Category_Model;
      
      echo $cat->categories(1);
      

      【讨论】:

        【解决方案6】:

        我严格使用 self:: 只用于静态变量和静态成员函数

        【讨论】:

          猜你喜欢
          • 2010-10-07
          • 1970-01-01
          • 2015-05-04
          • 2023-03-18
          • 2017-02-02
          • 1970-01-01
          • 2017-08-22
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多