self или static?

brone

Новичок
В PHP 5.3 появилась возможность вызова статических методов своего класса через ключевое слово static. Раньше для этих целей использовали слово self, но static обладает явным преимуществом перед self, т.к. позволяет статическим свойствам прозрачно наследоваться.

Приемлемо ли вообще забыть про self и использовать static по умолчанию для вызова статических методов/свойств внутри класса? Совместимость со старыми PHP не нужна, но волнует вопрос производительности, гибкости и вообще правильности подхода.
 

Духовность™

Продвинутый новичок
ИМХО static нужно использовать и не пытаться его заменять на self. Хотя бы для того, что бы в процессе работы не появлялось непонимание того, является ли член класса Late Static Bindings или это обычный статический член класса. Фактически это более приемлемо с точки зрения визуального восприятия кода.
 

cDLEON

Онанист РНРСlub
static не подойдёт для приватных статических свойств и методов.
 

brone

Новичок
static не подойдёт для приватных статических свойств и методов.
Согласно Zend PHP Coding Standard, приватных статических свойств и методов вообще быть не должно, да и вообще, необходимость их использования представялется сомнительной.
В любом случае, для них можно использовать self, если есть такая необходимость. Вопрос в том, что использовать по умолчанию, когда функциональной разницы нет.

Я посмотрел код последнего Zend Framework, там в большинстве случаев используется self, и только очень редко (видимо, по необходимости) static. Почему так? Ведь static удобнее для наследования?
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
давайте отойдем на шаг и ответим на более общий вопрос:
зачем Вам статический класс? почему не объект, не набор функций?
 

brone

Новичок
давайте отойдем на шаг и ответим на более общий вопрос:
зачем Вам статический класс? почему не объект, не набор функций?
Для возможности наследования, например.
Статическим может быть не весь класс, а только некоторые свойства или методы, которые может возникнуть необходимость перекрыть в дальнейшем.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
давай без "например", без сферических абстракций
код в студию плз, что ты наследуешь и зачем :)
статический метод в одном классе с обычными уместен только в синглтоне, но синглтон - уже не есть хорошо
 

AmdY

Пью пиво
Команда форума
brone
статика должна быть сквозной, по сути это не OOП, а эмуляция нэймспейсов в php для несвязанных мусорных функций-тулз. Соответственно, наследование здесь смысла не имеет.
static - это костыль, который закрывает относительно тяжёлое порождение объектов и добавляет синтаксического сахара в виде более простого доступа Foo::doMethodFromFoo() . может когда-нибудь появится (new Foo())->doMethodFromFoo().
 

tz-lom

Продвинутый новичок
AmdY
патчи на эту фичу уже были предложены вроде как,есть надежда что уже в 5.3.4 будет
 

cDLEON

Онанист РНРСlub
Согласно Zend PHP Coding Standard, приватных статических свойств и методов вообще быть не должно, да и вообще, необходимость их использования представялется сомнительной.
В любом случае, для них можно использовать self, если есть такая необходимость. Вопрос в том, что использовать по умолчанию, когда функциональной разницы нет.

Я посмотрел код последнего Zend Framework, там в большинстве случаев используется self, и только очень редко (видимо, по необходимости) static. Почему так? Ведь static удобнее для наследования?
Спасибо, кэп.
Использую self только там, где мне нужно обращение к свойствам и методам этого же класса. (Случаи с приватными методами и переменными). В остальных случаях - static.
 

brone

Новичок
давай без "например", без сферических абстракций
код в студию плз, что ты наследуешь и зачем :)
статический метод в одном классе с обычными уместен только в синглтоне, но синглтон - уже не есть хорошо
brone
статика должна быть сквозной, по сути это не OOП, а эмуляция нэймспейсов в php для несвязанных мусорных функций-тулз. Соответственно, наследование здесь смысла не имеет.
static - это костыль, который закрывает относительно тяжёлое порождение объектов и добавляет синтаксического сахара в виде более простого доступа Foo::doMethodFromFoo() . может когда-нибудь появится (new Foo())->doMethodFromFoo().
Статичные методы в нестатичных классах в некоторых случаях очень удобно использовать для создания и инициализации экземпляра класса. Привожу конкретный пример:

PHP:
// Есть базовый класс:

class Template {
	
	public static function instance($filename)
	{
		$engine = static::detect_engine($filename);
		$class_name = ucfirst($engine) . '_Template';
		$instance = new $class_name();
		$instance->load($filename);
		
		return $instance; 
	}

	protected static function detect_engine($filename) { /* ... */ }
	
	public function load($filename) { /* ... */ }
	
	public function render($data) {}
}

// Есть несколько классов-потомков, перекрывающих метод render

class Smarty_Template extends Template {
	
	public function render($data) { /* ... */ }
}

class Xsl_Template extends Template {
	
	public function render($data) { /* ... */ }
}

// Удобное использование. Нам не надо заботиться о правильном названии класса, мы вызываем класс Template,
// а получаем экземпляр класса-наследника, соответствущего передаваемым параметрам

Template::instance($filename)->render($data);
Наследование статических методов здесь имеет смысл, потому что мы можем заходеть перекрыть методы instance или detect_engine в наследниках.
 

HraKK

Мудак
Команда форума
brone
Ты открыл синглетон? При том что синлетон дурной тон. Так что не катит.
 

phprus

Moderator
Команда форума
HraKK
Почему это синглтон? Это больше на Фабричный метод похоже, который по параметру создает экземпляр конкретного класса с интерфейсом Template.

Хотя лучше было бы отдельно выделить Фабрику, а отдельно задекларировать интерфейс Template, а не смешивать их в одном классе.
 

Mols

Новичок
Парни... я не хочу показаться занудой... но хотелось бы всё таки уточнить почему
...синлетон дурной тон
Например эдесь
пишут так

Patterns are ways to describe best practices and good designs. They show a flexible solution to common programming problems.
Собсно и синглтон там представлен.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
мы можем заходеть перекрыть методы instance или detect_engine в наследниках.
для тех, кто в танке :) реальный код в студию, где тебе реально надо переопределить статику.
Переопределение инициализатора фабрики - очень странная идея, которая приведет к неожиданным проблемам.

phprus
это смесь фабрики с регистром без кеширования :)
ни рыба ни мясо - изобретаем паттерны
 

phprus

Moderator
Команда форума
Patterns are ways to describe best practices and good designs. They show a flexible solution to common programming problems.
Собсно и синглтон там представлен.
Тут написано, что паттерны это хорошая практика хорошей архитектуры. Они показывают гибкие, обобщенные решения часто встречающихся проблем программирования.
Про то, что какие-то паттерны лучше, а какие-то хуже тут ничего не говориться. Синглтон не очень хороший паттерн так как увеличивает связность кода (в местах получения экземпляра требуется прописывать имя класса).

grigori
Да, согласен.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
>почему ...синлетон дурной тон

Я бы уточнил, что синглтон пришел из джавы и С. Есть ситуации, в которых синглтон необходим.
Пример - многопоточные приложения. Синглтон используется для синхронизации/обмена между потоками, и замены ему нет.
Другой случай - active templates, когда хочется использовать одно подключение к БД в разных модулях, а центрального места для создания соединения нет.
Но у синглтонов есть недостатки, которые появляются при изменении условий работы приложения.
Синглтон усложняет масштабируемость и заставляет переписывать все, что с ним связано, когда, например, внезапно оказывается, что надо работать с 2мя разными базами.
Почитай, например, http://insidecpp.ru/patterns/singleton/

В php нет многопоточности, нет application server-ов, нет активных шаблонов, нет много чего.
А вот недостатки синглтонов при изменении требований появляются всегда.
 
Сверху