Доброго времени суток, хабражители!
В своей статье я хочу поговорить об обработке многомерных ассоциативных массивов в PHP. На мой взгляд, не всегда удобно получать необходимую информацию из многомерного массива. Одно дело если массив двумерный:
То, конечно, получить, интересующие нас значения, легко:
Но, а если мы имеем массив n-мерный? Например, пятимерный:
То, чтобы получить значение по ключу, например, «value1», нам надо прописать такой код:
Я такую запись не назвал бы красивой, хотя она является правильной. Я предлагаю слегка сделать эту запись красивой путем приведения ее к такому виду:
Согласитесь, ведь смотрится, действительно, куда симпотичней, по сравнению со стандартной записью.
Итак, для начала нам понадобится создать класс, который будет обрабатывать наш массив. Назовем его easyArray и сделаем его одиночкой (Singleton):
После того, как наш класс стал одиночкой, добавим ему весьма важный метод, который будет записывать полученный массив в приватную переменную:
Ну а теперь мы переопределим магический метод "__get()" нашего класса. Это необходимо для того, чтобы получить желаемый нами результат. Итак:
И, как последний штрих нашего класса, добавим метод, который будет возвращать текущий массив, с которым работает наш класс:
Итак, наш класс готов, но чтобы получить значения, теперь мы должны использовать такой код:
Стало даже длиннее, чем было. Но эта проблема решаема, и для этого нам понадобится простая функция:
Ну, а теперь проверим, что мы получили в итоге:
Помимо этого, данному классу можно передавать конфигурационные файлы типа:
Для этого необходимо использовать такую конструкцию:
Возможно я изобрел велосипед, но я думаю, что данная статья будет интересна, как новичкам, так и остальным программистам.
Ссылки на файлы:
Файлы на GitHub.
Спасибо за внимание.
В своей статье я хочу поговорить об обработке многомерных ассоциативных массивов в PHP. На мой взгляд, не всегда удобно получать необходимую информацию из многомерного массива. Одно дело если массив двумерный:
<?
$array = array(
"dimension1" => array(
"key1" => "value1",
"key2" => "value2"
)
);
?>
То, конечно, получить, интересующие нас значения, легко:
echo $array['dimension1']['key1']; // value1
Но, а если мы имеем массив n-мерный? Например, пятимерный:
$array = array(
'dimension1' => array(
'dimension2' => array(
'dimension3' => array(
'dimension4' => array(
'dimension5' => array(
'value1' => 'Hey! I\'m value1',
'value2' => 'Hey! I\'m value2'
)
)
)
)
)
);
То, чтобы получить значение по ключу, например, «value1», нам надо прописать такой код:
echo $array["dimension1"]["dimension2"]["dimension3"]["dimension4"]["dimension5"]["value1"]; // Hey! I'm value1
Я такую запись не назвал бы красивой, хотя она является правильной. Я предлагаю слегка сделать эту запись красивой путем приведения ее к такому виду:
echo easyA($array)->dimension1->dimension2->dimension3->dimension4->dimension5->value1; // Hey! I'm value1
Согласитесь, ведь смотрится, действительно, куда симпотичней, по сравнению со стандартной записью.
Итак, для начала нам понадобится создать класс, который будет обрабатывать наш массив. Назовем его easyArray и сделаем его одиночкой (Singleton):
Код
class easyArray{
private static $instance; // Состояние класса.
private $Array; // Массив, который был передан классу.
private function __construct(){
// Запилили конструктор.
}
private function __clone(){
// Запилили метод клонирования.
}
public static function getInstance(){
if(null === self::$instance){
self::$instance = new self();
}
return self::$instance;
}
После того, как наш класс стал одиночкой, добавим ему весьма важный метод, который будет записывать полученный массив в приватную переменную:
Код
Из кода видно, что мы также осуществляем проверку того, что было передано на вход метода. В случае того, если был передан все-таки не массив, мы просто выбросим исключение с ошибкой "К сожалению вы передали не массив.". Если проверка прошла успешно, то мы записываем в приватную переменную полученный массив и возвращаем текущий объект.
public function loadArray($newArray){
if(is_array($newArray)){
$this->Array = $newArray;
return $this;
}else{
$error = 'К сожалению вы передали не массив.';
throw new Exception($error);
}
}
Из кода видно, что мы также осуществляем проверку того, что было передано на вход метода. В случае того, если был передан все-таки не массив, мы просто выбросим исключение с ошибкой "К сожалению вы передали не массив.". Если проверка прошла успешно, то мы записываем в приватную переменную полученный массив и возвращаем текущий объект.
Ну а теперь мы переопределим магический метод "__get()" нашего класса. Это необходимо для того, чтобы получить желаемый нами результат. Итак:
Код
Первым делом, мы проверяем наличие запрошенного ключа в массиве, в случае отсутствия такового, выбрасываем исключение с ошибкой "'Отсутствует ключ ('.$index.') в массиве'". Далее проверяем является ли, запрошенный ключ массивом. Если по такому ключу в массиве находится значение, то просто возвращаем это значение. А если все-таки это массив, то мы отправляем его методу "loadArray($newArray)" и возвращаем текущий объект ($this).
public function __get($index){
if(isset($this->Array[$index])){
if(is_array($this->Array[$index])){
$this->loadArray($this->Array[$index]);
return $this;
}else{
return $this->Array[$index];
}
}else{
$error = 'Отсутствует ключ ('.$index.') в массиве';
throw new Exception($error);
}
}
Первым делом, мы проверяем наличие запрошенного ключа в массиве, в случае отсутствия такового, выбрасываем исключение с ошибкой "'Отсутствует ключ ('.$index.') в массиве'". Далее проверяем является ли, запрошенный ключ массивом. Если по такому ключу в массиве находится значение, то просто возвращаем это значение. А если все-таки это массив, то мы отправляем его методу "loadArray($newArray)" и возвращаем текущий объект ($this).
И, как последний штрих нашего класса, добавим метод, который будет возвращать текущий массив, с которым работает наш класс:
Код
public function arrayReturn(){
return $this->Array;
}
Итак, наш класс готов, но чтобы получить значения, теперь мы должны использовать такой код:
echo easyArray::getInstance()->loadArray($array)->dimension1->dimension2->dimension3->dimension4->dimension5->value1; // Hey! I'm value1
Стало даже длиннее, чем было. Но эта проблема решаема, и для этого нам понадобится простая функция:
function easyA($newArray){
return easyArray::getInstance()->loadArray($newArray);
}
Ну, а теперь проверим, что мы получили в итоге:
Код
Все работает, как и задумывалось.
<?
$array = array(
'dimension1' => array(
'dimension2' => array(
'dimension3' => array(
'dimension4' => array(
'dimension5' => array(
'value1' => 'Hey! I\'m value1',
'value2' => 'Hey! I\'m value2'
)
)
)
)
)
);
require_once('easyArray.php');
require_once('easyArrayFunction.php');
echo easyA($array)->dimension1->dimension2->dimension3->dimension4->dimension5->value1; // Hey! I\'m value1
echo easyA($array)->dimension1->dimension2->dimension3->dimension4->dimension5->value2; // Hey! I\'m value2
?>
Все работает, как и задумывалось.
Помимо этого, данному классу можно передавать конфигурационные файлы типа:
Код
<?
return array(
'dimension1' => array(
'dimension2' => array(
'dimension3' => array(
'dimension4' => array(
'dimension5' => array(
'value1' => 'Hey! I\'m value1 from file array.php',
'value2' => 'Hey! I\'m value2 from file array.php'
)
)
)
)
)
);
?>
Для этого необходимо использовать такую конструкцию:
Код
echo easyA(require_once('array.php'))->dimension1->dimension2->dimension3->dimension4->dimension5->value1; // Hey! I'm value1 from file array.php
Возможно я изобрел велосипед, но я думаю, что данная статья будет интересна, как новичкам, так и остальным программистам.
Ссылки на файлы:
Файлы на GitHub.
Спасибо за внимание.