Используя $this, self::, parent:: для чтения кода

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

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

Является ли 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 (библиотека в кохане).

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

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

Ответ 1

Контроллеры не являются статичными в Kohana, хотя они могут содержать статические переменные-члены/методы или константы.

self:: - сокращенный способ записи ClassName:: i.e

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::, так что нам не нужно вводить полное имя класса (так как это может быть очень долго!)

В ответ на ваш вопрос: No - 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 UNLESS, вы создали 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

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

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

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

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

Ответ 3

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

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

Ответ 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, вы не сможете это сделать:)

Ответ 5

Еще одно замечание, кстати, заключается в том, что это не очень хороший дизайн MVC для создания функций статического контроллера, которые возвращают списки категорий.

Контроллеры предназначены для обработки запросов. Модели предназначены для работы с данными (что и есть), а Views - для отображения.

сделайте модель!

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:: только для статических переменных и статических функций-членов