Comments 54
Неплохое решение, отшлифовать в реальном приложении до блеска и весьма полезная штука будет.
+2
без подсветки синтаксиса — не оч удобно читать =\
идея понравилась
идея понравилась
+2
З.Ы. А вот когда выйдет релиз PHP5.3, то можно будет добавить к класс Enum метод:
public static method asArray() {}
А что мешает сделать это сейчас?
$ColorReflection = new ReflectionClass("Enum_Colors"); printf("<pre>%s«, print_r($ColorReflection->getConstants(), TRUE));
Array
(
[RED] => F00
[GREEN] => 0F0
[BLUE] => 00F
)
+1
то что такой метод придется писать в каждом классе, а вот с LSB он будет только в родительском
0
а если просто реализовать класс констант без проверки? в чем практический плюс Вашего метода? в создании экземпляра класса? и зачем сравнивать коонстанты класса с константами экземпляря этого же класса?
0
В родительском
$ColorReflection = new ReflectionClass(get_called_class());
0
ну в этом примере тоже есть недостаток, надо создавать объект каждый раз для получения результата
+4
как бы вот проще:
где-то так ;)
final class enum
{
private $something;
public function __construct($val)
{
$this->something = $val;
}
public function eget($index='')
{
if($index=='') return $this->something;
if(! isset($this->something[$index])) return NULL;
return $this->something[$index];
}
}
<?
$array = array(«red»=>«#FF0000», «green»=>«#00FF00», «blue»=>«#0000FF»);
$enum = new enum($array);
echo $enum->eget(«red»);
?>
где-то так ;)
-2
ну первое замечание — что бы использовать значение перечисления в Вашем варианте надо сначала создать объект (new), а затем вызвать метод. Тоесть отпадает вариант простого использования как аргумента:
useMyFunction( new Color_Enum( 'RED' ) );
useMyFunction( new Color_Enum( 'RED' ) );
0
Эээммм, мне тут подумалось, что возможно enum-ы в пхп и не нужны и вполне достаточно констант? Ведь не зря же их не сделали.
Вполне вероятно, что вы пытаетесь «натягивать» функционал и методологию другого языка на пхп, в котором, вероятно, есть другие решения.
Например, я не вполне понимаю, чем вам не нравятся define()? Группировка, как по мне, — это чисто эстетический аргумент, например
enum { fOne, fTwo, fThree };
тоже только эстетически группируется. Проверка типов — это вообще интересно, так как в пхп нет типов в терминах «других» языков, так зачем лепить эти типы, если они не нужны?
В конце-концов не ясно, в чем разница между f(new Enum_Colors( 'GREEN' )) и f('00ff00'). Имхо, ясно одно, что вы на пхп пытаетесь реализовать яву/с++, что, вобщем то, не нужно и вредно ;) А это уже огрехи проектирования либо мышления в рамках языка.
Вполне вероятно, что вы пытаетесь «натягивать» функционал и методологию другого языка на пхп, в котором, вероятно, есть другие решения.
Например, я не вполне понимаю, чем вам не нравятся define()? Группировка, как по мне, — это чисто эстетический аргумент, например
enum { fOne, fTwo, fThree };
тоже только эстетически группируется. Проверка типов — это вообще интересно, так как в пхп нет типов в терминах «других» языков, так зачем лепить эти типы, если они не нужны?
В конце-концов не ясно, в чем разница между f(new Enum_Colors( 'GREEN' )) и f('00ff00'). Имхо, ясно одно, что вы на пхп пытаетесь реализовать яву/с++, что, вобщем то, не нужно и вредно ;) А это уже огрехи проектирования либо мышления в рамках языка.
+7
я люблю type hint'ы, так как с ними проще работать в команде
и именно в этом и отличается f(new Enum_Colors( 'GREEN' )) и f('00ff00'), что я могу указать какой именно параметр будет ожидать функция
з.ы. я, кстати, совершенно не настаиваю на использовании этого довеска, но если кому-то нехватало энумов, то вот решение…
и именно в этом и отличается f(new Enum_Colors( 'GREEN' )) и f('00ff00'), что я могу указать какой именно параметр будет ожидать функция
з.ы. я, кстати, совершенно не настаиваю на использовании этого довеска, но если кому-то нехватало энумов, то вот решение…
+1
Дык я потому и спрашиваю, что бы разъяснить для себя некоторые вещи :)
Видел я похожие решения для перла тоже, в связи с этим у меня возникают вопросы касательно эффективности этих методов. То есть, что эффективнее описать функцию в комментариях к ней либо применять подобные решения? Что эффективнее в контексте исполнения кода? Я так полагаю, что константа работает быстрее, не замедлят ли подобные решения весь код в целом? Я понимаю, что гигагерцы, кластеры и прочее, но как-то всегда стараюсь максимально оптимизировать.
То есть, как бы я хочу разъяснить, не приведет ли повышение эффективности в читабельности к падению эффективности в работе кода?
Видел я похожие решения для перла тоже, в связи с этим у меня возникают вопросы касательно эффективности этих методов. То есть, что эффективнее описать функцию в комментариях к ней либо применять подобные решения? Что эффективнее в контексте исполнения кода? Я так полагаю, что константа работает быстрее, не замедлят ли подобные решения весь код в целом? Я понимаю, что гигагерцы, кластеры и прочее, но как-то всегда стараюсь максимально оптимизировать.
То есть, как бы я хочу разъяснить, не приведет ли повышение эффективности в читабельности к падению эффективности в работе кода?
0
мне кажется что НЕ использовать это решение (если оно Вам таки надо) ради оптимизации производительности, это все равно что использовать echo вместо print (или наоборот?) и одинарные кавычки вместо двойных :)
я готов жертвовать в разумных пределах производительностью в счет удобочитаемости и понимания кода
я готов жертвовать в разумных пределах производительностью в счет удобочитаемости и понимания кода
+1
Дефайны не положишь в нэймспэйсы, а неймспейсы — важный аспект любого ОО-языка. Дефайны из мира С и ПХП 3/4.
+3
я вас умоляю, пхп — это ОО-язык? куда катится мир :(
Может не будет столь поспешны в рамках пхп, а то ява и C# просто удавятся от обиды :-)
Может не будет столь поспешны в рамках пхп, а то ява и C# просто удавятся от обиды :-)
-7
да — PHP ОО язык. Это уже многократно обосновывалось даже тут — на хабре. И попрошу в этой ветке холивары не разводить. Спасибо
-3
займись java(я серьезно), многое станет на свои места. Класс ради класса — это перебор.
-5
ПХП — объектно-ориентированый язык, правда с повсеместными костылями. Ява и До диез — тоже не эталон, это скорее мейнстрим.
0
кстати вот в РНР5.3 перечисления уже и появились :)
0
Про это?
www.php.net/manual/en/class.splenum.php
В частности: «SplEnum gives the ability to emulate and create „Enum“ objects natively in PHP. „
Насколько я понимаю это аналог
class MyEnumType { const A = 0; const B = 1; const C = 3; }
www.php.net/manual/en/class.splenum.php
В частности: «SplEnum gives the ability to emulate and create „Enum“ objects natively in PHP. „
Насколько я понимаю это аналог
class MyEnumType { const A = 0; const B = 1; const C = 3; }
0
Спасибо! Мне понравился ваш вариант.
А ещё можно добавить, что подобное решение известно под названием паттерна Type safe enum.
А ещё можно добавить, что подобное решение известно под названием паттерна Type safe enum.
+1
я своим юниорам по рукам буду бить за такие велосипеды, это усугубление ооп в очень серьезной форме.
-3
class Enum{
const RED = 'F00';
const GREEN = '0F0';
const BLUE = '00F';
} -явная группировка, получается что патерн нужен только для тайпхинтинга :), если это важно — то да.
обсолютно не нужен $class_name = get_class( $this ); так как при try->catche он передается одним из параметров, а иначе вы эту ошибку не словите.
за strtoupper, имхо, надо убивать, т.к. КОНСТАНТЫ И ПЕРЕМЕННЫЕ РЕГИСТРОЗАВИСИМЫ, вы же пишите аналог!
P.S. new Enum_Colors( $param) vs Enum_Colors::{$param}
const RED = 'F00';
const GREEN = '0F0';
const BLUE = '00F';
} -явная группировка, получается что патерн нужен только для тайпхинтинга :), если это важно — то да.
обсолютно не нужен $class_name = get_class( $this ); так как при try->catche он передается одним из параметров, а иначе вы эту ошибку не словите.
за strtoupper, имхо, надо убивать, т.к. КОНСТАНТЫ И ПЕРЕМЕННЫЕ РЕГИСТРОЗАВИСИМЫ, вы же пишите аналог!
P.S. new Enum_Colors( $param) vs Enum_Colors::{$param}
0
Что Вы хотели сказать в «P.S.»?
strtoupper тут необходим был идеологически. Класс этот опенсурс и распространяется as is :)
strtoupper тут необходим был идеологически. Класс этот опенсурс и распространяется as is :)
-3
обсолютно не нужен $class_name = get_class( $this );
Уверены?
0
извините что не в тему, подскажите кто нибудь как узнать колличество потраченной памяти буфера php, или оставшейся
-4
Да, типа ENUM в PHP очень не хватает.
На практике можно использовать например такое решение:
1) Группировка констант в один класс
2) Switch-блок в принимающих методах (он и без того очень часто используется в методах подобного типа) с исключением в блоке default (неизвестный тип)
Если же хочется полноценного контроля типа, то первое, что приходит на ум (но все равно все это костыли):
На практике можно использовать например такое решение:
1) Группировка констант в один класс
2) Switch-блок в принимающих методах (он и без того очень часто используется в методах подобного типа) с исключением в блоке default (неизвестный тип)
Если же хочется полноценного контроля типа, то первое, что приходит на ум (но все равно все это костыли):
<?php abstract class Color { protected $value; public function getValue() { return $this->value; } } final class Color_Red extends Color { protected $value = 'f00'; } ..... ....function setColor(Color $color)
0
прочитайте вот эту ветку с дискуссией на подобные рассуждения
0
лучше тут __toString использовать )
но в этом варианте обращаться напрямую нельзя
но в этом варианте обращаться напрямую нельзя
0
А чем $color->getValue() плохо?
-1
Вы забыли упомянуть, что для использования значения такой константы его нужно принудительно приводить к (string) в нестроковых контекстах.
0
зачем в нестроковых контекстах приводить к строке? может наоборот? если да — тогда за это отвечает метод __toString
0
Для получения значения. Как из вашего енум-контейнера получить конкретное текущее значение? только через __toString, что равнозначно приведению к строке. Вот пример, в данном случае имеем числовой контекст (потому что значения констант — не строки):
Без принудительного приведения в switch() получаем кучу ругани и 'unknown color'. С принудительным приведением в switch и __toString (это еще один момент, php запрещает возвращать из __toString не-строки) — ожидаемый результат.
class Enum_Colors extends Enum { const RED = 0xFF0000; const GREEN = 0x00FF00; const BLUE = 0x0000FF; } function something(Enum_Colors $color) { switch ((string)$color) { case Enum_Colors::RED: echo 'red'; break; case Enum_Colors::BLUE: echo 'blue'; break; case Enum_Colors::GREEN: echo 'green'; break; default: echo 'unknown color'; break; } } something(new Enum_Colors('RED'));
Без принудительного приведения в switch() получаем кучу ругани и 'unknown color'. С принудительным приведением в switch и __toString (это еще один момент, php запрещает возвращать из __toString не-строки) — ожидаемый результат.
0
Как по мне высосано из пальца, если можно быть проще, то надо быть проще. ООП ради ООП.
-1
Это все конечно красиво, но в сложном приложении выльется в множество объектов, которых могло и не быть. Всетаки для PHP, пожалуй, больше подходит старый добрый вариант с интовыми константами (в т.ч. класса).
-1
Беда «волшебных» методов и динамических свойств/констант в том, что нет еще ни одной IDE, которая могла бы их понимать и помогать подстановками. Часто из-за досадной очепятки приходится тратить массу времени на поиск неуловимого глюка. Но идея хорошая.
0
пересматривал старые статьи по пхп. Эта в избравнное — очень хорошее решение с типизацией.
0
Прошло время, но я всё же напишу. Проблема выше перечисленного способа в том, что не будет работает автодополнение. Поэтому предлагаю некоторое изменение.
Таким образом можно будет написать
abstract class Enum {
static public function __callStatic($name, $arguments){
return new static(constant(get_called_class() . '::' . $name)); // не нужно проверять, php сам кинет ошибку.
}
private $current_val;
private function __construct($value) {
$this->current_val = $value;
}
final public function __toString() {
return $this->current_val;
}
}
Таким образом можно будет написать
Enum_Colors::
, выбрать константу и дописать скобочки Enum_Colors::RED();
0
Sign up to leave a comment.
Перечисления в PHP