Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
Программирование. Ступени успешной карьеры. Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель PHP 5 / 6 (3 издание). Авторы: Кузнецов М.В., Симдянов И.В. MySQL на примерах. Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель MySQL 5. Авторы: Кузнецов М.В., Симдянов И.В. PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум PHP

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Не передается __get из родительского класса
 
 автор: ДацкыйКот   (12.08.2008 в 13:03)   письмо автору
 
 

В родительском классе имеется метод __get следующего содержания:

    public function __get($propertyName)   {
        if(!property_exists($this, $propertyName))
            exit ("Неверное имя свойства: '$propertyName");
        
        if(method_exists($this, 'get' . $propertyName))
            return call_user_func(array($this, 'get' . $propertyName));
        else
            return $this->$propertyName;    
    }


Пробую обратиться к закрытым членам класса-наследника:
echo $Object->_var;


Метод __get() подхватывается в классе-наследнике, но судя по всему, ищет член класса "_var" в родительском классе. В итоге отрабатывается ветка
if(!property_exists($this, $propertyName))
, т.е. этот член не виден..

Что делать?

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

  Ответить  
 
 автор: Axxil   (12.08.2008 в 13:14)   письмо автору
 
   для: ДацкыйКот   (12.08.2008 в 13:03)
 

Пробую обратиться к закрытым членам класса-наследника: 

это зачем? На от они и закрытые, что б к ним извне не обращались. Только по $this

Задачу на пальцах объясните. Может подругому спроектировать можно.

  Ответить  
 
 автор: ДацкыйКот   (12.08.2008 в 13:17)   письмо автору
 
   для: Axxil   (12.08.2008 в 13:14)
 

Насколько я понимаю, рекомендуется те члены, к которым нужен доступ извне делать закрытыми и обращаться к ним через методы типа getVar или __get, что здесь и реализуется.

  Ответить  
 
 автор: Axxil   (12.08.2008 в 13:24)   письмо автору
 
   для: ДацкыйКот   (12.08.2008 в 13:17)
 

Вообще-то рекомендуется вообще не обращаться с свойствами напрямую. Только через set и get методы.
Обычно в конструкциях вида echo $object->var или $object->var = 1; нет смысла.
Они легко заменяются на echo $obect->getVar(); $object->setVar(1);

  Ответить  
 
 автор: ДацкыйКот   (12.08.2008 в 13:21)   письмо автору
 
   для: Axxil   (12.08.2008 в 13:14)
 

Задача на пальцах...

Есть методы __get и __set (как описано в посте) и назревают еще несколько методов, которые будут реализовываться в нескольких классах.
Можно конечно копировать их в каждый класс, но хотелось сделать красиво - придумать класс-родитель с повторяющимися методами и наследовать от него...

  Ответить  
 
 автор: Axxil   (12.08.2008 в 13:26)   письмо автору
 
   для: ДацкыйКот   (12.08.2008 в 13:21)
 

ну и сделайте в классе родителе эти методы protected, а их инициализацию поручите set методам.

  Ответить  
 
 автор: ДацкыйКот   (12.08.2008 в 13:31)   письмо автору
 
   для: Axxil   (12.08.2008 в 13:26)
 

а поподробнее можно? сделал Protected в классе родителе:

protected function __get($propertyName)   {


а что теперь в наследниках сделать?
вот такой код в наследнике не работает:

    public function __get($propertyName)    {
        parent::__get($propertyName);
    }    

  Ответить  
 
 автор: Axxil   (12.08.2008 в 13:38)   письмо автору
 
   для: ДацкыйКот   (12.08.2008 в 13:31)
 

я не про то.
<?
class parent_class{
  protected 
$property1;
  protected 
$property2;

  public function 
setProperty1($val){
    
$this->property1 $val;
  }
  public function 
setProperty2($val){
    
$this->property2 $val;
  }
}

class 
child extends parent_class{
  public function 
useProperty1(){
    return 
$this->property1 1
  }
}

$foo = new child;
$foo->setProperty1(5);
echo 
$foo->useProperty1();
?>

  Ответить  
 
 автор: ДацкыйКот   (12.08.2008 в 13:45)   письмо автору
 
   для: Axxil   (12.08.2008 в 13:38)
 

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

какая-то кривая получается архитектура.. хотелось бы, чтобы в родителе были только свойства, которые будут присутствовать во всех наследниках..

у меня просто в одном наследнике 11 свойств.. во втором 7.. неужто их теперь придется все в родителя толкать? а при появлении нового наследника опять править родителя? %(

  Ответить  
 
 автор: Axxil   (12.08.2008 в 13:50)   письмо автору
 
   для: ДацкыйКот   (12.08.2008 в 13:45)
 

в родителя надо пихать только общие для всех наследников свойства.
И если при появлении нового потомка могут появится новые свойства у родителя, то проект классов (как правило) кривой. Обычно сверху вниз проектируется. Сначала прописывают абстрактные классы и интерфейсы, а потом уже детальную реализацию.

  Ответить  
 
 автор: ДацкыйКот   (12.08.2008 в 14:03)   письмо автору
 
   для: Axxil   (12.08.2008 в 13:50)
 

ок.. в теории поняли друг друга..

теперь к практике...

class Entity {

   private $_Id;

   // Методы доступа
    protected function __get($propertyName)   {
            if(!property_exists($this, $propertyName))
            exit ("Неверное имя свойства: '$propertyName'");
        
        if(method_exists($this, 'get' . $propertyName))
            return call_user_func(array($this, 'get' . $propertyName));
        else
            return $this->$propertyName;    
    }
    ... // Тут же и метод __set
}

class Sample extends Entity{
   
   private $_var1;
   private $_var2;

    public function __construct()    {
        $this->_var1 = 123;
        $this->_var2 = "текст";
    }        
}

$Object = new Sample( );

echo $Object->_var1;


Вобщем вот... в наследнике есть 2 закрытых члена класса, к которым нужно получить доступ методами __get и __set, которые прописаны в родителе.. А пхп начинает искать эти члены в классе-родителя и соответственно выдает ошибку...

  Ответить  
 
 автор: Axxil   (12.08.2008 в 14:09)   письмо автору
 
   для: ДацкыйКот   (12.08.2008 в 14:03)
 

private свойства доступны исключительно в пределах данного класса. И из родителя они не доступны.
если их сделать protected то всё заработает.

class Sample extends Entity{
   
   protected $_var1;
   protected $_var2; 

  Ответить  
 
 автор: ДацкыйКот   (12.08.2008 в 14:15)   письмо автору
 
   для: Axxil   (12.08.2008 в 14:09)
 

пуфф... круто!!!! спасибо большое, получилось...
кажется толегу пора снова засесть за основы теории ))

  Ответить  
 
 автор: Axxil   (12.08.2008 в 13:50)   письмо автору
 
   для: ДацкыйКот   (12.08.2008 в 13:45)
 

-

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования