使用$ this,self ::,parent ::代码可读性

时间:2009-07-16 08:28:18

标签: php coding-style kohana

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

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

中没有含糊之处

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

我理解self :: and parent ::引用类的静态实例,但在kohana中,除非你特意将方法定义为static,否则似乎没有区别。

感谢。

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

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()定义为static时才会抛出错误。

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

6 个答案:

答案 0 :(得分:16)

有区别。

$this指的是对象的实例。

parentself用于静态调用方法。

This page of PHP's manual比我现在有时间更详细地解释它。特别是第一个例子应该有助于突出一些差异。我鼓励你复制粘贴第一个例子,然后把它搞得一团糟,因为我觉得如果你还不知道它的区别,它会成为你的一个重要概念。

答案 1 :(得分:6)

控制器在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)(就像在开发期间那样),您将看到引发错误。< / p>

基本上会发生什么:

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(){}
}

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

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

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中的错误而静态工作,您应该无法执行此操作:)

答案 4 :(得分:0)

另外需要注意的是,这不是一个非常好的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);

答案 5 :(得分:0)

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