2011-09-23 163 views
0

我有以下设置:get_class_var儿童类

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中的类继承是相当陌生的,从我能收集的问题出现在如此范围的某个地方。但我无法弄清楚如何使它工作。 (有些可疑的解决方案是继续前进,并添加一个伟大的,如果($ name!='a'& & $ name!='b'... ...到混合中,但我是肯定有必须要做到这一点)

+0

foo函数识别$ a和$ b,因此您会看到它们。父类不知道Child类,所以它不会识别它是私有的。 它不会识别$ c和$ d,因为它们是私人的。 – galchen

+0

即使Child类是最初调用的类吗? 即使没有办法使公共的儿童属性,是否至少有一些方法,使其不承认父母的属性? – someSyl

+0

即使原来的类被调用。如果您将在全球范围内执行此操作,则它也不会识别它们。你可以使$ c/$ d受到保护,尽管 – galchen

回答

1

在整个实验中再次发生这个问题是其中的一部分。

(以防有人绊倒这一点,并有同样的问题),我来到了最终的解决方案是创建父类中的以下方法:

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; 
} 

这样,你让每一个参数(和他们的价值)没有任何父类的子类。如果你改变了类名,你将不得不改变这个函数,但至少对我来说这是一个可行的解决方案。

0

首先,一些基本的错误,另一种更理智和稳定的方式:

  1. 不要在功能名称(这里使用$$foo),这将导致成语法错误
  2. 你不应该命名一个类Parent,因为它是一个保留字。 调用,这将导致到像致命错误的错误:无法使用“父”作为类名称,因为它被保留

有一个很好的例子,它是如何工作的php manual,并有可以发现这重要的句子,它可以回答你的问题:

Class members declared public can be accessed everywhere. Members declared protected can be accessed only within the class itself and by inherited and parent classes. Members declared as private may only be accessed by the class that defines the member.

+0

1.)$ foo是一个打字错误(太习惯在foo前输入$)。但谢谢你指出。 2.)这是一个非常简化的示例代码,包含类和属性名称,便于阅读和理解... – someSyl

+0

可以理解的,当我低咖啡时,总是发生在我身上!但在简化代码时要小心 - 否则试图解决问题的人会分心并解决错误的问题。 – Bjoern

+0

就我所知,这个答案根本没有解决这个问题。 –

1
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。我觉得我有这个一个较好的解决方案(实际上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(); 

因为这将导致类字段公开,我会去第一个解决方案。

+1

在真实代码中令人伤心无法使用,因为$ a和$ b对于课程的其他部分都是绝对需要的。 – someSyl