Jump to content

Recommended Posts

Hi there,

 

I'm working on a custom datagrid and therefore I need to know the properties of a class.

I use reflection to do this.

However, if you use reflection on classes that have properties exposed via the magic __get and __set I get

the error: Cannot access non-public member ***.

 

The only way I can make it work is to make my variables in my classes public. The OOP way should be that you can have public properties which protect your private class members. This way I cannot.

 

some code:

 

class FooBar{
private $foo;

public function __get ($Var){
	return $this->$Var;
}
public function __set ($Var, $Value){
	$this->$Var = $Value;
}
}
{
   $f = new foo();
   $f->foo = 'blah';  

   $rfc = new ReflectionClass(get_class($f));
   $prop = $rfc->getProperty('foo');
   print $prop->getValue($f) . '<br>'; // this line causes the error: Cannot access non-public member ***
}

 

as you can see: $->foo = 'blah' works and $prop->getValue($f) does not, because then PHP thinks it is a private member, but it is an public property actually exposed via the magic __get method.

 

Does anyone know how to make this work without making everything public?

 

[...] because then PHP thinks it is a private member [...]

 

It is a private property and therefore it should not be able to be accessed from outside the class. If you want to access it from outside the class it should be defined as public.

It is a private property and therefore it should not be able to be accessed from outside the class. If you want to access it from outside the class it should be defined as public.

 

It IS a public property, the code below works:

$f->foo = 'blah'

or

print $f-foo;

 

Because I made it public via the __get and __set.

It just doesn't work with reflection->getValue this way. Reflection does not seem to work with the magic __get and __set methods. There could be reasons for this, or it's just not implemented.

 

 

 

__get and __set does not make a private data public. Although it allows you to retrieve private data, it does not change its visibility as it was setted. So, $foo is still a private data. The reason you are able to retrieve it outside of the class is because when you do $f->foo, it is calling the function __get('foo'). When that functioned is called, it is able to retrieve that private data because it is a member of the class. When getValue is called, it doesn't invoke the __get function so it can't retrieve the data.

ah yes, I meant:

$f = new FooBar; // see class description in first thread

 

sorry about that.

 

But so I know now that the Getvalue doen't invoke the magic __get method.

 

Does anyone have another suggestion then how to make it work without making the private field $foo public?

 

The purpose is that i can make a datagrid who can iterate trough the properties of a class you feed it. It is possible with reflection, but as soon as I want a value of its property I stumble upon this problem.

 

The behaviour of reflection class is correct (but since i think you actually want to work with an object you should use ReflectionObject it has the same behaviour though).

You can however do a quite ugly workaround if you really have to get the value of the private var through the __get method.

 

<?php class FooBar{
public $foo;

public function __get ($Var){
	return $this->$Var;
}
public function __set ($Var, $Value){
	$this->$Var = $Value;
}
}

   $f = new FooBar();
   $f->foo = 'blah';  

   $rfc = new ReflectionMethod(get_class($f),'__get');
   echo $rfc->invoke($f,'foo');

Me did a typo ;)

 

Should have set the variable to private instead of public. The code should look like this:

 

<?php
class FooBar{
private $foo;

public function __get ($Var){
	return $this->$Var;
}
public function __set ($Var, $Value){
	$this->$Var = $Value;
}
}

   $f = new FooBar();
   $f->foo = 'blah';  

   $rfc = new ReflectionMethod(get_class($f),'__get');
   echo $rfc->invoke($f,'foo');
?>

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.