Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [class] Klasa przeszukująca tablice i obiekty
Forum PHP.pl > Inne > Oceny
Puszy
Witam,

jest to mój pierwszy skrypt poddany ocenie użytkowników portalu forum.php.pl.

Skrypt powstał w wyniku mojej frustracji oraz nieudolności w odnalezieniu podobnej klasy.

Klasa przeszukuje tablice oraz obiekty w celu odnalezienia podanych wartości. Przeszukuje wartości jak również indeksy tablicy wielowymiarowej. Zdaję sobie sprawę że klasa nie jest demonem wydajności, lecz w moim przypadku znajduje swoje zastosowanie. Proszę o ocenę składni, funkcjonalności oraz wydajności. Jeżeli podobna klasa istnieje i jest zaawansowana proszę o ocenę kodu pod względem czytelności, stylu i wydajności. Jestem otwarty na wszelką krytykę. Pozdrawiam

Klasy:
  1. class AQL{
  2.  
  3. /**
  4. * @var array
  5. */
  6. private $HAYSTACK;
  7.  
  8. /**
  9. * @var boolean
  10. */
  11. private $IS_LOADED = false;
  12.  
  13. /**
  14. * @var integer
  15. */
  16. private $RETURN_TYPE;
  17.  
  18. /**
  19. * @var mixed
  20. */
  21. private $RESULTS;
  22.  
  23. /**
  24. * @var string
  25. */
  26. private $DELIMITER = '-';
  27.  
  28. /**
  29. * @var int
  30. */
  31. const RETURN_ARRAY = 0;
  32.  
  33. /**
  34. * @var int
  35. */
  36. const RETURN_OBJECT = 1;
  37.  
  38. /**
  39. *
  40. * Creates AQL instance.
  41. * @param array $haystack
  42. * @param int $return_type
  43. * @throws AQLException
  44. */
  45. public function __construct(array $haystack, $return_type=AQL::RETURN_ARRAY){
  46. if(count($haystack)<1){
  47. throw new AQLException('Haystack cannot be empty array.', 101);
  48. }
  49.  
  50. if(!in_array($return_type, array(AQL::RETURN_ARRAY, AQL::RETURN_OBJECT))){
  51. throw new AQLException('Incorrect return type.', 102);
  52. }
  53.  
  54. $this->RESULTS = array('KEYS'=>null, 'VALUES'=>null);
  55. $this->HAYSTACK = $haystack;
  56. $this->RETURN_TYPE = $return_type;
  57. $this->IS_LOADED = true;
  58. }
  59.  
  60. /**
  61. * Returns current return type.
  62. * @return int
  63. */
  64. public function get_current_return_type(){
  65. return $this->RETURN_TYPE;
  66. }
  67.  
  68. /**
  69. * Allows to change search result type.
  70. * @param int $return_type
  71. * @throws AQLException
  72. */
  73. public function change_return_type($return_type){
  74. if(!in_array($return_type, array(AQL::RETURN_ARRAY, AQL::RETURN_OBJECT))){
  75. throw new AQLException('Incorrect return type.', 102);
  76. }
  77.  
  78. $this->RETURN_TYPE = $return_type;
  79. }
  80.  
  81. /**
  82. * Returns current haystack.
  83. * @return array
  84. */
  85. public function get_current_haystack(){
  86. return $this->HAYSTACK;
  87. }
  88.  
  89. /**
  90. * Wipes current haystack.
  91. */
  92. public function wipe_haystack(){
  93. $this->HAYSTACK = null;
  94. $this->IS_LOADED = false;
  95. }
  96.  
  97. /**
  98. * Loads new haystack.
  99. * @param array $haystack
  100. * @throws AQLException
  101. */
  102. public function load_new_haystack(array $haystack){
  103. if(count($haystack)<1){
  104. throw new AQLException('Haystack cannot be empty array.', 101);
  105. }
  106.  
  107. $this->HAYSTACK = $haystack;
  108. $this->IS_LOADED = true;
  109. }
  110.  
  111. /**
  112. * Allows to change delimiter.
  113. * @param $delimiter
  114. * @throws AQLException
  115. */
  116. public function change_delimiter($delimiter){
  117. if(!is_string($delimiter) || strlen($delimiter) < 1){
  118. throw new AQLException('Delimiter has to be at least a single character string.', 102);
  119. }
  120.  
  121. $this->DELIMITER = $delimiter;
  122. }
  123.  
  124. /**
  125. * Returns delimiter
  126. */
  127. public function get_delimiter(){
  128.  
  129. }
  130.  
  131. /**
  132. * Returns results of searching based on query. Values and keys are returned separately in single array/object.
  133. * @param mixed $query
  134. * @return mixed
  135. */
  136. public function find_element($query){
  137.  
  138. if($this->RETURN_TYPE == 0){$this->RESULTS = array('KEYS'=>null, 'VALUES'=>null, 'DELIMITER'=>$this->DELIMITER, 'QUERY'=>$query);}
  139. if($this->RETURN_TYPE == 1){
  140. $this->RESULTS = new AQLResults();
  141. $this->RESULTS->DELIMITER = $this->DELIMITER;
  142. $this->RESULTS->QUERY = $query;
  143. }
  144.  
  145. $this->search_in_lvl($query, $this->HAYSTACK, 'ROOT');
  146. return $this->RESULTS;
  147. }
  148.  
  149. private function search_in_lvl($query, $haystack, $lvl){
  150. foreach($haystack as $k => $v){
  151.  
  152. if(is_array($v) || is_object($v)){
  153.  
  154. $this->search_in_lvl($query, $v, $lvl.$this->DELIMITER.$k);
  155.  
  156. if($this->RETURN_TYPE == AQL::RETURN_ARRAY){
  157. if($k === $query){
  158. $this->RESULTS['KEYS'][] = $lvl.$this->DELIMITER.$k;
  159. }
  160. }elseif($this->RETURN_TYPE == AQL::RETURN_OBJECT){
  161. if($k === $query){
  162. $key = new AQLKey();
  163. $key->path = $lvl.$this->DELIMITER.$k;
  164.  
  165. $this->RESULTS->KEYS[] = $key;
  166. }
  167. }
  168.  
  169. }else{
  170.  
  171. if($this->RETURN_TYPE == AQL::RETURN_ARRAY){
  172.  
  173. if($v === $query){
  174. $this->RESULTS['VALUES'][] = $lvl.$this->DELIMITER.$k;
  175. }
  176.  
  177. if($k === $query){
  178. $this->RESULTS['KEYS'][] = $lvl.$this->DELIMITER.$k;
  179. }
  180.  
  181. $this->RESULTS['DELIMITER'] = $this->DELIMITER;
  182. $this->RESULTS['QUERY'] = $query;
  183.  
  184. }elseif($this->RETURN_TYPE == AQL::RETURN_OBJECT){
  185.  
  186. if($v === $query){
  187. $value = new AQLValue();
  188. $value->path = $lvl.$this->DELIMITER.$k;
  189.  
  190. $this->RESULTS->VALUES[] = $value;
  191. }
  192.  
  193. if($k === $query){
  194. $key = new AQLKey();
  195. $key->path = $lvl.$this->DELIMITER.$k;
  196.  
  197. $this->RESULTS->KEYS[] = $key;
  198. }
  199.  
  200. }
  201. }
  202. }
  203. }
  204. }
  205.  
  206. class AQLException extends Exception{
  207.  
  208. public function __construct($message, $code){
  209. parent::__construct($message, $code);
  210. }
  211. }
  212.  
  213. class AQLResults{
  214. /**
  215. * @var AQLKey
  216. */
  217. public $KEYS;
  218.  
  219. /**
  220. * @var AQLValue
  221. */
  222. public $VALUES;
  223.  
  224. /**
  225. * @var string
  226. */
  227. public $DELIMITER;
  228.  
  229. /**
  230. * @var string
  231. */
  232. public $QUERY;
  233. }
  234.  
  235. class AQLKey{
  236. /**
  237. * @var string
  238. */
  239. public $path;
  240. }
  241.  
  242. class AQLValue{
  243. /**
  244. * @var string
  245. */
  246. public $path;
  247. }


Przykład:
  1. $haystack = array();
  2.  
  3. $object = new stdClass();
  4. $object->Kobiety = array();
  5. $object->Mezczyzni = array();
  6.  
  7. $anna = new stdClass();
  8. $anna->Imie = 'Anna';
  9.  
  10. $karolina = array('Imie'=>'Karolina');
  11.  
  12. $object->Kobiety[] = $anna;
  13. $object->Kobiety[] = $karolina;
  14.  
  15. $tomasz = new stdClass();
  16. $tomasz->Imie = 'Tomasz';
  17.  
  18. $object->Mezczyzni[] = $tomasz;
  19.  
  20. $kot = new stdClass();
  21. $kot->Wlasciciel = 133;
  22.  
  23. $zwierzeta = array();
  24. $zwierzeta[] = $kot;
  25.  
  26. $haystack[] = $object;
  27. $haystack[] = $zwierzeta;
  28.  
  29. $AQL = new AQL($haystack, AQL::RETURN_ARRAY);
  30. print_r($AQL->find_element('Anna'));
  31. print_r($AQL->find_element('Imie'));
  32. print_r($AQL->find_element('Kobiety'));
  33. print_r($AQL->find_element(1));

Wynik działania:
  1. (
  2. [KEYS] =>
  3. [VALUES] => Array
  4. (
  5. [0] => ROOT-0-Kobiety-0-Imie
  6. )
  7.  
  8. [DELIMITER] => -
  9. [QUERY] => Anna
  10. )
  11. (
  12. [KEYS] => Array
  13. (
  14. [0] => ROOT-0-Kobiety-0-Imie
  15. [1] => ROOT-0-Kobiety-1-Imie
  16. [2] => ROOT-0-Mezczyzni-0-Imie
  17. )
  18.  
  19. [VALUES] =>
  20. [DELIMITER] => -
  21. [QUERY] => Imie
  22. )
  23. (
  24. [KEYS] => Array
  25. (
  26. [0] => ROOT-0-Kobiety
  27. )
  28.  
  29. [VALUES] =>
  30. [DELIMITER] => -
  31. [QUERY] => Kobiety
  32. )
  33. (
  34. [KEYS] => Array
  35. (
  36. [0] => ROOT-0-Kobiety-1
  37. [1] => ROOT-1
  38. )
  39.  
  40. [VALUES] =>
  41. [DELIMITER] => -
  42. [QUERY] => 1
  43. )
buliq
Nazwy metod/parametrów które nie są public powinny być poprzedzone _, łatwiej się czyta kod wiedząc że coś jest niedostępne z zewnątrz.
Dodatkowo przyjęło się że stałe piszemy WIELKIMI literami, nie zmienne.
Sprawdź co to jest CamelCase.
Sprawdź co to jest PSR.

Linia 50, jesteś pewien że dla 2 rodzajów jest to szybsze rozwiązanie niż zwykły warunek z && ?
Dlaczego twoje Exceptions zwracają nikomu nie znane kody? Lepiej byłoby gdybyś używał stałych klasy AQLException
Metoda get_delimiter pusta.

Nie rozumiem założeń twojej klasy. Dlaczego chciałbyś abym korzystał z twojego kodu, skoro w momencie kiedy potrzebuję jakiejś wartości mogę to obsłużyć jedną funkcją? Jeżeli chcę sprawdzić czy jakaś wartość jest w tablicy mam wbudowane metody do iteracji/filtrowania.
Co zrobisz z tą ścieżką? I jak? Nie wiesz przecież czy to obiekt czy tablica.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.