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:
class AQL{
/**
* @var array
*/
private $HAYSTACK;
/**
* @var boolean
*/
private $IS_LOADED = false;
/**
* @var integer
*/
private $RETURN_TYPE;
/**
* @var mixed
*/
private $RESULTS;
/**
* @var string
*/
private $DELIMITER = '-';
/**
* @var int
*/
const RETURN_ARRAY = 0;
/**
* @var int
*/
const RETURN_OBJECT = 1;
/**
*
* Creates AQL instance.
* @param array $haystack
* @param int $return_type
* @throws AQLException
*/
public function __construct
(array $haystack, $return_type=AQL
::RETURN_ARRAY){ throw new AQLException('Haystack cannot be empty array.', 101);
}
if(!in_array($return_type, array(AQL
::RETURN_ARRAY, AQL
::RETURN_OBJECT))){ throw new AQLException('Incorrect return type.', 102);
}
$this->RESULTS = array('KEYS'=>null
, 'VALUES'=>null
); $this->HAYSTACK = $haystack;
$this->RETURN_TYPE = $return_type;
$this->IS_LOADED = true;
}
/**
* Returns current return type.
* @return int
*/
public function get_current_return_type(){
return $this->RETURN_TYPE;
}
/**
* Allows to change search result type.
* @param int $return_type
* @throws AQLException
*/
public function change_return_type($return_type){
if(!in_array($return_type, array(AQL
::RETURN_ARRAY, AQL
::RETURN_OBJECT))){ throw new AQLException('Incorrect return type.', 102);
}
$this->RETURN_TYPE = $return_type;
}
/**
* Returns current haystack.
* @return array
*/
public function get_current_haystack(){
return $this->HAYSTACK;
}
/**
* Wipes current haystack.
*/
public function wipe_haystack(){
$this->HAYSTACK = null;
$this->IS_LOADED = false;
}
/**
* Loads new haystack.
* @param array $haystack
* @throws AQLException
*/
public function load_new_haystack
(array $haystack){ throw new AQLException('Haystack cannot be empty array.', 101);
}
$this->HAYSTACK = $haystack;
$this->IS_LOADED = true;
}
/**
* Allows to change delimiter.
* @param $delimiter
* @throws AQLException
*/
public function change_delimiter($delimiter){
throw new AQLException('Delimiter has to be at least a single character string.', 102);
}
$this->DELIMITER = $delimiter;
}
/**
* Returns delimiter
*/
public function get_delimiter(){
}
/**
* Returns results of searching based on query. Values and keys are returned separately in single array/object.
* @param mixed $query
* @return mixed
*/
public function find_element($query){
if($this->RETURN_TYPE == 0
){$this->RESULTS = array('KEYS'=>null
, 'VALUES'=>null
, 'DELIMITER'=>$this->DELIMITER, 'QUERY'=>$query);} if($this->RETURN_TYPE == 1){
$this->RESULTS = new AQLResults();
$this->RESULTS->DELIMITER = $this->DELIMITER;
$this->RESULTS->QUERY = $query;
}
$this->search_in_lvl($query, $this->HAYSTACK, 'ROOT');
return $this->RESULTS;
}
private function search_in_lvl($query, $haystack, $lvl){
foreach($haystack as $k => $v){
$this->search_in_lvl($query, $v, $lvl.$this->DELIMITER.$k);
if($this->RETURN_TYPE == AQL::RETURN_ARRAY){
if($k === $query){
$this->RESULTS['KEYS'][] = $lvl.$this->DELIMITER.$k;
}
}elseif($this->RETURN_TYPE == AQL::RETURN_OBJECT){
if($k === $query){
$key = new AQLKey();
$key->path = $lvl.$this->DELIMITER.$k;
$this->RESULTS->KEYS[] = $key;
}
}
}else{
if($this->RETURN_TYPE == AQL::RETURN_ARRAY){
if($v === $query){
$this->RESULTS['VALUES'][] = $lvl.$this->DELIMITER.$k;
}
if($k === $query){
$this->RESULTS['KEYS'][] = $lvl.$this->DELIMITER.$k;
}
$this->RESULTS['DELIMITER'] = $this->DELIMITER;
$this->RESULTS['QUERY'] = $query;
}elseif($this->RETURN_TYPE == AQL::RETURN_OBJECT){
if($v === $query){
$value = new AQLValue();
$value->path = $lvl.$this->DELIMITER.$k;
$this->RESULTS->VALUES[] = $value;
}
if($k === $query){
$key = new AQLKey();
$key->path = $lvl.$this->DELIMITER.$k;
$this->RESULTS->KEYS[] = $key;
}
}
}
}
}
}
class AQLException extends Exception{
public function __construct($message, $code){
parent::__construct($message, $code);
}
}
class AQLResults{
/**
* @var AQLKey
*/
public $KEYS;
/**
* @var AQLValue
*/
public $VALUES;
/**
* @var string
*/
public $DELIMITER;
/**
* @var string
*/
public $QUERY;
}
class AQLKey{
/**
* @var string
*/
public $path;
}
class AQLValue{
/**
* @var string
*/
public $path;
}
Przykład:
$object = new stdClass();
$object->Kobiety = array(); $object->Mezczyzni = array();
$anna = new stdClass();
$anna->Imie = 'Anna';
$karolina = array('Imie'=>'Karolina');
$object->Kobiety[] = $anna;
$object->Kobiety[] = $karolina;
$tomasz = new stdClass();
$tomasz->Imie = 'Tomasz';
$object->Mezczyzni[] = $tomasz;
$kot = new stdClass();
$kot->Wlasciciel = 133;
$zwierzeta[] = $kot;
$haystack[] = $object;
$haystack[] = $zwierzeta;
$AQL = new AQL($haystack, AQL::RETURN_ARRAY);
print_r($AQL->find_element('Anna')); print_r($AQL->find_element('Imie')); print_r($AQL->find_element('Kobiety'));
Wynik działania:
(
[KEYS] =>
(
[0] => ROOT-0-Kobiety-0-Imie
)
[DELIMITER] => -
[QUERY] => Anna
)
(
(
[0] => ROOT-0-Kobiety-0-Imie
[1] => ROOT-0-Kobiety-1-Imie
[2] => ROOT-0-Mezczyzni-0-Imie
)
[VALUES] =>
[DELIMITER] => -
[QUERY] => Imie
)
(
(
[0] => ROOT-0-Kobiety
)
[VALUES] =>
[DELIMITER] => -
[QUERY] => Kobiety
)
(
(
[0] => ROOT-0-Kobiety-1
[1] => ROOT-1
)
[VALUES] =>
[DELIMITER] => -
[QUERY] => 1
)
Ten post edytował Puszy 9.12.2013, 16:50:44