Как стать автором
Обновить

Комментарии 53

быть может я недалек, но что-то мне подсказывает, что пользование такой "фишкой" только усложнит понимание и сопровождение кода
Я всё ещё опасаюсь в очередной раз с вами спорить, но всё-таки скажу что иногда и это может пригодиться.
P.S. Ох, чувствую, доказать трудно будет :)
Сегодня-завтра опубликую вторую часть - там будет пример использования рассмотрен.
Согласен, похоже на какой-то кошмарик. Почему нельзя просто завести виртуальную функцию, возвращать в ней что надо и переопределять ее в тех классах где это нужно?
Потому что в любая функция по умолчанию виртуальная, и при вызове будет вызываться функция родителя.
в *PHP*
Значит я не допонял - ко второму куску кода отсутствует результат его вывода.
Нет не усложнит, наоборот упростит. Будет тоже самое, что и для динамических методов.
Многие программные модели станет проще реализовывать :)
ну у меня слова "перегрузить", "переопределить", "перекрыть" ассоциируются с методами ...
с константами такие ассоциации никак в голове не укладывается. На то они и константы.

А своих работах я вижу, где за счет этой фишки я могу убрать 5-10 строк кода (заменить геттеры), но делать этого не стану, ибо константа должна быть константой
Почему обязательно константы? Вся соль в том, что непереопределенный родительский метод будет знать, что вызывают его из наследника, а не так как сейчас. Сейчас он думает, что его напрямую вызвали.
честно признаться не понял что вы сказали, скорее всего из-за своей недалекости, но вот последнее предложение у меня вызвало массу эмоций:

>> непереопределенный родительский метод будет знать, что вызывают его из наследника, а не так как сейчас. Сейчас он думает, что его напрямую вызвали.

Один из канонов ООП - инкапсуляция. Ни один метод объекта никогда даже намеком не должен знать откуда его вызвали.
Рассмотрим пример:

Во втором классе Bar переопределена только статическая переменная. Указание $this в методе dyn() позволяет узнать имя класс, без него всегда вернет Foo. В статическом методе ничего подобного реализовать нелья, поэтому необходимо переопределять метод, как в классе Habr. Это вызывает неоторые неудобства. Со статической переменной думаю тоже все понятно.

<?
class Foo {
static $var = 'dima';

function dyn()
{
echo 'Dynamic: ', get_class($this), "\n";
}

static function stat($class=null)
{
if (is_null($class))
{
$class = get_class();
}

echo 'Static: ', $class, "\n";
}

static function stat_var()
{
echo 'Variable: ', self::$var, "\n";
}
}

class Bar extends Foo {
static $var;
}

class Habr extends Foo {
static $var;

static function stat($class=null)
{
parent::stat(get_class());
}
}

$obj = new Bar;
$obj->dyn();

Bar::stat();
Bar::stat_var();

Habr::stat();
?>
Возможно вы правы. Наверное мне следует себя пересилить и принять наконец такие конструкции в коде как "get_class", "фишка static::CONST", и т.д.

но пока удается прожить без этого (возможно лишними усилиями), и я этом рад :-)
Это надо просто знать, не обязательно пихать куда не следует :)
Я привел кусок г..на, которое приходится поддерживать. А вот с выходом 5.3 может получится хотя бы запашок убрать :)
Он не знает, откуда он вызван. Он знает какому классу принадлежит.
Тьфу, ну так это я и имел в виду :)
>>Один из канонов ООП - инкапсуляция. Ни один метод объекта никогда даже намеком не должен знать >>откуда его вызвали.

к инкапсуляции это не имеет ни малейшего отношения
Для товарищей, которые курят нормальные мануалы, программили на ЦПП и шарят в ООД — вряд ли.
Это вовсе не «фишка» — это наконец нормальная реализация, а то обычные методы в PHP всегда виртуальные а статические получается — никогда не виртуальные?
Теперь все работает как ожидалось, а это довольно важно в программировании.
НЛО прилетело и опубликовало эту надпись здесь
Думаю, что сообщество PHP от этого не сильно пострадало.
НЛО прилетело и опубликовало эту надпись здесь
Тут разработчик наш говорит что LSB в CSV уже месяца три.
Там ещё много чего ;) и врядли всё попадёт в релиз 5.3 как правило из-за того что мало тест кейсов.
"зачем-зачем". забыли, например, про паттерн синглтон ?
и при чём тут синглетон?
думаю имелось ввиду нормальное наследование(extends Singletone) и callStatic
да, это и имелось ввиду. не как именно для чего нужно, а как возможное применение.
синглтон прекрасно реализуется и без этого.
реализуется, но не прекрасно.
Возможность конечно клевая, НО она доступна начиная с PHP 5.3.0

А текущая стабильная версия 5.2.5. Когда мы этим всем поспользуемся не очень понятно...
не хватало очень раньше позднего связывания.
раньше приходилось делать через жопу protected static.
кстати почему вы ничего не написали про __callStatic ?
Нужная вещь которой давно не хватало в PHP. Без нее нормальный ORM не сделать. Неполучится красиво написать $user = Users::find($user_id), раньше этого добивались через *опу.
Поясните пожалуйста. Никогда не замечал недостатка этой фичи при реализации ORM. Может, я чего не так делаю? :)
Смотря какой ORM. ActiveRecord например до сих пор полностью нельзя реализовать на PHP, DataAccessObject тоже от чего очень страдают Doctrine ORM и Propel ORM.
Да именно об этом я и говорю.
Спасибо. К сожалению, мой скилл не позволяет пока этого понять :(
Получается, что смысл такой "фичи" в том, чтобы иногда можно было обойтись без перегрузки методов.
Если разбирать чужой код, то перегрузка получается более прозрачной, чем LSB.
Что по вашему лучше? Это?

<?
class DAO {
static function getObjects($class_name=null)
{
$sql = 'SELECT FROM '.$class_name;
}
}

class News extends DAO {
static function getObjects($class_name=null)
{
parent::getObjects(get_class());
}
}

class Faq extends DAO {
static function getObjects($class_name=null)
{
parent::getObjects(get_class());
}
}

$news = News::getObjects();
$faq = Faq::getObjects();
?>


Или это?

<?
class DAO {
static function getObjects()
{
$sql = 'SELECT FROM '.$class_name;
}
}

class News extends DAO {}
class Faq extends DAO {}

$news = News::getObjects();
$faq = Faq::getObjects();
?>


Неужели не прозрачно?
лучше - третий вариант, которого вы не описали

class News extends DAO {
const TABLE_NAME = 'news';
static function getTableName()
{
return self::TABLE_NAME;
}
static function getObjects()
{
parent::getTableObjects(self::getTableName());
}
}
ХАРДКОД!!!
простите, ну это сугубо мое имхо, ваш код - полный ацтой, DorBer - все очень правильно показал. я рад LSB, мне лично это добавит счастья, скорее бы стабильная версия
Честно говоря, кажется костылем.
Вынужденная мера для сохранения BC
С выходом 5.3 все начнут писать абстрактных синглтонов :)
Ой как красиво подмечено!
Три года этот баг в багтракере висит! Ужас.
Это не баг, это - судьба :))
Автору - полегче на поворотах: "и наконец мы его получили в PHP 5.3" - это пока ещё голубая мечта. Фиг знает когда он ещё выйдет. Я уж судорожно на php.net полез проверять :)
О ну наконец-то! Как я в свое время с этим натрахался.
Приходилось жутко хачить через debug_backtrace...
Наконец-то, давно пора, а то статические свойства и методы в PHP вообще слабо развиты. Они бы еще с функциями что-то порешали, local как в перле добавили или позволили бы объявлять, замыкания, хотя на это надеяться не стоит наверное ;)
Ура!! свершилось! как часто приходилось извращаться чтоб решать эти проблеммы! теперь реально многие, очень многие вещи можно будет делать по-человечески! Спасиб огромное автору - отличная новость!
Имхо. думаю что ввод такой константы во времена первого использования будет вызывать лёгкое раздражение при дебажинге, так как перестанешь доверять тому что константа на самом деле и не константа, что повлечёт за собой просмотр родителя каждый раз при наращивании функцивнала через длительный промежуток времени простоя кода.
Вообще-то, это не ООП-style.
Статические члены тем и отличаются от динамических, что принадлежат типу (классу), а не объекту. Поэтому наследование и перекрытие никак не должно на них влиять, это сродни сквозной функциональности.
Наличие же позднего связывания развяжет руки ради мнимой выгоды. "Наследование статических членов"... Не должно такого быть. Как бы красиво это не выглядело.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории