<?php
//===============================================================================================
// Define a Box class
//   with public static attribute
//   with public and private object attributes
//   with __construct which will automatically be called upon using new Obj() 
//   with __get which will automatically be called if the attribute is private
//   with __set which will automatically be called if the attribute is private
//   with __toString which will automatically be called when using the obj in a string context 
//   with a static method  
//   with an object method  
//===============================================================================================
class Box
{
    public static $className = 'A Box class';   //class attribute

    public  $height;                            //object attributes
    private $width;
    private $depth;
    
    function __construct($h, $w)        //will automatically be called upon using new Box()
    {
        $this->height = $h;                     //assign incoming param to class attributes
        $this->width  = $w;                                     
        $this->depth  = 100;
    }    

    function __get($name)               //will automatically be used if attribute is private
    {
        if ($name == 'depth')                                   //protect access of attribute           
            die("error - $name cannot be retrieved <br>");

        return($this->$name);                                   //return the value of the attribute
    }    

    function __set($name, $value)       //will automatically be used if attribute is private
    {
        if ($name == 'depth' && $value > 199)                   //validate attribute values
            die("error - $name cannot be set more than 199 <br>");

        $this->$name = $value;                                  //set the value of the attribute
    }    

    public function toString()
    {
        return ("The class is: "        . self::$className    . "<br>" .
                "The object X/Y/Z dim: ". $this->height . "," . $this->width . ","
                                        . $this->depth);
    }

    public function __toString()        //will automatically be called when obj is used in string context 
    {
        $str  = "The class is: "        . self::$className    . "<br>" . 
                "The object X/Y/Z dim: ". $this->height  . "," . $this->width . ","
                                        . $this->depth   . "<br>" . 
                "The box volume: "      . $this->size()  . "<br>" .
                "Conclusion: "          . self::theEnd() .
                "The var export: "      . var_export($this, TRUE);
        return ($str);
    }

    public static function theEnd()                             //a static method
    {
        return "That's all folks... ";
    }

    public function size()                                      //an object method
    {
        $box_size    = $this->height * $this->width * $this->depth;
        return ($hello_world . $box_size);
    }
}
?>

<?php
//===============================================================================================
// Use a Box class
//   access the static attribute
//   instantiate and object using new.  This will automatically call the __construct()
//   access the object attributes
//   call my own toString() method
//   change attribute values (if attribute is private, __get() and __set() will be used) 
//   print the object, this will automatically call the __toString()
//===============================================================================================

    print "<h2>Defining a class called 'Box' </h2>";

    print Box::$className  ."<br>";          //accessing a static attribute
    print Box::theEnd()    ."<br>";;         //calling a static method


    print "<h2>Creating our first object 'obj1' </h2>";

    $obj1 = new Box(6,8);                    //instantiate object
        
    print "Our first object height/width: ";
    print $obj1->height ." ";                //print a public object attribute
    print $obj1->width  ."<br>";             //print a private object attribute, will use __get( )           

    print "<br>";
    print "First object: <br>". $obj1->toString();  //my own toString() method will be called
    print "<br>";

    $obj1->height = 15;                      //change public object attribute
    $obj1->width  = 24;                      //change private object attribute, will use __set( )                                            

    print "<br>";
    print "Changed to: <br> $obj1 <br>";     //__toString() will automatically be called

    print "<br>";
    print "The box volume: " . $obj1->size();  //call the size() method

    print "<br>";
    print "<hr>"; //-------------------------------------------------------------------------------

    print "<h2>Creating our second object 'obj2' </h2>";

    $obj2 = new Box(33,42);                  //instantiate another object
        
    print "Second object: <br>$obj2 <br>";   //__toString() will automatically be called

    $obj2->height = 12; 
    $obj2->width  = 12; 

//  $obj2->depth = 200;                      //this will fail - depth is private, 
                                             //__set will be called and depth will be validated
                                             //and since it is > 199, it will fail

//  print $obj2->depth;                      //this will fail - depth is private,
                                             //__get will be called and depth will not be returned

    print "<br>";
    print "Changed to: <br>$obj2 <br>";      //__toString() will automatically be called

    print "<br>";
    print "The box size: " . $obj2->size();  //call the size() method

    print "<hr>"; 
?>

<?php include "../include.php"; ?>           <!-- hyperlink to see the code -->