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