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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Получение индекса массива через __get 
:(
    Опции темы
Mal Hack
Дата 6.8.2006, 15:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Мудрый...
****


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

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



Сабж заключается в чем. Через __get( $name ) делаем перегрузку, обрабатывая обращение к несуществующим свойствам объекта.
Препдоложим, есть вызов:
$a = $this->LNG['index'].
Свойства LNG в объекте нет. В __get имеем только $name == "LNG". Вопрос заключается в том, как можно получить имя индекса, тобишь "index".
PM ICQ   Вверх
jzZ
Дата 6.8.2006, 17:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата

$this->LNG['index']

Возможно я ошибаюсь, но тут идет обращение к переменной внутри класса, она реализует лишь описание объекта.
метод __get() вызывается при попытке прочитать значение неопределенного свойства.
Кажется правильно будет вызывать несуществующие свойства так:
obj->LNG = "blabla";
т.е. уже после определения самого объекта, а внутри не знаю, хотя может быть LNG это уже переменная к-рой было передано св-во из объекта из другого класса? Ну это лишь мои (возможно неправильные рассуждения), попробуйте конкретней описать ситуацию.
А если речь идет о инициализации неизвестного св-ва по ключу в массиве т.е. так:
Код

obj['index'] = "blabla";

то тут надо воспользоваться интерфейсом ArrayAccess, который поставляется с SPL.

Добавлено @ 17:48 
точное описание ArrayAccess и его методов
PM MAIL   Вверх
Mal Hack
Дата 6.8.2006, 17:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Мудрый...
****


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

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



Цитата(jzZ @  6.8.2006,  18:46 Найти цитируемый пост)
метод __get() вызывается при попытке прочитать значение неопределенного свойства.


Цитата(Mal Hack @  6.8.2006,  16:11 Найти цитируемый пост)
$a = $this->LNG['index'].

Ну как не обращение к несуществующему свойству? LNG через var не описывался.

Цитата(jzZ @  6.8.2006,  18:46 Найти цитируемый пост)
Кажется правильно будет вызывать несуществующие свойства так:
obj->LNG = "blabla";

Это уже __set будет.

PM ICQ   Вверх
jzZ
Дата 6.8.2006, 18:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата

Это уже __set будет.

Это ж только пример, если хотите только __get(), тогда так: $a = obj->LNG;
Я просто хотел показать, что если метод __get() реализован в том же классе, в котором вы обращаетесь к несуществующей переменной LNG, не должен работать. По принципу должен работать, если вы обращаетесь к несуществуещему св-ву  уже самого объекта т.е. так $obj->LNG.

Добавлено @ 18:09 
Цитата

Вопрос заключается в том, как можно получить имя индекса, тобишь "index".

Придется обращаться так $obj[index]; за пределами класса реализующего метод __get()
К сожалению сейчас нет возможности проверить свои слова за php, о пределах действия __get()

Это сообщение отредактировал(а) jzZ - 6.8.2006, 18:09
PM MAIL   Вверх
Mal Hack
Дата 6.8.2006, 18:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Мудрый...
****


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

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



Цитата(jzZ @  6.8.2006,  19:04 Найти цитируемый пост)
Я просто хотел показать, что если метод __get() реализован в том же классе, в котором вы обращаетесь к несуществующей переменной LNG, не должен работать. По принципу должен работать, если вы обращаетесь к несуществуещему св-ву  уже самого объекта т.е. так $obj->LNG.

Ты ошибаешься. __get работает так, как  я описал выше. Это 100% проверенно.

Цитата(jzZ @  6.8.2006,  19:04 Найти цитируемый пост)
Придется обращаться так $obj[index]; за пределами класса реализующего метод __get()

Я через this обращаюсь, и такой синтаксис будет 100% ошибочным.
PM ICQ   Вверх
jzZ
Дата 6.8.2006, 19:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата

Я через this обращаюсь, и такой синтаксис будет 100% ошибочным. 

Невнимательность... Чтобы обращаться как я сказал
Цитата

то тут надо воспользоваться интерфейсом ArrayAccess, который поставляется с SPL.

PM MAIL   Вверх
Mal Hack
Дата 6.8.2006, 19:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Мудрый...
****


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

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



МНе надо все стандартными средствами сделать без лишних телодвижений.
Система переносима должна быть.
PM ICQ   Вверх
jzZ
Дата 6.8.2006, 19:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата

Я просто хотел показать, что если метод __get() реализован в том же классе, в котором вы обращаетесь к несуществующей переменной LNG, не должен работать. По принципу должен работать, если вы обращаетесь к несуществуещему св-ву  уже самого объекта т.е. так $obj->LNG.

Я не ошибаюсь, только что все сам проверил, просто мы не поняли друг друга. Ты говорил о том что и я только другими словами.
Не понимаю чего ты хочешь, сложно сказать без какого-либо кода.
Цитата

Как можно получить имя индекса, тобишь "index". 

Код

class Setter
{
   public $n;
   private $x = array("a" => 1, "b" => 2, "c" => 3);

   private function __get($nm)
   {
       echo "Getting [$nm]\n";

       if (isset($this->x[$nm])) {
           $r = $this->x[$nm];
           print "Returning: $r\n";
           return $r;
       } else {
           echo "Nothing!\n";
       }
   }
}

отсюда: http://ru.php.net/manual/en/language.oop5.overloading.php

Добавлено @ 19:45 
Это если ты имя хочешь получить, а если работать с объектом как с массивом, то только с помощью SPL.
PM MAIL   Вверх
Mal Hack
Дата 6.8.2006, 20:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Мудрый...
****


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

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



Вот по твоему примеру. В $nm я получаю LNG. При вызове
$a = $this->LNG['index']
Массива X у меня нет.
Мне надо вернуть: К примеру
$b->LNG['index']
так вот имя индекса я НЕ МОГУ ПОЛУЧИТЬ.
PM ICQ   Вверх
imm
Дата 6.8.2006, 22:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Код

class CPropChecked implements ArrayAccess
{
//private
   private $m_prop_name = '';
   
//public

   //ArrayAccess interface
   public function offsetExists($offset)
   {
       return TRUE;
   }
   
   public function offsetGet($offset)
   {
       throw new Exception('Undefined index `'.$offset.'` in property `'.$this->m_prop_name.'`!');
   }
   
   public function offsetSet($offset, $value)
   {
   }

   public function offsetUnset($offset)
   {
   }

   //...
   public function __construct($prop_name)
   {
       $this->m_prop_name = $prop_name;
   }
}


class CLoader
{
//private
   private function __get($nm)
   {
       return new CPropChecked($nm);
   }
}


//Implementation


$instance = new CLoader;
try {
    $instance->LNG['index'];
}
catch(Exception $e) {
    print($e);
}

PM MAIL WWW ICQ   Вверх
Mal Hack
Дата 6.8.2006, 22:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Мудрый...
****


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

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



НИчего не понял. Конструктор полуает один параметр, но ты его ниоткуда не передаешь..
ЗЫ: Решить задачу надо через __get или встроенные уже в модель ООП методами.
PM ICQ   Вверх
jzZ
Дата 6.8.2006, 23:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Mal Hack
SPL поставляется вместе php5 он и является стандартным ООП решением, не нужно изобретать колесо, читай ссылку что я дал.
imm привел наглядный пример его реализации.
Цитата

$b->LNG['index']

это ты получишь работая с ArrayAccess, не иначе как.
PM MAIL   Вверх
imm
Дата 6.8.2006, 23:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



В принцепи, подобная ситуация возникать не должна вовсе. Наверняка тебе нужно все классы, для объектов которых, может быть вызван метод LNG неследовать от какого-нибудь базового, в котором этот метод/член определен по умолчанию, или определена реакция на вызов этого члена, а в наследниках уже переопределять.
PM MAIL WWW ICQ   Вверх
Mal Hack
Дата 7.8.2006, 00:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Мудрый...
****


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

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



Ребят, вы меня просто не поняли...
Ладно, обошолся более простым вариантом.
PM ICQ   Вверх
imm
Дата 9.8.2006, 11:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Приношу свои извинения за длительную задержку, но меня твоя проблема очень заинтересовала и я  кой-чего написал. Кстати, если есть дерево (по которому мы будем ходить), то можно с помощью этой концепции реализовать что-то типа SimpleXML (я имею ввиду принцип доступа), вручную (а можно и красивее чем SimpleXML, только гора-а-аздо тяжелее smile)) Лови пример:
Код

//Читалка индексов
class CIndexReader implements ArrayAccess
{
//private
   private $m_member_name;
   private $m_sender_object;
   
   
   //На всякий случай
   private function __get($name)
   {
       throw new Exception('Error! Undefined operation with CIndexReader.'."<br>\n");
   }
   private function __set($name, $value)
   {
       throw new Exception('Error! Undefined operation with CIndexReader.'."<br>\n");
   }
   private function __call($name, $params)
   {
       throw new Exception('Error! Undefined operation with CIndexReader.'."<br>\n");
   }
   
   
//public
   //ArrayAccess interface
   public function offsetExists($offset)
   {
       return TRUE;
   }
   
   public function offsetGet($offset)
   {
       return $this->m_sender_object->getMemberValue($this->m_member_name, $offset);
   }
   
   public function offsetSet($offset, $value)
   {
       $this->m_sender_object->setMemberValue($this->m_member_name, $offset, $value);    
   }
   
   public function offsetUnset($offset)
   {
       $this->m_sender_object->freeMemberValue($this->m_member_name, $offset); 
   }
   
   //...
   
   //Подготавливает читалку индексов
   public function prepare($sender_object, $member_name)
   {
       $this->m_member_name = $member_name;
       $this->m_sender_object = $sender_object;
       return $this;
   }
}




class CLoader
{
//private

   //Members actions interface
   private function __get($name)
   {
       //Если это то свойство, для которого нужен ещё и индекс, то выполняем
       return self::$m_ireader->prepare($this, $name);
   }
   
//public

    //Читалка индексов
    public static $m_ireader;


    //Внутренний интерфейс для читалки индексов
    public function getMemberValue($member_name, $index)
    {
        printf('Вы запросили свойство `%s` с индексом `%s` для чтения.'."<br>\n", $member_name, $index);
        
        //if (ещё уровень индекса)
        //    учесть полученное значение индекса.
        //    ...
        //    return self::$m_ireader; //Продолжаем цепочку индексов
        //else
        return NULL;  //Возвращаем необходимое значение
    }
    
    public function setMemberValue($member_name, $index, $value)
    {
        printf('Вы запросили свойство `%s` с индексом `%s` для записи значения `%s`.'."<br>\n", $member_name, $index, $value);
    }
    
    public function freeMemberValue($member_name, $index)
    {
        printf('Вы запросили свойство `%s` с индексом `%s` для удаления.'."<br>\n", $member_name, $index);
    }
}



class CMyClass extends CLoader
{
//Твой класс
}



//Implementation

//Создаем собственную читалку индексов для всех наследников от CLoader, одной на всех вполне хватит
CLoader::$m_ireader = new CIndexReader;

$instance = new CMyClass;

$instance->LNG['index_1'] = 'value';
$a = $instance->LNG['index_1'];
unset($instance->LNG['index_1']);
//А теперь зло
try {
    $b = $instance->LNG; //в $b записан экземпляр класса CIndexReader
    $b->any_method = 55; //Делаем что-нибудь неправильное и получаем исключение
}
catch (Exception $e) {
    print($e);
}
//А так можно
$b = $instance->LNG;
$a = $b['index_1'];
//А так нельзя, потому как CIndexReader один на всех
$instance_2 = new CMyClass; //Либо любой наследник CLoader
$x = $instance->LNG;
$x2 = $instance_2->LNG;
//Это уже неправильно, потому как $x == $x2, но ошибки не будет, пока...



Это сообщение отредактировал(а) imm - 9.8.2006, 22:13
PM MAIL WWW ICQ   Вверх
Ответ в темуСоздание новой темы Создание опроса

Внимание: данный раздел предназначен для решения сложных, нестандартных задач.

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


 




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


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

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