0

Is it normal to not defined variable in class properties, but indicate at once in constructor ? I just learn OOP, and found that example:

class Foo {
  public function __construct($name) {
    $this->_name = $name;
  }
}

and it works, i can use this variable

$objFoo = new Foo('Fido');
echo $objFoo->_name; //output 'Fido'

But in class properties, there has no defined variable $_name, like public $_name in start of class. So if we dont define it directly, it will be created automatically throught constructor ? And is it real to set scope for variable that way, protected, private ?

2
  • 2
    Note that the new properties defined in the actual code will always be public.... if you want protected or private you need to define them explicitly in your class definition Commented Sep 8, 2014 at 8:23
  • also, you should always code with error_reporting(E_STRICT | E_NOTICE) Commented Sep 8, 2014 at 8:36

2 Answers 2

2

In PHP, this is called "object overloading", you can add/set new properties on (almost) any instance on the fly. However, you shouldn't do this. These properties make your code more error prone, less maintainable and overloaded properties that are added are slower: details here.

Pre-declaring properties allows for better documentation, your IDE's auto-completion function is actually worth something then, and you don't get in the habit of relying on something that doesn't always work. I tend to write my data models along these lines:

class DataModel
{
    /**
     * @var int
     */
    protected $id = null;

    /**
     * @var string
     */
    protected $name = null;

    /**
     * @var \DateTime
     */
    protected $birthday = null;

    public function __construct(array $data)
    {}//set values
    public function __set($name, $value)
    {
        throw new \BadMethodCallException('Do not attempt overloading, use getters and setter');
    }
}

I define getters and setters for all of the properties, to ensure type safety, and validation can be done. I expressly disable overloading because of the risk of typo's, and difficult debugging. I often find myself disabling __sleep, __serialize and all those magic methods for pretty much the same reason.

Sign up to request clarification or add additional context in comments.

7 Comments

The explanation is plain wrong. In OP's example Foo does obviously not implement __set(). PHP allows to declare and initialize public class members on the fly
@hek2mgl: You clearly didn't read my answer thoroughly. I explain that object overloading is available, but I consider it to be bad, for reasons mentioned both in the link, and further down the answer. I then procede to give an example of a class where overloading wouldn't work: implementing a __set that throws an excpetion would cause the OP's code to fail
Again, this question is not about overloading. Please read the question (and probably other answers) again
@hek2mgl: This question is about overloading: PHP's definition of overloading is "[..] means to dynamically "create" properties and methods". It's a silly term, and a bad idea as I've often stated before, but that's what it's called... so sit-rap: adding properties on the fly is called overloading, It does not require a __set method, it's a silly term, and a bad idea we're on the same page here
@hek2mgl: Yes, I have. What's your point? We're on the same page. But really, you seem to be hell-bound on disagreeing with me... not sure why, but heck: whatever works
|
1

Creating object members on the fly, meaning just assigning a value to it without declaring the member, is not limited to the constructor method. It can be done from inside of every method in the class or even from outside of the class, like this:

$c = new stdClass();
$c->foo = "bar";

While there are still a few use cases for this, I suggest to declare every class member explicitly in the head of the class. Also you will want in most cases to declare class members as protected or even private which requires an explicit declaration anyway.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.