Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

PHP Object-Oriented PHP Basics (Retired) Properties and Methods Constructor Method

Hossein Jalali
Hossein Jalali
5,658 Points

Getting the default value

when i'm using __construct, how can i get a default value of something(name or price or desc) , for example i wanted for some of my products to use a default price, how can i do that ?

2 Answers

No problem!

As a rule of thumb, you never want to skip an argument for a method or function - otherwise you run into this problem!

This will fix what you're trying to do:

<?php

class Product
{
    /**
     *  @var string 
     */
    public $name;

    /**
     *  @var float 
     */
    public $price;

    /**
     *  @var string
     */
    public $description;    

    /**
     * Create a new instance of SomeClass.
     *
     * @param string $name
     * @param float|null $price
     * @param string|null $description
     */
    public function __construct($name, $price = null, $description = null)
    {
        $this->name = $name;

        $this->price = ($price) ? $price : 4.00;
        $this->description = ($description) ? $description : 'Some Description';
    }
}

You could also

<?php

class Product
{
    /**
     *  @var string 
     */
    public $name;

    /**
     *  @var float 
     */
    public $price = 4.00;

    /**
     *  @var string
     */
    public $description = 'Some Description';    

    /**
     * Create a new instance of SomeClass.
     *
     * @param string $name
     * @param array $options
     */
    public function __construct($name, $options = [])
    {
        $this->name = $name;

        if (array_key_exists('price', $options) && $options['price']) {
            $this->price = $price;
        }
        if (array_key_exists('description', $options) && $options['description']) {
            $this->description = $description;
        }
    }
}

The second method is not advisable for a constructor method. When you create a new instance of an object, you want to be as verbose (specific) as possible about what the object requires to be created.

You are far better off making getters and setters for the additional and optional requirements.

<?php

class Product
{
    /**
     *  @var string 
     */
    public $name;

    /**
     *  @var float 
     */
    public $price = 4.00;

    /**
     *  @var string
     */
    public $description = 'Some Description';    

    /**
     * Create a new instance of SomeClass.
     *
     * @param string $name
     */
    public function __construct($name)
    {
        $this->name = $name;
    }

    /**
     * Set the price
     *
     * @param float $price
     */
    public function setPrice($price)
    {
        $this->price = $price;
    }

    /**
     * Set the description
     *
     * @param string $description
     */
    public function setPrice($description)
    {
        $this->description = $description;
    }  
}


$shirt = new Product('Blue Shirt');

$shirt->setPrice(4.00);
$shirt->setDescription('A really awesome blue shirt.');

If you think of it like this - a constructor should contain everything that's required to make an instance of the object. If it's optional, it's probably better off in a dedicated method. You'll probably not run into this exact issue in the real world because in very few cases would you want to set a default price!! Imagine a bug that meant £1,000 products were selling for £4.00 :-p

Defaults can be set on the class variable, or in the construct itself. You don't need to do both of the following - it really depends on what you find most readable.

<?php


class Product
{
    /**
     *  @var float 
     */
    public $price = 4.00

    /**
     * Create a new instance of SomeClass. Default the price to £4.00.
     *
     * @param float $price
     */
    public function __construct($price = 4.00)
    {
        $this->price = $price;
    }
}

When you create a new instance, you can override the defaults simply by passing in an alternative value:

<?php

$shirt = new Product(10.00);

$shirt->price // 10.00;
Hossein Jalali
Hossein Jalali
5,658 Points

Thanks for your answer , it works when i have one variable, but still when i put like 3 variables(name, price and desc) and i want to make the price default value i cant , i put NULL in price it shows nothing, and if i put nothing it says missing argument, the codes are like this :

<?php

    class Product {

        public $price;
        public $name;
        public $desc;


        function __construct($name , $price = 20 , $desc = 'it has no description'){

            $this->name = $name;
            $this->price = $price;
            $this->desc = $desc;
                }

        public function getinfo(){

            return "product info is: ".$this->name . ' '. $this->price . ' ' . $this->desc; 
            }
        }

                $p = new Product('TV' , NULL , ',it has description' );

        echo $p->getinfo();

Thanks in advance :)