el_mariachi Posted January 6, 2008 Share Posted January 6, 2008 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? Quote Link to comment https://forums.phpfreaks.com/topic/84766-__get-and-__set-public-and-private-question/ Share on other sites More sharing options...
el_mariachi Posted January 6, 2008 Author Share Posted January 6, 2008 ... Quote Link to comment https://forums.phpfreaks.com/topic/84766-__get-and-__set-public-and-private-question/#findComment-431997 Share on other sites More sharing options...
DyslexicDog Posted January 6, 2008 Share Posted January 6, 2008 check out this article it should help quite a bit. http://www.onlamp.com/pub/a/php/2005/06/16/overloading.html Quote Link to comment https://forums.phpfreaks.com/topic/84766-__get-and-__set-public-and-private-question/#findComment-432008 Share on other sites More sharing options...
Daniel0 Posted January 6, 2008 Share Posted January 6, 2008 [...] 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. Quote Link to comment https://forums.phpfreaks.com/topic/84766-__get-and-__set-public-and-private-question/#findComment-432011 Share on other sites More sharing options...
el_mariachi Posted January 6, 2008 Author Share Posted January 6, 2008 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. Quote Link to comment https://forums.phpfreaks.com/topic/84766-__get-and-__set-public-and-private-question/#findComment-432052 Share on other sites More sharing options...
Ken2k7 Posted January 6, 2008 Share Posted January 6, 2008 I may look stupid here but, $f = new foo(); ? Is foo() defined? Quote Link to comment https://forums.phpfreaks.com/topic/84766-__get-and-__set-public-and-private-question/#findComment-432062 Share on other sites More sharing options...
duclet Posted January 7, 2008 Share Posted January 7, 2008 __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. Quote Link to comment https://forums.phpfreaks.com/topic/84766-__get-and-__set-public-and-private-question/#findComment-432657 Share on other sites More sharing options...
el_mariachi Posted January 7, 2008 Author Share Posted January 7, 2008 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. Quote Link to comment https://forums.phpfreaks.com/topic/84766-__get-and-__set-public-and-private-question/#findComment-432663 Share on other sites More sharing options...
Ken2k7 Posted January 7, 2008 Share Posted January 7, 2008 This may be wrong, but do you mean something like: <?php class FooBar{ private $foo; public function get(){ return $this->foo; } public function set ($Value){ $this->foo = $Value; } } $f = new FooBar; $f->set('blah'); echo $f->get(); ?> Quote Link to comment https://forums.phpfreaks.com/topic/84766-__get-and-__set-public-and-private-question/#findComment-432899 Share on other sites More sharing options...
duclet Posted January 8, 2008 Share Posted January 8, 2008 Nope. He is basically trying to create a class where his data's visibility are private. However, he wants to have the Reflection classes to have access to its value. Quote Link to comment https://forums.phpfreaks.com/topic/84766-__get-and-__set-public-and-private-question/#findComment-433551 Share on other sites More sharing options...
aschk Posted January 9, 2008 Share Posted January 9, 2008 Drop the private $foo part in your class. Then when __set is called it creates the member as public, allowing the reflection class to utilise it. This is BAAAAAAD practise thought so i don't condone it's usage. Quote Link to comment https://forums.phpfreaks.com/topic/84766-__get-and-__set-public-and-private-question/#findComment-434398 Share on other sites More sharing options...
olle.lundberg Posted January 14, 2008 Share Posted January 14, 2008 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'); Quote Link to comment https://forums.phpfreaks.com/topic/84766-__get-and-__set-public-and-private-question/#findComment-438932 Share on other sites More sharing options...
olle.lundberg Posted January 15, 2008 Share Posted January 15, 2008 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'); ?> Quote Link to comment https://forums.phpfreaks.com/topic/84766-__get-and-__set-public-and-private-question/#findComment-439659 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.