Pages

OOPS PHP


Index

  1. The Very Basics
    1. A tiny bit of theory
    2. Hold on, read this disclaimer first
    3. Absolute basic syntax
  2. Defining how objects should behave
    1. Classes
    2. Inheritance
    3. Constructors
    4. Scope Resolution Operator
    5. Abstract Classes
  3. Beyond the Absolute Basics
    1. Object Handles
    2. Interfaces
    3. Autoload
    4. Destructors
    5. Visibility
    6. Class Constants
    7. Type Hinting
    8. Exceptions
    9. The Final Keyword
    10. More Magic Methods
      1. Object Overloading
      2. Object cloning
      3. Serialization
      4. Other
    11. Object Iteration
  4. Hot off The Press Features
    1. Namespaces
    2. Late static binding

1. The Very Basics

1.1 A tiny bit of theory
So what is an object anyway? In a definition proposed by IBM’s Grady Booch in 1991:
An object is an instance of a class with the following essential properties:
  • Each object has its own identity.
  • Each object can have certain behaviour.
  • Each object is in a state.
Let’s do a quick elaboration on these properties.
Each object has its own identity.

'Having its own identity' implies that even if two objects are
structurally the same (of the same class and in the same state), they
are still not identical.
Each object can have behaviour.

This behaviour is used, thus this is also referred to as “offer
services”. Basically an object has functions and variables local to that
object, referred to as methods and properties (more on that in the next
section), which define and influence this behaviour.
Each object is in a state.

The before mentioned properties (local variables) define the state an
object is in. This state can influence the behaviour (the methods act
differently depending on the properties).
In addition, objects often represent some concept, an object in the more literal sense.
I know you all can’t stand all this abstract talk and are itching for a code example, so here we go…
1.2 Hold on, read this first
Wait. Before I show you ANY code
AT ALL, note that in this tutorial I violate a truckload of ‘good
practice’ heuristics. This is done to be able to explain you the basics.
Take note of the fact that this tutorial is intended to show the
features available to you in PHP, it does not promote any actual
practice. Don’t worry, I will definitely get to that later.
1.3 Absolute basic syntax
Instantiating an (creating a new, unique) object:
$someVariable = new SomeClassDefiningAnObject;
Executing a function in the object (a method):
$someVariable->someMethod($someArgumentJustLikeARegularFunction);
Assigning the return value from a method to a variable:
$returnValue = $someVariable->someMethodThatReturnsSomething();
Setting and retrieving the current value of a property (a variable local to the object, not unlike an array index):
$someVariable->someProperty = 'SomeValue';
$currentValue = $someVariable->someProperty;
Hopefully
you now have a basic understanding of what objects are and how to
operate on them. Next we’re looking at defining the state and behaviour
of objects.

2 Defining how objects should behave

2.1 Classes
Classes
are the (partial) definition of an object. Also referred to as a
“object blueprint”, the class defines how the object will look after
first instantiation, and how it will behave in response to operating on
it. However it also possible to operate within the scope of a class
without an instantiation. You will read more about that in the “Scope
Resolution Operator” section.
Consider this extremely simple example of a class:
class Dog {
        public $hungry = 'hell yeah.';
        
        function eat($food)
        {
                $this->hungry = 'not so much.';
        }
}
$this
is a reserved variable name, referring to the current instantiation of
the object. By instantiating, we create a new Dog. Don’t mind the public
keyword for now.
$dog = new Dog;
The initial state of this dog is that it is pretty hungry.
echo $dog->hungry;
Echoes:
hell yeah.
So we feed our newly instantiated dog a treat, to modify its state.
$dog->eat('cookie');
Yep, doggie isn’t as hungry as before:
echo $dog->hungry;
Will echo:
not so much.
Doggie is happy enough, moving on.
2.2 Inheritance
Classes can have parent and child classes. When an object is
instantiated by name of a child class, PHP looks for parent classes and
starts combining the declarations, from the top, to create the initial
object. This is called inheritance. It isn’t such a hard concept to
grasp: a child inherits anything from its parents and ancestors that
isn’t redefined on the way down. If a class lower in the chain has a
property or method with the same name as one higher in the chain, the
last declaration is used for requests to the object.
To declare one class as a child of another, use the extends keyword.
Like with most popular languages, in PHP one class can only extend a
single other class. An infinite number of classes can be derived from
(extending) a single class though.
A simple example:
class Animal {
        public $hungry = 'hell yeah.';
        
        function eat($food)
        {
                $this->hungry = 'not so much.';
        }       }
class Dog extends Animal {
        function eat($food)
        {
                if($food == 'cookie')
                {
                        $this->hungry = 'not so much.';
                }
                else 
                {
                        echo 'barf, I only like cookies!';
                }
        }
}
Method
eat is overridden, because doggie only likes cookies. But, because all
animals are hungry when you don’t feed them, the initial state of
$hungry need not be defined in Dog. The fictional Bird, Cat and Piggy
could all extend Animal.
Class Animal is unaware of the fact that it is being extended; there
are no references to Dog whatsoever. Say Animal extended another class
called LifeForm, and I instantiated Animal, only methods and properties
of Animal and LifeForm would be included in the object.
2.3 Constructors
Constructors are a way to define the default
behaviour (set the default state) upon instantiation. You can, as shown
in the previous example, define the default state by setting default
values for properties. A constructor is nothing more than a method that
is executed when instantiating an object. This is referred to as
initializing the object.
An object isn’t fully initialized, constructed, until the constructor
method has completed (if present). A constructor method isn’t required,
our previous examples worked just fine without them. Another thing that
should be noted is that only the constructor of the class used to
instantiate is called automatically, any parent constructors need to be
called explicitly.
PHP 5 uses the __construct magic method. You can use the
name of the class as well, but this is only for backwards compatibility,
and will throw an error if you have E_STRICT error reporting enabled
(which you should have).
class Dog extends Animal {
        public $breed;

        function __construct($breed)
        {
                $this->breed = $breed;
        }
        
        function eat($food)
        {
                if($food == 'cookie')
                {
                        $this->hungry = 'not so much.';
                }
                else 
                {
                        echo 'barf, I only like cookies!';
                }
        }
}
Instantiating
a Dog requires us to specify it’s breed. The property breed is assigned
a new value by cause of this initialization (previously NULL), and we
have a Dog which initial state specifies it’s breed:
$dog = new Dog('Golden Retriever');
We could change its breed afterwards if we’d like:
$dog->breed = 'Bloodhound';
2.4 Scope Resolution Operator
Officially
called Paamayim Nekudotayim (Hebrew for double colon, now you know what
the parser is talking about when you get errors), the scope resolution
operator (::) allows you to perform static calls to methods and class
members.
Static methods can be called without instantiation of an object. This
can be useful both inside a class declaration (within an object
hierarchy) as outside of it.
After an object is created, some reference to the overwritten methods
and properties remains intact. One can access these methods from within
the object statically (no new instantiation is required, yet the object
from within you are operating is still affected.).
class Animal {
        public $hungry = 'hell yeah.';
        
        function __construct()
        {
                echo 'I am an animal.';
        }
        
        function eat($food)
        {
                $this->hungry = 'not so much.';
        }       }
class Dog extends Animal {       
        public $breed;
        
        function __construct($breed)
        {
                $this->breed = $breed;
                
                Animal:: __construct();
        }
        
        function eat($food)
        {
                if($food == 'cookie')
                {
                        Animal::eat($food);
                }
                else 
                {
                        echo 'barf, I only like cookies!';
                }
        }
}
$dog = new Dog('Rotweiler');
$dog->eat('cookie');
echo $dog->hungry;
Dog is using its parent’s method eat to refer to the declaration of eat
that was overwritten by its own declaration of eat. You need not specify
the specific class name like in the above example to refer to the last
declaration of a method (or property), the parent keyword will point to
that reference:
parent::eat($food);
Should
you have multiple levels of inheritance, and want to address a
declaration other than the one last defined, you’ll have to specify the
class like in the above example class.
The constructor of parent classes is called upon instantiation,
unless it is overridden. We override __construct(), so if we desire to
run a parent constructor, we have to call it explicitly:
Animal::__construct();
Trying
to call a method statically which has references to object specific
variables (makes use of $this) from outside of the object, will throw an
error:
Dog::eat('cookie');
Result:
Fatal error: Using $this when not in object context
PHP 5 features static class members. It requires you to define what
methods and properties can be used statically. Static properties work
the same as regular static variables, if you are unfamiliar with static
variables, have a thorough read on Variable Scope in the manual.
class Dog {
        static $hungry = 'hell yeah.';
        
        static function eat($food)
        {
                if($food == 'cookie')
                {
                        self::$hungry = 'not so much.';
                }
                else 
                {
                        echo 'barf, I only like cookies!';
                }
        }
}
Dog::eat('cookie');
echo Dog::$hungry;
Note
the self keyword. It is simply referring to this class declaration.
Like with the parent keyword, alternatively one could use the actual
name of the class (Dog).

2.5 Abstract Classes

Abstract classes are, well, abstract. An abstract class isn’t intended
to be instantiated, but to serve as a parent to other classes, partly
dictating how they should behave. Abstract classes can have abstract
methods, these are required in the child classes.
Abstract classes can be used to enforce a certain interface.
An example:
abstract class Animal {       
        public $hungry = 'hell yeah.';
        
        abstract public function eat($food);
}
class Dog extends Animal
{
        function eat($food)
        {
                if($food == 'cookie')
                {
                        $this->hungry = 'not so much.';
                }
                else 
                {
                        echo 'barf, I only like cookies!';
                }
        }
}
$dog = new Dog();
echo $dog->hungry; //echoes "hell yeah."
$dog->eat('peanut'); //echoes "barf, I only like cookies!"

3 Beyond the Absolute Basics

3.1 Object Handles
In PHP5, objects are defined by handles, not unlike resource type variables.
Passing an object to a function doesn’t make a copy of it. Have a
read on References Explained if you’re still a little confused by this.
3.2 Interfaces
PHP5 features interfaces. Not to be confused with interfaces in the more
general sense, the interface keyword creates an entity that can be used
to enforce a common interface upon classes without having to extend
them like with abstract classes. Instead an interface is implemented.
Interfaces are different from abstract classes. For one, they’re not
actually classes. They don’t define properties, and they don’t define
any behaviour. The methods declared in an interface must be declared in
classes that implement it.
Because an interface in the more general sense is a definition of how
an object interacts with other code, all methods must be declared
public (see section on visibility in this chapter). Using abstract
classes, an abstract method can have any visibility, but the extending
classes must have their implementations use the same (or weaker)
visibility. Implementing an interface adds the methods as abstract
methods to the subject class, failure to implement it will result in an
error like the following:
Fatal error: Class SomeConcreteClass contains n abstract
method(s) and must therefore be declared abstract or implement the
remaining methodsYes, abstract classes can implement interfaces.

Interfaces can be looked upon as a contract, a certificate of
compliance if you will. Other code is guaranteed that a class
implementing it will use certain methods to interact.
Enough babbling, let’s see a code example:
interface Animal {
        public function eat($food);
}
interface Mammal {
        public function giveBirth();
}
class Dog implements Animal, Mammal
{
        public $gender = 'male';
        
        function eat($food)
        {
                if($food == 'cookie')
                {
                        $this->hungry = 'not so much.';
                }
                else 
                {
                        echo 'barf, I only like cookies!';
                }
        }
        function giveBirth()
        {
                if($this->gender == 'male')
                {
                        echo 'I can\'t, I am a boy :P';
                }
                else 
                {
                        echo 'I\'m not even pregnant yet.';     
                }
        }
}
Doggie implements 2 interfaces, both Animal and Mammal. You can implement as many interfaces as you like.
3.3 Autoload
A very convenient feature, __autoload allows you to get rid of all those
annoying includes that need to be managed. This magic function will
execute whenever a class or interface is referenced that hasn’t been
defined. That gives you the opportunity to include it.
Here’s a simple example of how that might look using the standard
PEAR naming scheme (the segments between underscores become directory
names, bar the last, which becomes the filename):
function __autoload($className) {
        $file = str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php';

        if(!file_exists($file))
        {
                return false;
        }
        else 
        {
                require_once $file;
        }
}
new Foo_Bar(); //Maps to ‘Foo/Bar.php’
We
don’t really need require_once, because once the file is included,
__autoload will not trigger on that class or interface reference again.
3.4 Destructors
Destructors are another type of magic methods. Indicated by __destruct,
these methods are called when all references to their objects are
removed. This includes explicit un-setting and script shutdown. A quick
example of this:
class Example {
        private $_name;
        
        public function __construct($name)
        {
                $this->_name = $name;
        }
        function __destruct() 
        {
                echo "Destructing object '$this->_name'." . PHP_EOL;
        }
}

$objectOne = new Example('Object one');
$objectTwo = new Example('Object two');
unset($objectOne);
echo 'Script still running.' . PHP_EOL;
This echoes:


Destructing object 'Object one'.

Script still running.

Destructing object 'Object two'.


Object one is destructed when we explicitly unset it, object two just
before the script execution is completed. An object’s destructor is
always executed (or rather ‘should be’: don’t rely on this mechanism too
much). Note that if we had created a second object from within class
Example, it’s destructor would also have been executed, as it would have
removed all references to the embedded object.
3.5 Visibility
PHP 5 allows you to declare the visibility of methods and properties.
There are three types of visibility: public, protected and private.
Public

Public methods and properties are visible (accessible) to any code that
queries them. No accessibility restrictions are applied. In PHP 5,
methods without visibility declaration are assumed public, the
visibility declaration is required, excluding static class members (if
you don’t include it, ‘public’ is assumed). Class constants are always
globally available.
Protected

Requests are only allowed from within the objects blueprint (that
includes parent and child classes). Meaning the following would fail:
class Teeth {
        protected $_colour = 'white';
        
        public function stain()
        {
                $this->_colour = 'yellow';
        }       }
class Dog {
        public $teeth;
        
        public function __construct()
        {
                $this->teeth = new Teeth();
        }
        public function eat($food)
        {
                if($food == 'cookie')
                {
                        $this->hungry = 'not so much.';
                        //Attempt to turn teeth green:
                        $this->teeth->_colour = 'green'; 

                }
                else 
                {
                        echo 'barf, I only like cookies!';
                }
        }
}
$dog = new Dog();
Produces:
Fatal error: Cannot access protected property Teeth::$_colour
Should Teeth have been a parent class of Dog instead of a member
object (class Dog extends Teeth - don’t do that), $colour would have
been accessible though $this, but also statically by Teeth::$_colour (or
parent::$_colour).
Private

Access is limited to the declaring class (the class the property is declared in). No external access whatsoever is allowed.
One thing that should be noted when using protected or private
properties, is that if you attempt to assign a value to a property that
isn’t visible to the class you are doing it in, you will be creating a
new property instead of resetting the original. Keep that in mind when
you get unexpected values: check the property’s visibility.
3.6 Class Constants
We already covered using static class members, there is another type of class member, which we haven’t covered: class constants.
I am assuming you are already familiar with regular constants, and are aware of how they differ from variables.
Class constants are just regular constants, declared in a class. It’s
reference is obtained through the class scope. Because constants are
unchangeable, they are independent of any state the object could be in.
Therefore they can only be called statically.
class Dog {
        const NUMBER_OF_LEGS = '4';
        
        public function __construct()
        {
                echo 'I have '.self::NUMBER_OF_LEGS.' legs, 
                and you can\'t take that away from me!';
        }
}
$dog = new Dog();
Both
$dog->NUMBER_OF_LEGS and $this->NUMBER_OF_LEGS would have PHP
looking for a non-existent object property: $NUMBER_OF_LEGS.
Class constants are always publicly accessible. Any code can call Dog::NUMBER_OF_LEGS.
3.7 Type Hinting
PHP 5 features type hinting as a means to limit the types of variables
that a method will accept as an argument. Let’s kick off with a simple
example:
class Rabbit {}
class Feeder {
        public function feedRabbit(Rabbit $rabbit, $food)
        {
                $rabbit->eat($food);
        }
}
$dog = new Dog();
$feeder = new Feeder();
$feeder->feedRabbit($dog, 'broccoli');
Attempting to use an instance of Dog with the feedRabbit method results in the following error:
Fatal error: Argument 1 passed to Feeder::feedRabbit() must be an instance of Rabbit
However, type hinting allows a more generic use. Consider the following example:
class Animal {}
class Feeder {
        public function feedAnimal(Animal $animal, $food)
        {
                $animal->eat($food);
        }
}
class Dog extends Animal {
        public function eat($food)
        {
                if($food == 'cookie')
                {
                        $this->hungry = 'not so much.';

                }
                        else 
                {
                        echo 'barf, I only like cookies!';
                }
        }
}
$dog = new Dog();
$feeder = new Feeder();
$feeder->feedAnimal($dog, 'broccoli');
Because
$dog is not only a Dog, but also an Animal, the requirement is met.
Doggie doesn’t like broccoli (who does?), but that is besides the point.
Currently PHP only supports type hinting with objects and arrays.
Note: since PHP 5.2, failing type hinting requirements result in a E_RECOVERABLE_ERROR type error, not an immediate fatal error.
3.8 Exceptions
PHP 5 introduces the concept of exceptions to PHP. An exception is not an error, an uncaught exception is (a fatal error).
Using exceptions you will need the following keywords: try, throw and
catch. PHP 5 has it’s build-in Exception class, which you can extend.
You can have multiple catch blocks following a try block. PHP will
execute the first catch block that matches the type of the exception
thrown. If no exception is thrown or none of the catch declarations
match the thrown exception type, no catch blocks are executed.
class LiarException extends Exception {}
try {
        if($doggy->talk() == 'Doggie likes broccoli.')
        {
                throw new LiarException(
                        'Doggie is a big fat liar. He only likes cookies.'
                );
        }
        else 
        {
                throw new Exception('Just because we can.');
        }
        echo 'An exception was thrown, so this will never print...';
} catch(LiarException $e)
{
        echo "Somebody lied about something: {$e->getMessage()}'";
}
catch(Exception $e)
{
        echo "Somebody threw an exception: {$e->getMessage()}'";
}
In
the example above, the code in the try block is executed until an
exception is thrown. If an exception is thrown, the code in the
corresponding catch block is executed. As noted, PHP executes the FIRST
matching catch block. So if we switched the catch blocks, the first
block would be executed, even though the second is a ‘closer match’.
If there isn’t a corresponding catch block, the exception is ‘falls
through’. Assuming the call to the code is not itself contained in a try
block, the exception is uncaught, resulting in a fatal error.
3.9 The Final Keyword
The final keyword indicates that the declaration following it is final,
no child class will be able to redefine it. One can declare both a
single method or a whole class as final. If the whole class is declared
final, it becomes un-extendable: no child classes are allowed.
There really isn’t much more to it, apply it only if you are
absolutely sure you don’t want that specific class or method extended or
re-declared respectively.
3.10 More Magic Methods
Aside from __construct, __destruct, there are quite a few more magic methods:
Overloading
  • __call
  • __get
  • __set
  • __isset
  • __unset
Object cloning
  • __clone
Serialization
  • __sleep
  • __wakeup
Other
  • __toString
  • __setState
3.10.1 Object Overloading

If you’re coming from a different OO language, the term ‘overloading’
likely has a very different meaning to you: defining different method
with the same name having different signatures. This has nothing to do
with that.
Object overloading in PHP refers to the mechanism where a call to a
method or property will ‘overload’ the call to a different property or
method. The call ultimately made can depend on the type of the arguments
or the context.
These magic methods allow you catch calls to methods and properties
that haven’t been defined, because you didn’t know (or didn’t want to
specify) the exact name.
The magic methods are executed only if the object doesn’t have the method or property declared.
The following example class uses __set to check if an embedded object
does have the property requested, before creating a new property for
the parent object.
class DomXml
{
        private $_domDoc;
        
        public function __construct()   
        {
                $this->_domDoc = new DOMDocument();
        }
        private function __set($name, $value)
        {
                if(property_exists($this->_domDoc, $name))
                {
                        $this->_domDoc->$name = $value;
                }
                else 
                {
                        $this->$name = $value;
                }
        }
}
An example __call use:
private function __call($name, $params)
{
        if(method_exists($this->_doc, $name))
        {
                return call_user_func_array(
                        aray($this->_doc, $name), $params
                );
        }
        else 
        {
                throw new DomXmlException(
                        "Call to undeclared method '$name'"
                );
        }
}
Methods __get, __isset and __unset have similar uses.
3.10.2 Object cloning

Because in PHP 5 objects use handles, if you would want to create a copy
of an object you have to explicitly indicate so with the clone keyword.
$obj = new Example();
$objectCopy = clone $obj;
Above gives you a new object that is an exact copy of $obj in the state it was when copied.
The __clone method is triggered by this clone keyword. This allows
you, for example, to ensure embedded objects are also cloned (otherwise
they would this use the same object handle for the embedded objects).
The following example illustrates this:
class Teeth {
        public $colour = 'white';
}
class Dog {       
        public $teeth;
        
        public function __construct()
        {
                $this->teeth = new Teeth();
        }
}
$Lassie = new Dog();
$Snoopy = clone $Lassie;
$Snoopy->teeth->colour = 'green';
echo $Snoopy->teeth->colour . PHP_EOL;
echo $Lassie->teeth->colour . PHP_EOL;
That will echo:


green

green


Changing the property colour to green on $Snoopy’s teeth, also
changes $Lassie’s teeth to green, because they share the same teeth.
Imagine that, two dogs attached at the mouth…
To give Lassie’s clone Snoopy its own set of teeth, we can use the __clone method:
class Dog {       
        public $teeth;
        
        public function __construct()
        {
                $this->teeth = new Teeth();
        }
        
        public function __clone()
        {
                $this->teeth = clone $this->teeth;
        }
}
Now it will output:


green

white


Voila, a cloned Dog now has its own teeth.
3.10.3 Serialization

Resource handles don’t serialize. If one of your properties has a
resource handle as its value, for example a file handle or database
connection, You can use the __wakeup magic to re-establish these
handles. This method will be called when you call
unserialize($serializedObject). The __sleep method is invoked when you
serialize an object, and is expected to return an array of property
names to be included in the serialization. This allows you to exclude
certain properties.
3.10.4 Other

Other methods that don’t fit in the previous categories.
__toString: This magic method can be used to define how an object
will present itself if the whole object is treated as a string.
Example:
class Dog
{
        function __toString()
        {
                return 'I am Dog.';
        }
}
$dog = new Dog();
echo $dog;
Result:
I am Dog.
Note that older versions of PHP 5 didn’t support calling __toString()
when embedding or concatenating in a string. Currently, this will work
as well:
$dog = new Dog();
echo "Doggie says: $dog";


__set_state: This is a static method that can be used to reinitialize an object after being “flattened” by var_export.
3.11 Object Iteration

PHP allows objects to be iterated, all properties visible to the scope
the iteration is requested from are used. Example of this with a foreach
loop:
class ExampleParent {
        protected $propertyOne = 'value1';
        public $propertyTwo = 'value2';
}
class Example extends ExampleParent {
        
        private $propertyThree = 'value3';

        public function __construct()
        {
                echo "Internal iteration of Example:" . PHP_EOL;
                
                foreach($this as $property => $value)
                {
                        echo "Property '$property' => '$value' " . PHP_EOL;
                }
                echo PHP_EOL;
        }
}
$example = new Example();

echo "External iteration of Example:" . PHP_EOL;
foreach($example as $property => $value)
{
        echo "Property '$property' => '$value' " . PHP_EOL;
}
echo PHP_EOL;

$exampleParent = new ExampleParent();

echo "External iteration of ExampleParent:" . PHP_EOL;
foreach($exampleParent as $property => $value)
{
        echo "Property '$property' => '$value' " . PHP_EOL;
}
Output:


Internal iteration of Example:

Property 'propertyThree' => 'value3'

Property 'propertyOne' => 'value1'

Property 'propertyTwo' => 'value2'

External iteration of Example:

Property 'propertyTwo' => 'value2'

External iteration of ExampleParent:

Property 'propertyTwo' => 'value2'


You’ll notice that the external iteration doesn’t list the private and protected properties.

4. Hot off The Press Features

4.1 Namespaces
PHP 5.3 and up offers namespaces which allows you to give your classes
logical names without resorting to really long winded names like the
ones caused by the PEAR naming standard.
Simply put, the PEAR naming standard defines pseudo namespaces, which
map to a location on the file system (see section Autoload). A name
like the following:
Application_Input_Validate_PhoneNumber_Us
Would map to Application/Input/Validate/PhoneNumber/Us.php
Sometimes these names get way bigger than this. Here’s a different example, from Zend Framework:
Zend_Controller_Action_Helper_AutoComplete_Abstract
It can get even bigger.
PHP 5.3+ namespaces solves this by creating aliases.
namespace Application::Input::Validate::PhoneNumber
class Us {
}
Now, I could call this:
$validator = new Application::Input::Validate::PhoneNumber::Us($arg);
But that can hardly be called an improvement, can it?
Instead, knowing that I am going to use a phone number validator, I can create a namespace alias:
use Application::Input::Validate::PhoneNumber as PhoneValidators

$validator = new PhoneValidators::Us($arg);
Better,
no? It saves me having to refer to the fully quantified class name, and
I can select the right validator class in my client code without
littering it with repeated lengthy namespace selections.
I can also create an alias for a class name. For example:
use Framework::Controller::Response::Http HttpResponse

$response = new HttpResponse();
The
fully quantified name of the class includes the namespace. Hence,
calling var_dump on the above $response object would output something
like the following:


object(Framework::Controller::Response::Http)#1 (0) {

}


This allows us to mend our __autoload function to load classes in a namespace:
function __autoload($className) {
        $file = str_replace('::', DIRECTORY_SEPARATOR, $className) . '.php';

        if(!file_exists($file))
        {
                return false;
        }
        else 
        {
                require_once $file;
        }
}
4.2 Late static binding
In PHP 5.2, you can already do this:
abstract class ParentClass
{
        public static function foo()
        {
                echo 'blah';
        }
}
class ImplementationClass extends ParentClass
{}
ImplementationClass::foo();
Static
methods are inherited. But without late static binding, ParentClass
will not be able to invoke any static methods of ImplementationClass,
like in this non-static example:
abstract class ParentClass
{
        public function foo()
        {
                $this->meh();
        }
}
class ImplementationClass extends ParentClass
{
        public function meh()
        {
                echo 'blah';
        }
}

$impl = new ImplementationClass();
$impl->foo();
If we wanted meh to be static, it would be tempting to try this:
abstract class ParentClass
{
        public function foo()
        {
                self::meh();
        }
}
class ImplementationClass extends ParentClass
{
        public static function meh()
        {
                echo 'blah';
        }
}
ImplementationClass::foo();
But self refers to the current class scope, ParentClass in this case, so we produce this error:
Fatal error: Call to undefined method ParentClass::meh()
In PHP5.3+, self still points to the current class reference. To make
the above scenario possible, a new use is given to the static keyword:
abstract class ParentClass
{
        public static function foo()
        {
                static::meh();
        }
}
class ImplementationClass extends ParentClass
{
        public static function meh()
        {
                echo 'blah';
        }
}
ImplementationClass::foo();
Above will echo ‘blah’ on PHP5.3+.
But, all is not as simple as it seems. The static keyword doesn’t
take inheritance into account, like $this does. Instead it tries to
resolve the correct call.
The following code will fail:
abstract class ParentClass
{
        public static function delegate()
        {
                static::meh();
        }
}
class ImplementationClass extends ParentClass
{
        public static function meh()
        {
                echo 'blah';
        }
        public static function foo()
        {
                parent::delegate();
        }
}
ImplementationClass::foo();
Because
'parent' resolves to ParentClass, 'static' in delegate() resolves to
ParentClass as well. But ParentClass doesn’t have a method called ‘meh’;
the dreaded fatal error we got before is inescapable. You’ll get
similar results trying it with multiple levels of inheritance, a fully
resolved method call (ParentClass::delegate()), or with static
properties instead of methods.
In summary: if you want to use this new feature, be very aware of its limitations.