10

我想知道在 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 会导致歧义,对我来说就是这样。

4

6 回答 6

16

它们是有区别的。

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

parentself用于静态调用方法。

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

于 2009-07-16T08:35:59.747 回答
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)(就像你在开发过程中应该做的那样)你会看到一个错误被引发。

基本上发生的事情是:

核心有一个文件名为:

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(){}
}
于 2009-07-16T10:11:43.923 回答
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 中的错误,调用私有函数 categories() 静态工作,你不应该这样做:)

于 2009-07-16T13:02:20.403 回答
0

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

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

于 2009-07-16T08:34:37.677 回答
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);
于 2009-07-16T13:31:44.330 回答
0

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

于 2009-07-16T13:53:58.560 回答