get_class_var на дочернем классе - PullRequest
       13

get_class_var на дочернем классе

0 голосов
/ 23 сентября 2011

У меня есть следующие настройки:

abstract class AParentLy{
   private $a;
   private $b;

   function foo(){
      foreach(get_class_vars(get_called_class()) as $name => $value){
         echo "$name holds $value";
      }
   }
}

class ChildClass extends AParentLy{
   protected $c='c';
   protected $d='d';
}

$object = new ChildClass();
$object->foo();

То, что я хочу, чтобы это было выведено:

c holds c
d holds d

Что он выводит:

c holds c
d holds d
a holds
b holds

Метод get_called_class () правильно выводит «ChildClass»

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

(Несколько сомнительным решением было бы просто добавить большой микс if ($ name! = 'A' && $ name! = 'B' ... ~ в микс. Но я уверен, что есть должен быть другой, более здравый и стабильный способ сделать это)

Ответы [ 4 ]

1 голос
/ 05 марта 2012

Если бы еще один эксперимент во всем эксперименте, частью которого был этот вопрос.

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

function get_properties(){
    foreach(get_class_vars(get_called_class()) as $name => $value){
        if(!in_array($name,array_keys(get_class_vars('Parent')))){
            $r[$name]=$this->$name;
        }   
    }
    return $r;
}

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

1 голос
/ 23 сентября 2011
class Parent1 {
   //private $a;
   //private $b;

   function foo(){
      foreach(get_object_vars($this) as $name => $value){
         echo "$name holds $value";
      }
   }
}

class Child1 extends Parent1 {
   protected $c='c';
   protected $d='d';
}

Родитель является зарезервированным именем. в классе Parent1 вы можете видеть, что $ a и $ b удалены. изменил $ c / $ c на защищенный.

другое решение будет:

class Parent1 {
   private $a;
   private $b;
}

class Child1 extends Parent1 {
   private $c='c';
   private $d='d';

   function foo(){
      foreach(get_object_vars($this) as $name => $value){
         echo "$name holds $value<br>";
      }
   }
}

кладет foo в Child

EDIT

Извините, что разбудил старый пост. Я думаю, что у меня есть предпочтительное решение (на самом деле 2 решения) для этого: Первый - использовать средний класс, который создаст барьер между родителем и ребенком:

abstract class Parent1 {
    private $a;
    private $b;
    abstract function foo();
}
class ParentClone1 {
    function foo(){
        foreach(get_object_vars($this) as $name => $value){
            echo "$name holds $value<br />";
        }
    }
}

class Child1 extends ParentClone1 {
    protected $c='c';
    protected $d='d';
}
$c = new Child1();
$c->foo();
// c holds c
// d holds d

Другое решение заключается в использовании видимости:

Если вы вызываете get_class_vars () / get_object_vars () из класса, он видит все переменные (включая private / protected). Если вы запустите его извне, он будет виден только публично:

function get_object_vars_global($class){
    return get_object_vars($class);
}
abstract class Parent1 {
    private $a;
    private $b;

    function foo(){
        foreach(get_object_vars_global($this) as $name => $value){
            echo "$name holds $value<br />";
        }
    }

}

class Child1 extends Parent1 {
    public $c='c';
    public $d='d';
}

$c = new Child1();
$c->foo();

, поскольку это приведет к тому, что поля класса станут открытыми, я бы выбрал первое решение.

0 голосов
/ 23 сентября 2011

Измените видимость дочерних свойств на ЗАЩИЩЕННЫЕ.

Когда свойства закрыты, они не видны.

Более подробная информация по адресу:

http://php.net/manual/en/language.oop5.visibility.php

0 голосов
/ 23 сентября 2011

Сначала несколько основных ошибок:

  1. Не используйте $ в имени функции (здесь: $foo), это приведет к синтаксической ошибке.
  2. Вы не должны называть класс Parent, потому что это зарезервированное слово.Вызов этого может привести к ошибке, такой как Неустранимая ошибка: невозможно использовать 'Parent' в качестве имени класса, поскольку оно зарезервировано

Есть хороший пример того, как это работает в php manual , и здесь можно найти это важное предложение, которое отвечает на ваш вопрос:

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

...