Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Enumerator w PHP
batman
post
Post #1





Grupa: Moderatorzy
Postów: 2 921
Pomógł: 269
Dołączył: 11.08.2005
Skąd: 127.0.0.1




Oddaję dzisiaj pod waszą ocenę klasę enumeratora, którego tak bardzo mi brakuje w PHP (SplEnum to jakieś nieporozumienie). Jak sama nazwa wskazuje jet to standardowy typ wyliczeniowy, zaimplementowany w PHP.

Kod klasy
  1. namespace Batman;
  2.  
  3. abstract class Enum
  4. {
  5. private static $_consts = null;
  6.  
  7. final public function __construct()
  8. {
  9. throw new \ErrorException('Can\'t create object from enum');
  10. }
  11.  
  12. final static private function getConstants()
  13. {
  14. if(self::$_consts === null) {
  15. $class = get_called_class();
  16. if($class == __CLASS__) {
  17. throw new \BadMethodCallException('You can\'t access constants from Enum class');
  18. }
  19. $reflection = new \ReflectionClass($class);
  20. self::$_consts = $reflection->getConstants();
  21. }
  22. return self::$_consts;
  23. }
  24.  
  25. final static public function getNames()
  26. {
  27. return array_keys(self::getConstants());
  28. }
  29.  
  30. final static public function getValues()
  31. {
  32. return array_values(self::getConstants());
  33. }
  34. }


Przykład użycia
  1. class UserStatus extends \Batman\Enum
  2. {
  3. const DELETED = -1;
  4. const BLOCKED = 0;
  5. const ACTIVE = 1;
  6. }


Download, issue tracker i całą resztę znajdziecie na githubie.
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 7)
hwao
post
Post #2


Developer


Grupa: Moderatorzy
Postów: 2 844
Pomógł: 20
Dołączył: 25.11.2003
Skąd: Olkusz




Sam kod jest bardzo ładnie napisany, dlatego też nie spodziewam się w tym temacie za dużego ruchu. Także muszę się poczepiać żeby napisać cokolwiek (IMG:style_emoticons/default/smile.gif)

[PHP] test1.php - pobierz, plaintext
  1. <?php
  2.  
  3. include './Enum.php';
  4.  
  5. class UserStatus extends \Batman\Enum
  6. {
  7. const DELETED = 'ble';
  8. const BLOCKED = 0;
  9. const ACTIVE = 1;
  10. }
[PHP] test1.php - pobierz, plaintext


Można ustawić jako string, raczej nie powinno się dopuszczać do takiej możliwości.

[PHP] test2.php - pobierz, plaintext
  1. <?php
  2.  
  3. include './Enum.php';
  4.  
  5. class UserStatus extends \Batman\Enum
  6. {
  7. const DELETED = 'ble';
  8. const BLOCKED = 0;
  9. const ACTIVE = 1;
  10. }
  11.  
  12. var_dump( UserStatus::DELETED );
  13. var_dump( UserStatus::getNames() );
  14. var_dump( UserStatus::getValues() );
[PHP] test2.php - pobierz, plaintext


Są 2 metody, przydała by mi się jeszcze 3 która zwraca mi Wartość (Values) => Nazwa (Names)
Lub metoda, która z Value poda mi Name:

[PHP] test3.php - pobierz, plaintext
  1. $mUserStatus = \UserStatus::DELETED;
  2.  
  3. var_dump( $mUserStatus );
  4.  
  5. echo 'User status: '.$mUserStatus;
[PHP] test3.php - pobierz, plaintext


Żeby po uruchomieniu jakiejś metody z parametrem $mUserStatus był output:
Kod
User status: DELETED
Go to the top of the page
+Quote Post
batman
post
Post #3





Grupa: Moderatorzy
Postów: 2 921
Pomógł: 269
Dołączył: 11.08.2005
Skąd: 127.0.0.1




Cytat
Można ustawić jako string, raczej nie powinno się dopuszczać do takiej możliwości.
Niestety PHP nie daje możliwości wymuszenia typu prostego. Ale w momencie korzystania z refleksji będę mógł dodać sprawdzenie typu.

Cytat
Są 2 metody, przydała by mi się jeszcze 3 która zwraca mi Wartość (Values) => Nazwa (Names)
Lub metoda, która z Value poda mi Name:
Pojawi się metoda toArray i prawdopodobnie iterator.

Cytat
Żeby po uruchomieniu jakiejś metody z parametrem $mUserStatus był output:
Kod
User status: DELETED
Dobry pomysł. Nie potrzebowałem takiej funkcjonalności, ale na pewno się przyda.
Go to the top of the page
+Quote Post
Bags_Bunny
post
Post #4





Grupa: Zarejestrowani
Postów: 262
Pomógł: 39
Dołączył: 12.04.2004

Ostrzeżenie: (0%)
-----


  1. class EnumTest1 extends \Batman\Enum
  2. {
  3. const foo = 1;
  4. }
  5.  
  6. class EnumTest2 extends \Batman\Enum
  7. {
  8. const bar = 1;
  9. }
  10.  
  11. print_r( EnumTest1::getNames() ); //foo
  12. print_r( EnumTest2::getNames() ); //foo (!)
Go to the top of the page
+Quote Post
Speedy
post
Post #5





Grupa: Zarejestrowani
Postów: 651
Pomógł: 28
Dołączył: 4.12.2004

Ostrzeżenie: (0%)
-----


Gdzie wykorzystujesz tę klasę? Czy jest ona tak naprawdę potrzebna w PHP, czy to raczej sztuka dla sztuki? Czy odpowiednia implementacja interfejsu Iterator lub IteratorAggregate nie byłaby wystarczająca?
Go to the top of the page
+Quote Post
batman
post
Post #6





Grupa: Moderatorzy
Postów: 2 921
Pomógł: 269
Dołączył: 11.08.2005
Skąd: 127.0.0.1




@Bags_Bunny
Dzięki za znalezienie tego babola. Poprawione.

@Speedy
Równie dobrze sztuką dla sztuki można nazwać interfejsy lub klasy abstrakcyjne. Wymienione przez Ciebie iteratory służą do czegoś zupełnie innego. Zadaniem typu wyliczeniowego jest zebranie w jednym miejscu podobnych do siebie danych. Najlepszym przykładem będą tutaj dni tygodnia lub miesiące. Tworząc typ wyliczeniowy, w kodzie posługujemy się czytelnymi dla ludzi nazwami, natomiast aplikacja otrzymuje liczbę. W ten sposób nie zaśmiecamy klas/konfiguracji zbędnymi informacjami.
Go to the top of the page
+Quote Post
Speedy
post
Post #7





Grupa: Zarejestrowani
Postów: 651
Pomógł: 28
Dołączył: 4.12.2004

Ostrzeżenie: (0%)
-----


Klasy abstrakcyjne i interfejsy akurat są przydatne. Enumeratory mamy też dostępne jako typ pola w tabelach bazy danych, a aplikacje internetowe prawie zawsze bazy wykorzystują, więc można z tego korzystać, choć ja i tak wolę tworzyć sobie tabele słownikowe, bo projekt jest wtedy bardziej czytelny i elastyczny.
Go to the top of the page
+Quote Post
batman
post
Post #8





Grupa: Moderatorzy
Postów: 2 921
Pomógł: 269
Dołączył: 11.08.2005
Skąd: 127.0.0.1




@Speedy
Nie można polegać na zewnętrznych mechanizmach. Co z tego, że baza danych posiada pole typu enum. A jeśli będziemy korzystali z MongoDB lub chmury? Tam nie ma czegoś takiego jak enum.
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 4.10.2025 - 12:23