子类上的 get_class_var

发布于 2024-12-06 06:46:25 字数 725 浏览 1 评论 0 原文

我有以下设置:

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_used_class() 方法正确输出“ChildClass”

我对 PHP 中的类继承相当陌生,从我可以收集到的情况来看,问题出在某处如此范围内。但我不知道如何让它发挥作用。

(有点可疑的解决方案是继续添加一个很大的 if($name!='a' && $name!='b' ...~ 到混合中。但我确信有必须是另一种更理智、更稳定的方式来做到这一点)

I have the following setup:

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();

What I want it to output is:

c holds c
d holds d

What it does output is:

c holds c
d holds d
a holds
b holds

The get_called_class() method correctly outputs "ChildClass"

I'm fairly new to class inheritance in PHP and from what I can gather the problem lies somewhere in the so scope. But I can't figure out how to make it work.

(The somewhat questionable solution would be to just go ahead and add a great big if($name!='a' && $name!='b' ...~ into the mix. But I'm sure there must be another, more sane and stable way to do this)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

红墙和绿瓦 2024-12-13 06:46:26

再次尝试整个实验,这个问题是其中的一部分。

我最终的解决方案(以防万一有人遇到这个问题并遇到同样的问题)是在父类中创建以下方法:

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

通过这个方法,您可以获得子类的每个参数(及其值),而无需任何父类。如果您更改类名,则必须稍微更改该函数,但至少对我来说这是一个可行的解决方案。

Had another go at the whole experiment this question was a part of.

The eventual solution (just in case anyone stumbles over this and has the same problem) I came to was to create the following method within the parent class:

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

with this you get every parameter (and their value) of the child class without any of the parent class. You'll have to change the function a bit if you ever change the class name, but at least for me this was a workable solution.

你的往事 2024-12-13 06:46:26
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';
}

Parent 是保留名称。
在 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

抱歉唤醒旧帖子。我认为我有一个更好的解决方案(实际上有两个解决方案):
第一个是使用中间类,它将在父级和子级之间创建屏障:

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() ,它会看到所有变量(包括私有/受保护)。如果您从外部运行它,它只会看到公共:

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();

因为这将导致将类字段设置为公共,所以我会选择第一个解决方案。

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

Parent is a reserved name.
in class Parent1 you can see $a and $b so removed.
changed $c/$c to protected.

the other solution would be:

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

putting foo in Child

EDIT

Sorry to wake an old post. I think i have a preferable solution (actually 2 solutions) for this:
The first one is to use a middle class that will create a barrier between the parent and the child:

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

The other solution is to use visibility:

If you call get_class_vars()/get_object_vars() from inside a class, it sees all the variables (including private/protected). If you run it from outside it will only see public:

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();

since this will result in putting class fields as public, I'd go with the first solution.

心意如水 2024-12-13 06:46:26

首先是一些基本错误:

  1. 不要在函数名称中使用 $ (此处:$foo),这将导致语法错误。
  2. 您不应该将类命名为 Parent,因为它是保留字。
    调用此函数会导致类似致命错误:无法使用'Parent'作为类名,因为它是保留的之类的错误,

php手册,可以找到这句重要的话,它回答了你的问题:

声明为 public 的类成员可以在任何地方访问。会员
声明为 protected 只能在类本身内访问
继承类和父类。声明为私有的成员只能是
由定义成员的类访问。

First some basic mistakes:

  1. Don't use a $ in a function name (here: $foo), this will result into a syntax error.
  2. You shouldn't name a class Parent, because it is a reserved word.
    Calling this would result into an error like Fatal error: Cannot use 'Parent' as class name as it is reserved

There is a good example how it works in the php manual, and there can be found this important sentence, which answers your question:

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.

最佳男配角 2024-12-13 06:46:25

将子属性的可见性更改为“受保护”。

当属性是私有的时,它是不可见的。

更多信息请访问:

http://php.net/manual/en/language.oop5 .可见性.php

Change the visibility of Child's properties to PROTECTED.

When properties are private, its not visibles.

More info at:

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文