Использование $ this, self ::, parent :: для удобства чтения кода - PullRequest
10 голосов
/ 16 июля 2009

Я хотел бы знать, допустимо ли / предпочтительнее ли использовать self :: method () и parent :: method () при работе в классах php.

Вы можете использовать $ this-> method (), но $ this-> также может ссылаться на переменную класса, переменную родительского класса или метод из родительского класса. В себе нет двусмысленности ::

Является ли self :: амортизируемым и / или есть какие-либо предостережения или недостатки в использовании этого стиля?

Я понимаю, что self :: и parent :: ссылаются на статический экземпляр класса, но в кохане, если только вы не определите метод как статический, похоже, нет никакой разницы.

Спасибо.

Добавлен пример: Предполагая, что это приложение хранит форумы с нескольких веб-сайтов ...

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;
    }

}

Этот пример работает в кохане с установленным значением отчета об ошибках: сообщение об ошибке (E_ALL & ~ E_STRICT);

$ this-> site_id определен в основном классе Controller_Core (библиотека в кохане).

Насколько я знаю, $ this не должен быть доступен, так как я вызываю self :: Categories () статическим способом, но только когда я определяю category () как статический, он выдает ошибку.

Но, как я уже сказал, я скорее предпочитаю использовать self ::, поскольку с точки зрения читабельности я точно знаю, где должна быть эта функция, а не использование $ this, которое вызывает у меня двусмысленность.

Ответы [ 6 ]

16 голосов
/ 16 июля 2009

Есть разница.

$this относится к экземпляру объекта.

parent и self используются для статического вызова методов.

Эта страница руководства PHP объясняет это более подробно, чем я успеваю написать в данный момент. В частности, первый пример должен помочь выделить некоторые различия. Я призываю вас скопировать и вставить первый пример и поэкспериментировать с ним, поскольку я думаю, что это важная концепция, о которой вы должны подумать, если вы еще не знаете разницу.

6 голосов
/ 16 июля 2009

Контроллеры не являются статичными в 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 читайте ниже для получения дополнительной информации ...).

p.s статический вызов нестатических методов - это неправильно и не должен быть разрешен - если вы установите 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(){}
}
0 голосов
/ 16 июля 2009

Я строго использую self :: only для статических переменных и статических функций-членов

0 голосов
/ 16 июля 2009

Кстати, стоит отметить, что это не очень хороший дизайн 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);
0 голосов
/ 16 июля 2009

Я не могу добавить комментарий (очевидно, у меня нет нужного представителя!)

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); (измените его в файле кохана)

вызов категорий закрытой функции () статически работает из-за ошибки в PHP, вы не должны этого делать:)

0 голосов
/ 16 июля 2009

Я думаю, что self :: обычно используется для статических функций и свойств.

Я использую Kohana, и, возможно, контроллеры сделаны статичными.

...