Hall of Famer Posted May 17, 2012 Share Posted May 17, 2012 Well the title may seem a bit confusing, but heres an example: <?php class User{ public $uid; public $username; protected $password; protected $email; public $usergroup; public $profile; public function __construct($id){ // constructor code inside } public function getemail(){ return $this->email; } public function getusergroup(){ return $this->usergroup; } public function getprofile(){ $this->profile = new UserProfile($this->uid); } } class UserProfile(){ protected $avatar; protected $bio; protected $gender; protected $favcolor; public function __construct($id){ // constructor code inside } public function formatavatar(){ // avatar formatting code inside } public function formatusername(){ // format username? } } ?> As you can see, the User class(an outer class) has a property called Profile, which can be instantiated as a UserProfile object(an inner class). The two objects have distinct functionalities, but there are times when the UserProfile object needs to access property and methods from the user object. I know its easy for outer class to access methods from inner class by using the single arrow access operator twice, but how about the other way around? Lets say from the above example the userprofile can format the username displayed to the screen by adding a sun to the left of the username if the usergroup is admin, a moon if the usergroup is mod, and nothing if its just a member. The usergroup property is stored in the outer class, and can be accessed with this $user->getusergroup() method only. I know I can always do the hard way by passing a user object to the method's argument, but is there an easier way for the inner class UserProfile to access properties/methods for outerclass User? If so, how can I achieve that? Quote Link to comment https://forums.phpfreaks.com/topic/262683-accessing-methods-of-outer-class-from-methods-in-inner-class/ Share on other sites More sharing options...
scootstah Posted May 17, 2012 Share Posted May 17, 2012 You can extend the User class with the UserProfile and then access all of User's methods/objects. Quote Link to comment https://forums.phpfreaks.com/topic/262683-accessing-methods-of-outer-class-from-methods-in-inner-class/#findComment-1346370 Share on other sites More sharing options...
requinix Posted May 17, 2012 Share Posted May 17, 2012 Shouldn't the UserProfile know whose profile it is? A bidirectional association: User has a profile, UserProfile has a user. Quote Link to comment https://forums.phpfreaks.com/topic/262683-accessing-methods-of-outer-class-from-methods-in-inner-class/#findComment-1346376 Share on other sites More sharing options...
Hall of Famer Posted May 17, 2012 Author Share Posted May 17, 2012 Shouldn't the UserProfile know whose profile it is? A bidirectional association: User has a profile, UserProfile has a user. You are absolutely right, this is what I am trying to achieve. Are you suggesting that I need to instantiate a user object inside the UserProfile class' constructor? Quote Link to comment https://forums.phpfreaks.com/topic/262683-accessing-methods-of-outer-class-from-methods-in-inner-class/#findComment-1346380 Share on other sites More sharing options...
requinix Posted May 17, 2012 Share Posted May 17, 2012 That's actually a tricky question with many answers. If you're pulling information from a database then the generic answer is "when you do so is when you set up the User and/or UserAccount objects" (like in getprofile() or a constructor). But hold on a second. Why is the UserProfile dealing with the username? Why not have the User class do that? That's where the information is, after all. Quote Link to comment https://forums.phpfreaks.com/topic/262683-accessing-methods-of-outer-class-from-methods-in-inner-class/#findComment-1346387 Share on other sites More sharing options...
mrMarcus Posted May 17, 2012 Share Posted May 17, 2012 Remove the parenthesis () from your UserProfile() class: class UserProfile { ... } Quote Link to comment https://forums.phpfreaks.com/topic/262683-accessing-methods-of-outer-class-from-methods-in-inner-class/#findComment-1346390 Share on other sites More sharing options...
Hall of Famer Posted May 17, 2012 Author Share Posted May 17, 2012 @requinix: I see, now this sounds a bit complicated. The User profile object is only instantiated and used in a page called profile.php, while the user object is used everywhere. So yeah the $user->getprofile() method is only called in script file profile.php, while it should not be invoked anywhere else since it will only be a waste of memory. And well, you are right ideally the User class should handle username formatting, not the UserProfile class. So perhaps it is not really a good example here, but in occasions it is definitely possible that an inner class needs to access properties/methods and I was wondering if there are easier ways to handle that. @MrMarcus: Oh my mistake, thanks for pointing it out. Quote Link to comment https://forums.phpfreaks.com/topic/262683-accessing-methods-of-outer-class-from-methods-in-inner-class/#findComment-1346395 Share on other sites More sharing options...
KevinM1 Posted May 17, 2012 Share Posted May 17, 2012 There are a few ways you could approach this. The easiest would be inheritance. Child classes have access to all of their parent's public and protected members. You could also try the Decorator pattern (look it up), since a UserProfile is really something that wraps a User. Quote Link to comment https://forums.phpfreaks.com/topic/262683-accessing-methods-of-outer-class-from-methods-in-inner-class/#findComment-1346434 Share on other sites More sharing options...
Hall of Famer Posted May 17, 2012 Author Share Posted May 17, 2012 There are a few ways you could approach this. The easiest would be inheritance. Child classes have access to all of their parent's public and protected members. You could also try the Decorator pattern (look it up), since a UserProfile is really something that wraps a User. I see what you mean, I will go with inheritance then. In fact I already incorporate some decorators in my script. The Friend and Banned decorators are good examples. I also coded child classes like Admin and Mod as inheritance. The problem I had before is that I couldnt envision UserProfile as child class as User(though ironically, I had not such problem with Admin and Mod classes). And thanks for your advice. Quote Link to comment https://forums.phpfreaks.com/topic/262683-accessing-methods-of-outer-class-from-methods-in-inner-class/#findComment-1346438 Share on other sites More sharing options...
ignace Posted May 18, 2012 Share Posted May 18, 2012 I don't get why you have a UserProfile at all... It has no id, so it's not an entity. It wraps data which I feel should belong to the User object, and it's only responsibilities are formatting. IMO, at best, your UserProfile IS a View. But since this formatting is part of your domain these should also be in your User class. Just like the below function would: public function getFullName() { return $this->getTitle() . '. ' . $this->getFirstname() . ' (' . $this->getAlias() . ') ' . $this->getLastName(); } If you have a requirement that states that you always should address the user with it's full name. Admin and Mod are Special Case's of User so these should inherit from User (but since PHP does not support method overloading, it's better to make these responsibilities also part of User and just check with isModerator() and isAdmin() of some sort). I also fail to see how Friend and Banned could be Decorators? Banned could be a Value Object that tells how the user was banned (perm, temp) and how long (in case of temp) but not a Decorator. And Friend should be just an instance of a User as element in a _friends property array. $user1->isFriendsWith($user2); //implementation public function isFriendsWith(User $u) { Assert::true(!$this->equals($u)); return $this->_friends->contains($u); } Quote Link to comment https://forums.phpfreaks.com/topic/262683-accessing-methods-of-outer-class-from-methods-in-inner-class/#findComment-1346536 Share on other sites More sharing options...
Hall of Famer Posted May 20, 2012 Author Share Posted May 20, 2012 I don't get why you have a UserProfile at all... It has no id, so it's not an entity. It wraps data which I feel should belong to the User object, and it's only responsibilities are formatting. IMO, at best, your UserProfile IS a View. But since this formatting is part of your domain these should also be in your User class. Just like the below function would: public function getFullName() { return $this->getTitle() . '. ' . $this->getFirstname() . ' (' . $this->getAlias() . ') ' . $this->getLastName(); } If you have a requirement that states that you always should address the user with it's full name. Admin and Mod are Special Case's of User so these should inherit from User (but since PHP does not support method overloading, it's better to make these responsibilities also part of User and just check with isModerator() and isAdmin() of some sort). I also fail to see how Friend and Banned could be Decorators? Banned could be a Value Object that tells how the user was banned (perm, temp) and how long (in case of temp) but not a Decorator. And Friend should be just an instance of a User as element in a _friends property array. $user1->isFriendsWith($user2); //implementation public function isFriendsWith(User $u) { Assert::true(!$this->equals($u)); return $this->_friends->contains($u); } Well not really, the user profile class has methods that display certain portion of profile page content when invoked. But yeah formatting should be handled as methods for user class. Quote Link to comment https://forums.phpfreaks.com/topic/262683-accessing-methods-of-outer-class-from-methods-in-inner-class/#findComment-1346939 Share on other sites More sharing options...
ignace Posted May 20, 2012 Share Posted May 20, 2012 Well not really, the user profile class has methods that display certain portion of profile page content when invoked. Like? Quote Link to comment https://forums.phpfreaks.com/topic/262683-accessing-methods-of-outer-class-from-methods-in-inner-class/#findComment-1346971 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.