'Determine if a variable only belongs to a child class in PHP

I have a parent class and a child class. Through a function in the parent class, I am looping through the members of the class and setting values for each of them. However, when I iterate through the class members, I do so for ALL members (those of the parent and child class) like so:

In Parent Class:

foreach($this as $member_name => $member_value) {
 if(property_exists(get_class($this),$member_name) && isset($member_value))
     //do something....
}//end foreach

However, the above code is is treating PARENT class member variables as properties of the child class. Member variables in parent class are declared protected and I cannot change that so I understand why this is happening. I cannot declare members of parent class private (which would have solved my problem)!

My question: Is there a way to determine is a member variable belongs to a child class and child class ONLY from within the parent class without declaring all parent member variables private?

php


Solution 1:[1]

One solution to this could be using reflection to get info about properties.

<?php

class A {
  protected $a = 1;
  protected $b = 2;

  public function aa() {
    echo 'called class: '.get_class($this).PHP_EOL;

    $r = new ReflectionClass($this);
    $properties = [];
    foreach($r->getProperties() as $property) {
      $properties[$property->name] = $property->class;
    }

    echo 'properties info:'.PHP_EOL;
    var_dump($properties);

    echo 'iterate properties:'.PHP_EOL;
    foreach ($this as $k => $v) {
      echo $k.' => '.$v.', in: '.$properties[$k].', own: '.($properties[$k] === __CLASS__ ? 'yes': 'no').PHP_EOL;
    }
  }
}

class B extends A {
  protected $c = 3;
}

$a = new A();
$a->aa();
$b = new B();
$b->aa();

Output:

called class: A
properties info:
array(2) {
  ["a"]=>
  string(1) "A"
  ["b"]=>
  string(1) "A"
}
iterate properties:
a => 1, in: A, own: yes
b => 2, in: A, own: yes
called class: B
properties info:
array(3) {
  ["c"]=>
  string(1) "B"
  ["a"]=>
  string(1) "A"
  ["b"]=>
  string(1) "A"
}
iterate properties:
c => 3, in: B, own: no
a => 1, in: A, own: yes
b => 2, in: A, own: yes

So in this example we test both parent $a and child $b and from parent method aa we always have information about who is the "owner" of the property.

Solution 2: Instead of aa method with reflection (if you dont need to know who is the owner, only if it is the parent property or not) try method bb:

public function bb() {
    echo 'called class: '.get_class($this).PHP_EOL;

    foreach ($this as $k => $v) {
      echo $k.' '.(property_exists(__CLASS__,$k) ? 'own' : 'not own').PHP_EOL;
    }
  }

So check if property exists on class level, output:

called class: A
a own
b own
called class: B
c not own
a own
b own

Solution 2:[2]

I know what you are asking about and here is the solution to "ignore" the parent class's members:

foreach($this as $member_name => $member_value) {
 if(property_exists(get_class($this),$member_name) && isset($member_value) && !property_exists(__CLASS__,$member_name))
     //do something....
}//end foreach

The third statement in the 'if' will filter out those members that belong to the parent class.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Codemover