Detect if an object property is private in PHP

11,321

Solution 1

You can use Reflection to examine the properties of the class. To get only public and protected properties, profile a suitable filter to the ReflectionClass::getProperties method.

Here's a quicky example of your makeString method using it.

public function makeString()
{
    $string = "";
    $reflection = new ReflectionObject($this);
    $properties = $reflection->getProperties(ReflectionProperty::IS_PUBLIC);
    foreach ($properties as $property) {
        $name    = $property->getName();
        $value   = $property->getValue($this);
        $string .= sprintf(" property '%s' = '%s' <br/>", $name, $value);
    }
    return $string;
}

Solution 2

Check this code from http://php.net/manual/reflectionclass.getproperties.php#93984

  public function listProperties() {
    $reflect = new ReflectionObject($this);
    foreach ($reflect->getProperties(ReflectionProperty::IS_PUBLIC /* + ReflectionProperty::IS_PROTECTED*/) as $prop) {
      print $prop->getName() . "\n";
    }
  }

Solution 3

A quicker solution that I found:

class Extras
{
    public static function get_vars($obj)
    {
        return get_object_vars($obj);
    }
}

and then call inside of your testClass:

$vars = Extras::get_vars($this);

additional reading in PHP.net

Solution 4

You can easily use the Reflection API to check the visibility of properties:

$rp = new \ReflectionProperty($object, $property);

if ($rp->isPrivate()) {
  // Do if the property is private
} else {
  // Do if the property is public or protected
}

Solution 5

If you cast the object to an array before iterating over it, the private and protected members will have special prefixes:

class Test{
  public $a = 1;
  private $b = 1;
  protected $c = 1;
}
$a = new Test();
var_dump((array) $a);

displays this:

array(3) {
  ["a"]=>
  int(1)
  ["Testb"]=>
  int(1)
  ["*c"]=>
  int(1)
}

There are hidden characters there too, that don't get displayed. But you can write code to detect them. For example, the regular expression /\0\*\0(.*)$/ will match protected keys, and /\0.*\0(.*)$/ will match private ones. In both, the first capturing group matches the member name.

Share:
11,321

Related videos on Youtube

Hippyjim
Author by

Hippyjim

Hippy is as Hippy does

Updated on January 28, 2022

Comments

  • Hippyjim
    Hippyjim over 2 years

    I'm trying to make a PHP (5) object that can iterate through its properties, building an SQL query based only on its public properties, not its private ones.

    As this parent object method is to be used by child objects, I can't simply choose to skip the private properties by name (I won't know what they are in the child objects).

    Is there a simple way to detect from within an object which of its properties are private?

    Here's a simplified example of what I've got so far, but this output includes the value of $bar:

    class testClass {
    
        public $foo = 'foo';
        public $fee = 'fee';
        public $fum = 'fum';
    
        private $bar = 'bar';
    
        function makeString()
        {
            $string = "";
    
            foreach($this as $field => $val) {
    
                $string.= " property '".$field."' = '".$val."' <br/>";
    
            }
    
            return $string;
        }
    
    }
    
    $test = new testClass();
    echo $test->makeString();
    

    Gives the output:

    property 'foo' = 'foo'
    property 'fee' = 'fee'
    property 'fum' = 'fum'
    property 'bar' = 'bar' 
    

    I'd like it to not include 'bar'.

    If there's a better way to iterate through just the public properties of an object, that would work here too.

  • emmanuel honore
    emmanuel honore about 14 years
    There is also the reflection class and the magic method __get()
  • Hippyjim
    Hippyjim about 14 years
    I'm afraid I'm ignorant of the reflection class - I'll need to do some heavy Googling. Thanks for the pointer.
  • emmanuel honore
    emmanuel honore about 14 years
    I ignored it in the past too, but then I figured out the great opportunities you can have with it.
  • Hippyjim
    Hippyjim about 14 years
    That's exactly what I needed. Thanks for the lesson!
  • Hippyjim
    Hippyjim about 14 years
    Thanks - I think powtac beat you to it by about 30 seconds, but yes, that works exactly as needed.
  • salathe
    salathe about 14 years
    Yeah, I guess too much time was spent making a pretty answer with neat and tidy links to the docs. Lesson learned, quick and dirty answers from here on in! :-)
  • Louis Loudog Trottier
    Louis Loudog Trottier over 7 years
    one more tool in the toolbox
  • Chadwick Meyer
    Chadwick Meyer over 2 years
    This should be a method not a property e.g. $rp->isPrivate()