Модераторы: skyboy, MoLeX, Aliance, ksnk
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Затруднения с символическими ссылками в классах 
:(
    Опции темы
1234ru
  Дата 27.2.2010, 17:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 39
Регистрация: 26.8.2007

Репутация: -1
Всего: -1



Затруднения с символическими ссылками в классах

Перед одним из методов класса стоит задача вернуть значение переменной по переданной ему строке.
Строка вида 'key1.key2.key3' соответствует переменной $this->objectarray[key1][key2][key3].

Код для этого я написал следующий (символические ссылки я использовал, чтобы не делать каждый раз копию массива):

Код

function var_value($varname_string) {
    $var = &$this->objectarray;
    $keys = explode('.', $varname_string);
    foreach ($keys as $key) {
        if (isset($var[$key])) { $var = &$var[$key]; }
        else { $var = FALSE; break; }
    }
    return $var;
}


При попытке выполнить $this->var_value('строка') мне выдается ошибка:
Цитата
Cannot create references to/from string offsets nor overloaded objects


Подскажите, в чем тут дело.

(я вообще в классах не силён; может быть, код для такой задачи можно написать более грамотно?)
PM MAIL   Вверх
1234ru
Дата 27.2.2010, 18:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 39
Регистрация: 26.8.2007

Репутация: -1
Всего: -1



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

Работает только код вида
Код
foreach ($keys as $key) {
    $var = $var[$key];
}


Если заменить $var = $var[$key] на $var = &$var[$key] - ошибка.

Не хочется каждый раз полную копию делать (чтобы не тратить зря ресурсы). Можно ли как-нибудь без этого обойтись? 
PM MAIL   Вверх
IZ@TOP
Дата 1.3.2010, 12:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Панда-бир!
****


Профиль
Группа: Участник
Сообщений: 4795
Регистрация: 3.2.2003
Где: Бамбуковый лес

Репутация: 44
Всего: 73



Если Вы используете PHP 5, копия массива не будет создана пока Вы не попробуете изменить данные в одном из массивов.


--------------------
Один из розовых плюшевых-всадников апокалипсиса... очень злой...

Семь кругов ада для новых элементов языка
Мои разрозненные мысли
PM MAIL WWW ICQ Skype GTalk   Вверх
Sentox
Дата 1.3.2010, 23:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


как то так
**


Профиль
Группа: Участник
Сообщений: 392
Регистрация: 27.1.2009
Где: Зимбабве

Репутация: 7
Всего: 7



А почему сразу целевой элемент не определять?
Код

if(isset($var[$keys[0]][$keys[1]][$keys[2]]))
{
    return true;
}

как вариант использовать цикл не foreach а for с  предопределённым количеством элементов в массиве count($keys), соответственно и вложенность.

Это сообщение отредактировал(а) Sentox - 1.3.2010, 23:31
PM MAIL   Вверх
IZ@TOP
Дата 2.3.2010, 14:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Панда-бир!
****


Профиль
Группа: Участник
Сообщений: 4795
Регистрация: 3.2.2003
Где: Бамбуковый лес

Репутация: 44
Всего: 73



Sentox, а почему головой нельзя подумать? Вложенность динамическая, от 1 до N.


--------------------
Один из розовых плюшевых-всадников апокалипсиса... очень злой...

Семь кругов ада для новых элементов языка
Мои разрозненные мысли
PM MAIL WWW ICQ Skype GTalk   Вверх
Sentox
Дата 2.3.2010, 15:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


как то так
**


Профиль
Группа: Участник
Сообщений: 392
Регистрация: 27.1.2009
Где: Зимбабве

Репутация: 7
Всего: 7



Цитата(IZ@TOP @ 2.3.2010,  14:07)
Sentox, а почему головой нельзя подумать? Вложенность динамическая, от 1 до N.

Читайте мой пост до конца ... 
Вложенность определяется только количеством элементов в маccиве после explode.
Хорошо подумайте и посмотрите что возращает функция.
В любом случае функция стремиться проверить целевой элемент, какой бы вложенности он не был, так как при не нахождении возращает FALSE!


Это сообщение отредактировал(а) Sentox - 2.3.2010, 15:58
PM MAIL   Вверх
IZ@TOP
Дата 2.3.2010, 18:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Панда-бир!
****


Профиль
Группа: Участник
Сообщений: 4795
Регистрация: 3.2.2003
Где: Бамбуковый лес

Репутация: 44
Всего: 73



Функция возвращает или значение элемента массива или ложь.

Цитата(Sentox @  2.3.2010,  16:45 Найти цитируемый пост)
В любом случае функция стремиться проверить целевой элемент

Что такое целевой элемент? Можно на примере ? И еще мне не совсем понятно, зачем использовать цикл for.


--------------------
Один из розовых плюшевых-всадников апокалипсиса... очень злой...

Семь кругов ада для новых элементов языка
Мои разрозненные мысли
PM MAIL WWW ICQ Skype GTalk   Вверх
Sentox
Дата 2.3.2010, 19:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


как то так
**


Профиль
Группа: Участник
Сообщений: 392
Регистрация: 27.1.2009
Где: Зимбабве

Репутация: 7
Всего: 7



Элемент массива, цель которого выбрать или проверить.
Код

if(isset($var[$keys[0]][$keys[1]][$keys[2]]))
{
    return true;
}

Можно впринципе и не for, просто нужно сделать указатель на элемент.
PM MAIL   Вверх
1234ru
Дата 2.3.2010, 22:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 39
Регистрация: 26.8.2007

Репутация: -1
Всего: -1



Цитата
Если Вы используете PHP 5, копия массива не будет создана пока Вы не попробуете изменить данные в одном из массивов. 
Вот это ценная информация. Не знал.

А вообще вы знаете... Почему-то такой код вдруг заработал (честно, не знаю почему; сам голову ломаю).
Все-таки так можно (в смысле, так, как в первом посте было написано).
PM MAIL   Вверх
Sentox
Дата 4.3.2010, 00:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


как то так
**


Профиль
Группа: Участник
Сообщений: 392
Регистрация: 27.1.2009
Где: Зимбабве

Репутация: 7
Всего: 7



Точно говорил один из модераторов сперва учи мануал!

Это сообщение отредактировал(а) Sentox - 4.3.2010, 00:46
PM MAIL   Вверх
IZ@TOP
Дата 4.3.2010, 15:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Панда-бир!
****


Профиль
Группа: Участник
Сообщений: 4795
Регистрация: 3.2.2003
Где: Бамбуковый лес

Репутация: 44
Всего: 73



Цитата(Sentox @  2.3.2010,  20:13 Найти цитируемый пост)
Элемент массива, цель которого выбрать или проверить.
    
Код

if(isset($var[$keys[0]][$keys[1]][$keys[2]]))
{
    return true;
}


 

Мы не знаем вложенность которую нам надо проверить. Если нам надо пройти до сотого уровня массива, вы предлагаете такой мегагигантский if писать? Может вообще switch(count) { if1... if100} ?


--------------------
Один из розовых плюшевых-всадников апокалипсиса... очень злой...

Семь кругов ада для новых элементов языка
Мои разрозненные мысли
PM MAIL WWW ICQ Skype GTalk   Вверх
Sentox
Дата 4.3.2010, 23:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


как то так
**


Профиль
Группа: Участник
Сообщений: 392
Регистрация: 27.1.2009
Где: Зимбабве

Репутация: 7
Всего: 7



Если элемента $var[$keys[0]][$keys[1]][$keys[2]]) нет то и вложенности поочерёдно определять смысла не имеет, так как функция сразу обрывается и возращает FALSE.
Цель функции вернуть последний элемент или FALSE.
Вложенности можно сформировать перед тем как проверить ОДИН раз:
Код

function var_value($varname_string) 
{
    $var = &$this->objectarray;
    $keys = explode('.', $varname_string);
    foreach ($keys as $key) {
        $var = &$var[$key]; 
    }

    if (isset($var)) 
    { 
        return $var;
    } 
        
    return FALSE;
}


Это сообщение отредактировал(а) Sentox - 4.3.2010, 23:53
PM MAIL   Вверх
IZ@TOP
Дата 5.3.2010, 10:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Панда-бир!
****


Профиль
Группа: Участник
Сообщений: 4795
Регистрация: 3.2.2003
Где: Бамбуковый лес

Репутация: 44
Всего: 73



Sentox, по-моему тут с логикой явные проблемы. Для того, что бы проверить последний элемент, нужно проверить существование родительских элементов, цепочка которых может быть неопределенной вложенности. Посему, ну никак нельзя делать проверку isset($var[$keys[0]][$keys[1]][$keys[2]]). Впрочем, это можно сделать эвалом, но, имхо, необходимо реализовать задачу без использования костылей и с наименьшей затратой ресурсов.

Приведенный тобой код вообще даже разбирать не стоит, поскольку с него сразу посыпется куча нотисов и стриктов. Автором уже была приведена правильная реализация задачи, поэтому не вижу необходимости выдумывать что-то свое, к тому же еще и кривое, совершенно не понимая как устроен внутренний мир PHP.


--------------------
Один из розовых плюшевых-всадников апокалипсиса... очень злой...

Семь кругов ада для новых элементов языка
Мои разрозненные мысли
PM MAIL WWW ICQ Skype GTalk   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "PHP"
Aliance
IZ@TOP
skyboy
SamDark
MoLeX

Новичкам:

  • PHP редакторы собираются и обсуждаются здесь
  • Электронные книги по PHP, документацию можно найти здесь
  • Интерпретатор PHP, полную документацию можно скачать на PHP.NET

Важно:

  • Не брезгуйте пользоваться тегами [code=php]КОД[/code] для повышения читабельности текста/кода.
  • Перед созданием новой темы воспользуйтесь поиском и загляните в FAQ
  • Действия модераторов можно обсудить здесь

Внимание:

  • Темы "ищу скрипт", "подскажите скрипт" и т.п. будут переноситься в форум "Web-технологии"
  • Темы с именами: "Срочно", "помогите", "не знаю как делать" будут УДАЛЯТЬСЯ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, IZ@TOP, skyboy, SamDark, MoLeX, awers.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0606 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.