PHP getter/setter problem.

Please refer to my code snippet below:

class User {
    private $first_name = "John";
    
    public function get_firstName() {
        return $this->first_name;
    }
}

Open in new window


I create a class called User with only one property -- firstName. Based on what I've read, the way to create a getter and setter function in PHP is to prefix the getter function name with get_, and to prefix the setter function name with set_. So if my getter function is called get_firstName, I then would be able to do this:

$u = new User();
echo $u->firstName; // getting Undefined property error here

Open in new window


But it's not working, as I'm getting an Undefined property error. Can someone please tell me what I'm doing wrong?
elepilAsked:
Who is Participating?
 
Marco GasiFreelancerCommented:
As Dave said, get_ and set_ are nothing special and are not buyilt-in methods of Php OOP. To access private properties you must use Php magic methods __get and __set

class User {
    private $first_name = "John";
    
  public function __get($property) {
    if (property_exists($this, $property)) {
      return $this->$property;
    }
  }

  public function __set($property, $value) {
    if (property_exists($this, $property)) {
      $this->$property = $value;
    }
    return $this;
  }
}

Open in new window


Now this will work:
$u = new User();
echo $u->firstName;

Open in new window

0
 
Dave BaldwinFixer of ProblemsCommented:
You should read my last comment in your previous question.
0
 
Ray PaseurCommented:
It's still the same underlying problem.  The variable names are not the same!
http://iconoun.com/demo/temp_elepil_duplicate.php

Look carefully: first_name != firstName

<?php // demo/temp_elepil_duplicate.php

/**
 * See http://www.experts-exchange.com/Programming/Languages/Scripting/PHP/Q_28636075.html
 */
error_reporting(E_ALL);
echo '<pre>';


class User {
    private $first_name = "John";

    public function get_firstName() {
        return $this->first_name;
    }
}

$u = new User();

// UNDEFINED
echo PHP_EOL . $u->firstName;

// DEFINED, VIA A CALL TO THE OBJECT METHOD
echo PHP_EOL . $u->get_firstname();

Open in new window

0
Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

 
elepilAuthor Commented:
To Ray Paseur.

You were focused on the differing variable names. But that is by design. Private member variables are usually the property name differing only by an underscore (by convention).

Nevertheless, I got enough responses from others that provided an alternate solution by using __get and __set.

Thank you for responding.
0
 
Ray PaseurCommented:
Private member variables are usually the property name differing only by an underscore (by convention).
Good grief!  Who told you that?? It's completely wrong!  This is why I recommend that you use var_dump() so you can see what is really going on.

There is nothing wrong with using getters and setters, and in some environments that makes sense, but in this question and the other one you had about this subject, the getters and setters had nothing to do with the real issue.  The real issue is that the variable names do not match, so you get two completely different variable containers
0
 
elepilAuthor Commented:
To Chris Stanyon.

I felt responders were not understanding my problem. As much as I take great pains to make my code samples short, simple, and as easy to understand as possible, I do not always succeed, so that's my fault. Sorry if I had to create another post, certainly wasn't my intention to post it as a duplicate.
0
 
Chris StanyonCommented:
@Ray - the OP is actually correct in his statement that private backing variables, by convention are named the same as a public property, but preceded by an underscore. I've never seen it done in PHP but it gets done a lot in C#. The other convention, and the one I tend to prefer is to name the backing (private) variable using all lowercase, while the publuic property is capitalised.

If you use one of the Visual Studio exentions, then this convention is often enforced - StyleCop enforces the lowercase convention, whereas ReSharper enforces the underscore convention.

I think the OP is coming from a C# background.
0
 
Marco GasiFreelancerCommented:
@elepil Ray is totally right: I've been superficial and I didn't see the mismatch, but if your property name is $first_name, nor a magic method nor a magic wand will can make you get the exepected value calling $u->firstName. You shoud use $u->first_name. In this case, getter will return the value of a property you can't directly access because it is declared as private, but the name must be the right one not another one.
0
 
elepilAuthor Commented:
To Ray Paseur.

I've worked as a software developer for many years, and what I described to you is common classic OOP practice. Given a property like firstName, it is fairly common practice to define it as:

private String _firstName;

and it's getter would look like:

public String getFirstName() {
    return _firstName;
}
0
 
Marco GasiFreelancerCommented:
I guess the mismatch between the two property names was a typo...
0
 
Chris StanyonCommented:
@Marco - this wasn't a question about the mismatching names of variables - It was about an assumption (a wrong one!) that a method called get_firstName would automatically get fired when asking for a firstName property!! What the private variable is called is completely irrelevant!
0
 
Marco GasiFreelancerCommented:
The real issue is that the variable names do not match
This Ray's phrase made me look carefully to the property names elepil used and from here my last posts. About the question, it is evident there was a wrong assumption about get_ and set_ methods and I posted a small example (wrong, because I used mismatching property name as elepil did) about __get and __set methods. Don't undertand why all those exclamation marks...
0
 
Chris StanyonCommented:
Marco - Sorry - I didn't spot your typos but my point remains the same - this was never fundamentally about a mismatch of variable names - it was about a wrong assumption on how getters and setters work.

Even with your typos, you cleared that up, but then went on to say that Ray was absolutely correct - I simply disagreed - strongly!!

:)
0
 
elepilAuthor Commented:
I guess it all boils down to one's programming background. Chris Stanyon's assumption that my background was in C# is correct. It's actually C#/Java/ActionScript, all of which are classic OOP languages. It is common practice to precede private property names with an underscore to differentiate it from the public property's name.

But I am seeing now that if one's background is simply PHP, this convention might appear bizarre.
0
 
Marco GasiFreelancerCommented:
Ah, now I understand... :) Rereading carefully all the thread, I admit I misunderstood the real nature of the question. And I admit I've never known the convention you told about (different variable names depending on public/private nature): my mind struggles a bit thinking a case sensitive language which uses such a convention.
Anyway, it is now my opinion that magic methods were not involved here: this is the second time in a few days I get points for technically wrong answers. Maybe you can reopen the question: it seems this discussion it's not ended yet.
0
 
elepilAuthor Commented:
To Marco Gasi.

Haha, I did reopen the question, but I got reprimanded for posting a duplicate post. I guess I realized my original (first) post was meandering all over the place, to the point that I was spending too much time helping responders understand my problem.

I also realized my misconception that prefixing a function with get_ and set_ somehow made them "magically" become legitimate getters/setters. I am grateful to all you responders who made me see the error of my ways.

P.S. I do love the __get and __set solution though, it was perfect!
0
 
Marco GasiFreelancerCommented:
God works in mysterious ways
:-)
0
 
Chris StanyonCommented:
@Marco - I think your answer was the right one to accept. After all, the question was about an assumed 'magic' getter/setter functionality, so the fact that you showed the proper way of using the magic getter/setter is enough to earn the points :)

I think sometimes definitions get lost in translation - particularly between different development languages.

In C#, I never refer to class members as variables - we have private 'fields' and public 'properties'. Often the public property will expose a private field in a controlled way - the private field is simply named using camelCase where as the property uses PascalCase. These aren't hard and fast rules, just generally accepted coding standards. So in the example we've been working with here, you would have something like this in c#

// the private backing variable
private String firstName;

// the public property
public String FirstName
{
   get 
   {
      return firstName; 
   }
   set 
   {
      firstName = value; 
   }
}

Open in new window


By doing it this way (and a similar way in PHP), it allows you control over how your properties are used. For example, you could add validation code to the setter, or remove it altogether - creating a readonly property.

You can't do that if you just expose a public variable. It can be set and get by anyone, from anywhere.

Anyway - we're getting off topic, but it's been an interesting debate.
0
 
Marco GasiFreelancerCommented:
Yes, I have clear the avantage to use getters and setters (developing Delphi components they are usual): but I didn't never considered the evenience of convention like the one you described in C#. Even because many times I got a non working code bacause of a mismatch in the property or variable name :D
Cheers
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.