За последние 24 часа нас посетили 22534 программиста и 1139 роботов. Сейчас ищут 634 программиста ...

как построить цепь ключей для доступа к элементу массива и его изменения

Тема в разделе "Сделайте за меня", создана пользователем Conus, 10 июн 2019.

  1. Conus

    Conus Активный пользователь

    С нами с:
    21 окт 2015
    Сообщения:
    92
    Симпатии:
    0
    И снова Дорого дня всем желающим помочь,
    есть набор ключей для массива $qu 'select action key ey'
    мне надо построить цепочку для доступа к элементу массива и его изменения

    $qu[select][action][key][ey] = 'item'

    Код (Text):
    1.        
    2. $qu['select'] = array("action"=>array("key"=>array('ss', "ey"=>array('second'))));  
    3.        
    4.    $point = explode(" ", 'select action key ey');
    5.                
    6.                
    7.                 foreach($point as $key)
    8.                 {                
    9.                      $qu[$key];
    10.                
    11.                 }
    проблема в том что в следующей акте цикла значение ключа и ссылка на массив уже не совпадают
    первый $qu['select']
    второй $qu['action'] а надо $qu['select']['action']
    надо как то переопределять ссылку на массив и строить цепочку ключей
    если есть идеи или кто либо что либо делал подобное пожалуйста подскажите.
     
  2. Artur_hopf

    Artur_hopf Активный пользователь

    С нами с:
    7 май 2018
    Сообщения:
    2.266
    Симпатии:
    405
    @Conus а смысл новые темы плодить, я вам уже писал ответ, доделать не получилось?
    PHP:
    1. <?php
    2. $qu['select'] = array("action"=>array("key"=>array('ss', "ey"=>array('second'))));
    3. $point = explode(" ", 'select action key ey');
    4.  
    5. function my ($qu, $point){
    6.     foreach($point as $value){
    7.         if(isset($qu[$value])){
    8.             print_r($qu[$value]);
    9.  
    10.             my ($qu[$value], $point);
    11.             break;
    12.         }
    13.     }
    14. }
    15.  
    16. my($qu, $point);
    17. ?>
     
  3. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.751
    Симпатии:
    1.322
    Адрес:
    Лень
  4. Artur_hopf

    Artur_hopf Активный пользователь

    С нами с:
    7 май 2018
    Сообщения:
    2.266
    Симпатии:
    405
    @MouseZver ему я так понял нужно зачем то то что внутри массива.
    --- Добавлено ---
    @Conus можно такую шляпу еще написать =)

    uno :

    PHP:
    1. <?php
    2. $qu['select'] = array("action"=>array("key"=>array('ss', "ey"=>array('second'))));
    3. $point = explode(" ", 'select action key ey');
    4. function my ($qu, $point){
    5.     $i = false;
    6.     foreach($point as $value){
    7.         if(isset($qu[$value])){
    8.             $i = true;
    9.             my ($qu[$value], $point);
    10.             break;
    11.         }
    12.     }
    13.     if($i === false && isset($qu[0])){
    14.         echo $qu[0];
    15.     }
    16. }
    17. my($qu, $point);
    18. ?>
    due :
    PHP:
    1. <?php
    2.  
    3. $qu['select'] = array("action"=>array("key"=>array('ss', "ey"=>array('second'))));
    4.  
    5. $string = 'select action key ey';
    6.  
    7. $b = null;
    8.  
    9. foreach ( explode ( ' ', $string ) AS $i )
    10. {
    11.     $b = $b[$i] ?? $qu[$i];
    12. }
    13.  
    14. if(is_array($b)){
    15.     foreach($b as $value){
    16.         echo $value.'<br>';
    17.     }
    18. }else{
    19.     echo $b;
    20. }
    21. ?>
    оба варианта рабочие
     
    #4 Artur_hopf, 10 июн 2019
    Последнее редактирование: 10 июн 2019
  5. Conus

    Conus Активный пользователь

    С нами с:
    21 окт 2015
    Сообщения:
    92
    Симпатии:
    0
    спасибо
    но а как вы в вашей функции изменяете последний элемент и возвращаете массив
    $qu[select][action][key][ey] = 'item'

    а запрыгнуть в массив и я могу
    Код (Text):
    1.     function point($mass, $m, $NewItem)
    2.             { return 'Array' == ''.$mass
    3.                    ? ('Array' == ''.array_values($mass)[ count($mass)-1 ]
    4.                        ? array_keys($mass)[ count($mass)-1 ] .' ' .$m[array_keys($mass)[ count($mass)-1 ] ].' '
    5.                              .point(array_values($mass)[count($mass)-1], $m[array_keys($mass)[ count($mass)-1 ] ])
    6.                        : '')// array_keys($mass)[ count($mass)-1 ]  )
    7.                    : false; }
     
    #5 Conus, 10 июн 2019
    Последнее редактирование: 10 июн 2019
  6. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.751
    Симпатии:
    1.322
    Адрес:
    Лень
    implode ( <br> ... )
    --- Добавлено ---
    вопрос аналогичен первому посту, на который был дан ответ.
     
  7. Artur_hopf

    Artur_hopf Активный пользователь

    С нами с:
    7 май 2018
    Сообщения:
    2.266
    Симпатии:
    405
    @Conus всмысле изменяю, я просто пробегаюсь по всему массиву.
     
  8. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.072
    Симпатии:
    1.237
    Адрес:
    там-сям
    @Conus цепочка ключей выглядит как-то жутко неудобно. Может тебе подойдет такая адресация: 'first.second.third' ?
    В Laravel, например, так принято адресовать элементы конфигурации. Они доступны как массив произвольной размерности. Если например
    Код (Text):
    1. config() == [
    2.   'alfa' => 10,
    3.   'beta' => [
    4.     'gama' => 20,
    5.     'sigma'=> 30
    6.   ],
    7.   'theta' => 40
    8. ];
    то
    Код (Text):
    1. config('beta') == ['gama' => 20, 'sigma'=> 30]
    а
    Код (Text):
    1. config(beta.sigma') == 30
    ну и т.д.

    Если сам "интерфейс доступа" подходит, то реализацию могу подсказать.
     
  9. Conus

    Conus Активный пользователь

    С нами с:
    21 окт 2015
    Сообщения:
    92
    Симпатии:
    0
    интересно
     
  10. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.072
    Симпатии:
    1.237
    Адрес:
    там-сям
    PHP:
    1. class Config
    2. {
    3.     private $config = [];
    4.  
    5.     public function __construct(array $config)
    6.     {
    7.         $this->config = $config;
    8.     }
    9.  
    10.     public function get($name = null, $default = null)
    11.     {
    12.         if (is_null($name)) {
    13.             return $this->config;
    14.         }
    15.         $segments = explode('.', $name);
    16.         $ptr = & $this->config;
    17.         foreach ($segments as $s) {
    18.             if (!isset($ptr[$s])) {
    19.                 return $default;
    20.             }
    21.             $ptr = & $ptr[$s];
    22.         }
    23.  
    24.         return $ptr;
    25.     }
    26.  
    27.     public function set($name, $value)
    28.     {
    29.         $segments = explode('.', $name);
    30.         $n = count($segments);
    31.         $ptr = & $this->config;
    32.         foreach ($segments as $s) {
    33.             if (--$n) {
    34.                 if (!array_key_exists($s, $ptr)) {
    35.                     $ptr[$s] = [];
    36.                 } elseif (!is_array($ptr[$s])) {
    37.                     throw new \InvalidArgumentException("Scalar \"{$s}\" in the path \"{$name}\"");
    38.                 }
    39.                 $ptr = & $ptr[$s];
    40.             } else {
    41.                 $ptr[$s] = $value;
    42.             }
    43.         }
    44.  
    45.         return $this;
    46.     }
    47. }
    Использование:

    PHP:
    1. $array =
    2. [
    3.   'alfa' => 10,
    4.   'beta' => [
    5.     'gama' => 20,
    6.     'sigma'=> 30
    7.   ],
    8.   'theta' => 40
    9. ];
    10.  
    11. $config = new Config($array);
    12. var_dump($config->get('beta')); // array(2) {  ["gama"]=>  int(20)  ["sigma"]=>  int(30) }
    13. echo "\n";
    14. $config->set('beta.sigma', 1000);
    15. var_dump($config->get()); // array(3) {  ["alfa"]=>  int(10)  ["beta"]=>  array(2) {  ["gama"]=>  int(20)  ["sigma"]=>  int(1000)  }  ["theta"]=>  int(40) }
    16. echo "\n";
     
    MouseZver нравится это.
  11. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.072
    Симпатии:
    1.237
    Адрес:
    там-сям
    Conus получил предупреждение про дублирование темы.
     
  12. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.751
    Симпатии:
    1.322
    Адрес:
    Лень
    @artoodetoo
    PHP:
    1. $a = ['a'=>['b'=>1]];
    2.  
    3. $s = new class( $a )
    4. {
    5.     protected
    6.         $a = [],
    7.         $return = [];
    8.  
    9.     public function __construct ( array $array )
    10.     {
    11.         $this -> a = $array;
    12.     }
    13.  
    14.     public function __get( string $string )
    15.     {
    16.         if ( $this -> return == [] )
    17.         {
    18.             $this -> return = &$this -> a;
    19.         }
    20.      
    21.         if ( is_array ( $this -> return ) && array_key_exists ( $string, $this -> return ) )
    22.         {
    23.             $this -> return = &$this -> return[$string];
    24.          
    25.             return $this;
    26.         }
    27.      
    28.         return null; # либо ошибку кинуть + юзать маг метод isset
    29.    }
    30.  
    31.     public function __set( string $name, $value )
    32.     {
    33.         $this -> return[$name] = $value;
    34.      
    35.         $this -> return = &$this -> a;
    36.     }
    37.  
    38.     public function get()
    39.     {
    40.         $return = $this -> return ?: $this -> a;
    41.      
    42.         $this -> return = &$this -> a;
    43.      
    44.         return $return;
    45.     }
    46. };
    PHP:
    1. $s -> a->b=3;
    2. $s->a->b->get();
    3. $s -> a->b=['c'=>5];
    4. echo $s->a->b->c->get();
     
    Conus нравится это.