views:

111

answers:

2

I'm working through this tutorial: http://www.killerphp.com/tutorials/object-oriented-php/php-objects-page-3.php

At first he has you create a setter and getter method in the class:

<?php

class person{
    var $name;      

    function set_name($new_name){
        $this->name=$new_name;
    }

    function get_name(){
        return $this->name;
    }
}

php?>

And then you create the object and echo the results:

<?php 
    $stefan = new person();
    $jimmy  = new person();

    $stefan ->set_name("Stefan Mischook");
    $jimmy  ->set_name("Nick Waddles");

    echo "The first Object name is: ".$stefan->get_name();
    echo "The second Object name is: ".$jimmy->get_name();

?>

Works as expected, and I understand.

Then he introduces constructors:

class person{
    var $name;

    function __construct($persons_name) {       
        $this->name = $persons_name;        
    }       

    function set_name($new_name){
        $this->name=$new_name;
    }

    function get_name(){
        return $this->name;
    }
}

And returns like so:

<?php 

    $joel   = new person("Joel");

    echo "The third Object name is: ".$joel->get_name();
?>

This is all fine and makes sense.

Then I tried to combine the two and got an error, so I'm curious-is a constructor always taking the place of a "get" function? If you have a constructor, do you always need to include an argument when creating an object?

Gives errors:

<?php 
    $stefan = new person();
    $jimmy  = new person();
    $joel   = new person("Joel Laviolette");
    $stefan ->set_name("Stefan Mischook");
    $jimmy  ->set_name("Nick Waddles");

    echo "The first Object name is: ".$stefan->get_name();
    echo "The second Object name is: ".$jimmy->get_name();
    echo "The third Object name is: ".$joel->get_name();
?>
+4  A: 

A constructor is used to initialize an object. The expectation in object-oriented programming is that an object shouldn't exist unless it's in a valid state. For example, a Person without a first and last name might not be considered a valid entity, so when the object is first created it should be initialized with a first and last name in the constructor.

The reason you got an error is because the constructor has a required parameter, so you must pass an argument to it.

P.S. I really hate explanations of object-oriented programming that try to use analogies like "Dog is-a Mammal". You should probably stay away from those examples. They really give no helpful information in real world programming and sometimes even give students the illusion they understand how to use what they're being taught.

If you're looking for a practical application of using a constructor to create an object in valid state, imagine a blog post that uses a database for persistence.

For example, there would be no point writing a long post and then calling $BlogPost->save(); if the blog wasn't first initialized with a reference to the database. The application of using a constructor in this case would perhaps be

$BlogPost = new BlogPost($Database);

It would make no sense to have to write:

$BlogPost->setDatabase($Database);

every time you wanted to do anything with it. Maybe you'd forget to write it once and you'd be wondering where the post you spent 30 minutes writing disappeared to. That's an example of an invalid state.

The idea is that you're including anything the class is dependent upon when it is first initialized, instead of risking the possibility of the object being in an invalid state.

Edit: Corrected 'two parameters' to one.

Lotus Notes
Thanks for your answer-so to be clear-if I have a constructor in a class, then I will always have to pass an argument when creating an object otherwise I get an error? IE, I could not do $BlogPost = new BlogPost();
Joel
That's entirely up to how you define your constructor in the first place. function __construct($persons_name) has one variable, $persons_name is the parameter. In my example, I just happened to do the same thing, although you could define it to have any number of arguments (or none).
Lotus Notes
+1 very nice and explanatory answer.
Lars Andren
Thanks Byron. I accepted the other answer, because he more clearly answered my question of "do you always need to include an argument when creating an object?"-at least to my newbie brain-I learned a lot from you explanation as well!
Joel
+1 nice explanation
RC
+3  A: 

It's giving you errors because the constructor has required parameters. To make a parameter optional give it a default value like this

function __construct($persons_name=null) {
    if ($persons_name) {
        $this->set_name($persons_name);//use the setter in the constructor.
    }      
}

this will now work

$stefan = new person();
$stefan ->set_name("Stefan Mischook");
$joel   = new person("Joel Laviolette");
echo "The first Object name is: ".$stefan->get_name();
echo "The second Object name is: ".$joel->get_name();
Galen
Cool. I understand this. Thanks!
Joel