Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737
Форумы портала PHP.SU :: Цепочка свойств неизвестной длины

 PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи


 Страниц (1): [1]   

> Без описания
Anguis
Отправлено: 04 Февраля, 2016 - 23:25:42
Post Id



Частый гость


Покинул форум
Сообщений всего: 253
Дата рег-ции: Июнь 2012  


Помог: 2 раз(а)




Не понял
Странная задача передо мной стала.
Есть массив, размер может быть разным и заведомо неизвестен. В массиве записаны имена свойств объектов. Надо сделать запрос цепочки:
PHP:
скопировать код в буфер обмена
  1.  
  2. $c = new someClass;
  3. $a = array('prop1','prop2','prop3');
  4.  
  5. //Нужно:
  6. $c->$a[0]->$a[1]->$a[2];
  7.  


Как так сделать прозрачно? Пробовал $c->implode('->',$a); ессно, без результата. На ум идет foreach, но не хочется что то. Не практично foreach, ведь нужна такая конструкция:
PHP:
скопировать код в буфер обмена
  1.  
  2. if($c->$a[0]->$a[1]->$a[2]){
  3. return $c->$a[0]->$a[1]->$a[2];
  4. }else if($b->$a[0]->$a[1]->$a[2]){
  5. return $b->$a[0]->$a[1]->$a[2];
  6. }else{
  7. return 'called undefined property';
  8. }
  9.  


Any ideas?
 
 Top
Viper
Отправлено: 05 Февраля, 2016 - 01:07:05
Post Id



Активный участник


Покинул форум
Сообщений всего: 4555
Дата рег-ции: Февр. 2007  
Откуда: Симферополь


Помог: 98 раз(а)




Anguis пишет:
Странная задача передо мной стала.
не странная, а ошибка в проектировании.
Миллион элементов в массиве приедет, тоже миллион объектов городить будете? Вам там память на серваке не жмёт?


-----
Список фильмов с описанием, блекджеком и... для Joomla? -> https://киноархив[dot]com
Демо нового движка для сайта php.su -> php[dot]su, проект на гитхабе
 
 Top
OrmaJever Модератор
Отправлено: 05 Февраля, 2016 - 01:13:07
Post Id



Активный участник


Покинул форум
Сообщений всего: 7540
Дата рег-ции: Янв. 2010  
Откуда: Чернигов


Помог: 299 раз(а)




вообще есть такое понятие как рекурсия, но Viper прав - беда с проектированием.


-----
Если вы хотя бы 3-4 раза не решите всё выкинуть и начать заново - вы явно что-то делаете не так.
 
 Top
Anguis
Отправлено: 05 Февраля, 2016 - 07:20:20
Post Id



Частый гость


Покинул форум
Сообщений всего: 253
Дата рег-ции: Июнь 2012  


Помог: 2 раз(а)




Ну миллион не приедет, максимум три.
OrmaJever, я в курсе что такое рекурсия, но как её тут применить что то ладу не дам.

Проектирование, кмк, вполне ни чего. Поясню. Есть класс настроек. Есть настройки дефолтные, которые загружаются из файла, а есть настройки пользователя, которые загружаются из базы.
PHP:
скопировать код в буфер обмена
  1.  
  2. $default = new settings;
  3. $default = {'name':'Banners',
  4.                     'group1':{
  5.                                    'banner1':{
  6.                                                     'width':'240',
  7.                                                     'height':'300'
  8.                                                     },
  9.                                    'banner2':{
  10.                                                     'width':'240',
  11.                                                     'height':'300'
  12.                                                     },
  13.                                    'banner3':{
  14.                                                     'width':'240',
  15.                                                     'height':'300'
  16.                                                     }
  17.                                    },
  18.                      'group2':{
  19.                                    'banner1':{
  20.                                                     'width':'240',
  21.                                                     'height':'400'
  22.                                                     },
  23.                                    'banner2':{
  24.                                                     'width':'240',
  25.                                                     'height':'400'
  26.                                                     },
  27.                                    'banner3':{
  28.                                                     'width':'240',
  29.                                                     'height':'400'
  30.                                                     }
  31.                                    }
  32.                     }
  33.  
  34.  
  35. $user = new settings_from_bd;
  36.  
  37. $user = {'name':'Банеры',
  38.                     'group1':{
  39.                                    'banner1':{
  40.                                                     'width':'800',
  41.                                                     'height':'200'
  42.                                                     },
  43.                                    'banner2':{
  44.                                                     'width':'100',
  45.                                                     'height':'100'
  46.                                                     }
  47.                                    },
  48.                      'group2':{
  49.                                    'banner1':{
  50.                                                     'width':'240',
  51.                                                     'height':'300'
  52.                                                     }
  53.                                    }
  54.                     }
  55.  
  56.  


Задача в чем. Запросить нужное свойство сначала из объекта пользовательских настроек, если в он в себе такого не содержит, то запросить ту же цепочку из настроек дефолтных. Собсно, в чем беда то?

В шаблонах я не могу постоянно делать
PHP:
скопировать код в буфер обмена
  1. if($user->group1->banner3->width){
  2. return $user->group1->banner3->width;
  3. }else{
  4. return $default->group1->banner3->width;
  5. }


Поэтому и ищу способ перехватить цепочку запросов и по очереди подставить её сначала к одному объекту, затем к другому. Цепочку в массив записал. Как терь запрос сделать? Что там про рекурсию?

(Отредактировано автором: 05 Февраля, 2016 - 07:20:51)

 
 Top
Viper
Отправлено: 05 Февраля, 2016 - 10:17:30
Post Id



Активный участник


Покинул форум
Сообщений всего: 4555
Дата рег-ции: Февр. 2007  
Откуда: Симферополь


Помог: 98 раз(а)




Anguis вот с этого и надо начинать. Обычно делают настройки юзера пустыми если нет переназначения, тогда и проверять проще. Если нет юзерской настройки, то используем дефолтную.

Циклами проходитесь и сверяете по последнему элементу, т.е. по 'banner1'

PS! Хотя я бы пересмотрел такое хранение настроек. ИМХО неудобно кучу вложенных массивов дро* каждый раз.


-----
Список фильмов с описанием, блекджеком и... для Joomla? -> https://киноархив[dot]com
Демо нового движка для сайта php.su -> php[dot]su, проект на гитхабе
 
 Top
OrmaJever Модератор
Отправлено: 05 Февраля, 2016 - 14:41:20
Post Id



Активный участник


Покинул форум
Сообщений всего: 7540
Дата рег-ции: Янв. 2010  
Откуда: Чернигов


Помог: 299 раз(а)




Anguis пишет:
$c = new someClass;
$a = array('prop1','prop2','prop3');
 
//Нужно:
$c->$a[0]->$a[1]->$a[2];


PHP:
скопировать код в буфер обмена
  1. $a = array('prop1','prop2','prop3');
  2. var_dump( get( $c, $a ) );
  3.  
  4. function get( $obj, &$arr ) {
  5.    $val = current($arr);
  6.    if( is_object($obj->$val) ) {
  7.        next($arr);
  8.        return get($obj->$val, &$arr);
  9.    } else {
  10.        return $obj->$val;
  11.    }
  12. }

не проверял конечно, но как-то так


-----
Если вы хотя бы 3-4 раза не решите всё выкинуть и начать заново - вы явно что-то делаете не так.
 
 Top
DelphinPRO
Отправлено: 05 Февраля, 2016 - 18:12:53
Post Id



Активный участник


Покинул форум
Сообщений всего: 7187
Дата рег-ции: Февр. 2012  


Помог: 353 раз(а)




Почему рекурсивно не объединить два массива?

Берем дефолтный, и переписываем в нем свойства из пользовательского.

Для javascript это стандартный подход. Реализацию слияния можно подсмотреть в том же $.extend() (jQuery)

Хотя что там подсматривать. Просто рекурсивно обойти дефолтный массив, проверяя наличие таких же ключей в пользовательском.

(Отредактировано автором: 05 Февраля, 2016 - 18:13:58)



-----
Чем больше узнаю, тем больше я не знаю.
 
 Top
Anguis
Отправлено: 05 Февраля, 2016 - 18:19:47
Post Id



Частый гость


Покинул форум
Сообщений всего: 253
Дата рег-ции: Июнь 2012  


Помог: 2 раз(а)




DelphinPRO, ну хотя бы потому, что в дефолтном много значений и не все они нужны в каждый конкретный вызов страницы. Обходить 1000 значений из-за используемых 50-ти для текущего вызова мне кажется не рационально..
 
 Top
Viper
Отправлено: 05 Февраля, 2016 - 19:25:27
Post Id



Активный участник


Покинул форум
Сообщений всего: 4555
Дата рег-ции: Февр. 2007  
Откуда: Симферополь


Помог: 98 раз(а)




Anguis пишет:
Обходить 1000 значений из-за используемых 50-ти для текущего вызова мне кажется не рационально..
столько параметров? Не понял Ошибка, ошибка, ошибка


-----
Список фильмов с описанием, блекджеком и... для Joomla? -> https://киноархив[dot]com
Демо нового движка для сайта php.su -> php[dot]su, проект на гитхабе
 
 Top
Anguis
Отправлено: 05 Февраля, 2016 - 19:31:04
Post Id



Частый гость


Покинул форум
Сообщений всего: 253
Дата рег-ции: Июнь 2012  


Помог: 2 раз(а)




Пораскинув тем что осталось в черепной коробке все же пришел к выходу что рекурсивное объединение - единственно верное решение. Иначе не обеспечить прозрачность доступа к свойствам и адекватного возвращения запрашиваемых свойств. Подумалось, а вдруг нужно запросить не финальное свойство, а группу свойств. Т.е. объект. Тут и пришел конец всем рекурсиям, про которые OrmaJever пример давал..
(Добавление)
Viper, я утрировал, не буду же я их пересчитывать Ха-ха
 
 Top
DelphinPRO
Отправлено: 05 Февраля, 2016 - 22:07:50
Post Id



Активный участник


Покинул форум
Сообщений всего: 7187
Дата рег-ции: Февр. 2012  


Помог: 353 раз(а)




Anguis пишет:
Обходить 1000 значений из-за используемых 50-ти для текущего вызова мне кажется не рационально..


Блин... Ну обходите пользовательский массив, и значениями из него переписывайте дефолтные. В программе используйте результирующий массив данных.


-----
Чем больше узнаю, тем больше я не знаю.
 
 Top
MAXUS
Отправлено: 06 Февраля, 2016 - 08:47:12
Post Id


Посетитель


Покинул форум
Сообщений всего: 329
Дата рег-ции: Апр. 2011  


Помог: 7 раз(а)




Anguis пишет:
Задача в чем. Запросить нужное свойство сначала из объекта пользовательских настроек, если в он в себе такого не содержит, то запросить ту же цепочку из настроек дефолтных. Собсно, в чем беда то?


Если я правильно понимаю, то задача слить 2 json объекта, чтобы при этом пользовательские установки перезаписали дефолтные. В чем проблема?

PHP:
скопировать код в буфер обмена
  1.  
  2. $default=array(
  3.         'name'=>'Banners',
  4.         'group1'=>array(
  5.                 'banner1'=>array(
  6.                         'width'=>240,
  7.                         'height'=>300
  8.                 ),
  9.                 'banner2'=>array(
  10.                         'width'=>240,
  11.                         'height'=>300
  12.                 ),
  13.                 'banner3'=>array(
  14.                         'width'=>240,
  15.                         'height'=>300
  16.                 ),
  17.         ),
  18.         'group2'=>array(
  19.                 'banner1'=>array(
  20.                         'width'=>240,
  21.                         'height'=>300
  22.                 ),
  23.                 'banner2'=>array(
  24.                         'width'=>240,
  25.                         'height'=>300
  26.                 ),
  27.                 'banner3'=>array(
  28.                         'width'=>240,
  29.                         'height'=>300
  30.                 ),
  31.         ),
  32. );
  33. $user=array(
  34.         'name'=>'Баннеры',
  35.         'group1'=>array(
  36.                 'banner1'=>array(
  37.                         'width'=>540,
  38.                         'height'=>500
  39.                 ),
  40.                 'banner2'=>array(
  41.                         'width'=>540,
  42.                         'height'=>500
  43.                 ),
  44.                 'banner3'=>array(
  45.                         'width'=>540,
  46.                         'height'=>500
  47.                 ),
  48.         ),
  49. );
  50. $merged=array_merge($default,$user);
  51. var_dump($merged);
  52.  


name и group1 перезапишется. group2 останется дефолтным. Как гонять из json и обратно - это дело техники. Как превратить итог в объект, дак json_decode по умолчанию сделает объект. А надо массив, поставь true на второй аргумент.
 
 Top
OrmaJever Модератор
Отправлено: 06 Февраля, 2016 - 13:21:53
Post Id



Активный участник


Покинул форум
Сообщений всего: 7540
Дата рег-ции: Янв. 2010  
Откуда: Чернигов


Помог: 299 раз(а)




Anguis пишет:
Подумалось, а вдруг нужно запросить не финальное свойство, а группу свойств. Т.е. объект. Тут и пришел конец всем рекурсиям, про которые OrmaJever пример давал..

Почему-же? нужно просто проверять на конец $arr
Например обьект имеет такую цепочку
$c->prop1->prop2->prop3
а в массиве только ['prop1', 'prop2'], поэтому в функции банально нужно проверять результат функции next на false. Если она вернула false значит нужно вернуть текущее значение, даже если это обьект.


-----
Если вы хотя бы 3-4 раза не решите всё выкинуть и начать заново - вы явно что-то делаете не так.
 
 Top
Страниц (1): [1]
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« Объектно-ориентированное программирование »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 



Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB