PHP1
PHP1
class
Every class definition begins with the keyword class, followed by a class name, which can be
any name that isn't a reserved word in PHP. Followed by a pair of curly braces, which contains
the definition of the classes members and methods. A pseudo-variable, $this is available when
a method is called from within an object context. $this is a reference to the calling object
(usually the object to which the method belongs, but can be another object, if the method is
called statically from the context of a secondary object). This is illustrated in the following
examples:
<?php
class A
{
function foo()
{
if (isset($this)) {
echo '$this is defined (';
echo get_class($this);
echo ")\n";
} else {
echo "\$this is not defined.\n";
}
}
}
class B
{
function bar()
{
A::foo();
}
}
$a = new A();
$a->foo();
A::foo();
$b = new B();
$b->bar();
B::bar();
?>
<?php
class SimpleClass
{
// member declaration
public $var = 'a default value';
// method declaration
public function displayVar() {
echo $this->var;
}
}
?>
The default value must be a constant expression, not (for example) a variable, a class member
or a function call.
<?php
class SimpleClass
{
// invalid member declarations:
public $var1 = 'hello '.'world';
public $var2 = <<<EOD
hello world
EOD;
public $var3 = 1+2;
public $var4 = self::myStaticMethod();
public $var5 = $myVar;
}
?>
Example #4 Static data example
<?php
class foo {
// As of PHP 5.3.0
public $bar = <<<'EOT'
bar
EOT;
}
?>
new
To create an instance of a class, a new object must be created and assigned to a variable. An
object will always be assigned when creating a new object unless the object has a constructor
defined that throws an exception on error. Classes should be defined before instantiation (and in
some cases this is a requirement).
<?php
$instance = new SimpleClass();
?>
In the class context, it is possible to create a new object by new self and new parent.
When assigning an already created instance of a class to a new variable, the new variable will
access the same instance as the object that was assigned. This behaviour is the same when
passing instances to a function. A copy of an already created object can be made by cloning it.
extends
A class can inherit methods and members of another class by using the extends keyword in the
declaration. It is not possible to extend multiple classes, a class can only inherit one base class.
The inherited methods and members can be overridden, unless the parent class has defined a
method as final, by redeclaring them with the same name defined in the parent class. It is
possible to access the overridden methods or static members by referencing them with parent::
<?php
class ExtendClass extends SimpleClass
{
// Redefine the parent method
function displayVar()
{
echo "Extending class\n";
parent::displayVar();
}
}
Extending class
a default value
Autoloading Objects
Many developers writing object-oriented applications create one PHP source file per-class
definition. One of the biggest annoyances is having to write a long list of needed includes at the
beginning of each script (one for each class).
In PHP 5, this is no longer necessary. You may define an __autoload function which is
automatically called in case you are trying to use a class/interface which hasn't been defined
yet. By calling this function the scripting engine is given a last chance to load the class before
PHP fails with an error.
Note: Exceptions thrown in __autoload function cannot be caught in the catch block and results
in a fatal error.
Note: If the class name is used e.g. in call_user_func() then it can contain some dangerous
characters such as ../. It is recommended to not use the user-input in such functions or at least
verify the input in __autoload().
This example attempts to load the classes MyClass1 and MyClass2 from the files MyClass1.php
and MyClass2.php respectively.
<?php
function __autoload($class_name) {
require_once $class_name . '.php';
}
<?php
function __autoload($name) {
var_dump($name);
}
/*
string(5) "ITest"
Constructor
PHP 5 allows developers to declare constructor methods for classes. Classes which have a
constructor method call this method on each newly-created object, so it is suitable for any
initialization that the object may need before it is used.
Note: Parent constructors are not called implicitly if the child class defines a constructor. In
order to run a parent constructor, a call to parent::__construct() within the child constructor is
required.
<?php
class BaseClass {
function __construct() {
print "In BaseClass constructor\n";
}
}
Destructor
PHP 5 introduces a destructor concept similar to that of other object-oriented languages, such
as C++. The destructor method will be called as soon as all references to a particular object are
removed or when the object is explicitly destroyed or in any order in shutdown sequence.
<?php
class MyDestructableClass {
function __construct() {
print "In constructor\n";
$this->name = "MyDestructableClass";
}
function __destruct() {
print "Destroying " . $this->name . "\n";
}
}
Like constructors, parent destructors will not be called implicitly by the engine. In order to run a
parent destructor, one would have to explicitly call parent::__destruct() in the destructor body.
Note: Destructors called during the script shutdown have HTTP headers already sent. The
working directory in the script shutdown phase can be different with some SAPIs (e.g. Apache).
Note: Attempting to throw an exception from a destructor (called in the time of script termination)
causes a fatal error.
Visibility
The visibility of a property or method can be defined by prefixing the declaration with the
keywords: public, protected or private. Public declared items can be accessed everywhere.
Protected limits access to inherited and parent classes (and to the class that defines the item).
Private limits visibility only to the class that defines the item.
Members Visibility
<?php
/**
* Define MyClass
*/
class MyClass
{
public $public = 'Public';
protected $protected = 'Protected';
private $private = 'Private';
function printHello()
{
echo $this->public;
echo $this->protected;
echo $this->private;
}
}
/**
* Define MyClass2
*/
class MyClass2 extends MyClass
{
// We can redeclare the public and protected method, but not private
protected $protected = 'Protected2';
function printHello()
{
echo $this->public;
echo $this->protected;
echo $this->private;
}
}
?>
Note: The PHP 4 method of declaring a variable with the var keyword is still supported for
compatibility reasons (as a synonym for the public keyword). In PHP 5 before 5.1.3, its usage
would generate an E_STRICT warning.
Method Visibility
Class methods must be defined with public, private, or protected. Methods without any
declaration are defined as public.
<?php
/**
* Define MyClass
*/
class MyClass
{
// Declare a public constructor
public function __construct() { }
// This is public
function Foo()
{
$this->MyPublic();
$this->MyProtected();
$this->MyPrivate();
}
}
/**
* Define MyClass2
*/
class MyClass2 extends MyClass
{
// This is public
function Foo2()
{
$this->MyPublic();
$this->MyProtected();
$this->MyPrivate(); // Fatal Error
}
}
$myclass2 = new MyClass2;
$myclass2->MyPublic(); // Works
$myclass2->Foo2(); // Public and Protected work, not Private
class Bar
{
public function test() {
$this->testPrivate();
$this->testPublic();
}
The Scope Resolution Operator (also called Paamayim Nekudotayim) or in simpler terms, the
double colon, is a token that allows access to static, constant, and overridden members or
methods of a class.
When referencing these items from outside the class definition, use the name of the class.
As of PHP 5.3.0, it's possible to reference the class using a variable. The variable's value can
not be a keyword (e.g. self, parent and static).
Paamayim Nekudotayim would, at first, seem like a strange choice for naming a double-colon.
However, while writing the Zend Engine 0.5 (which powers PHP 3), that's what the Zend team
decided to call it. It actually does mean double-colon - in Hebrew!
$classname = 'MyClass';
echo $classname::CONST_VALUE; // As of PHP 5.3.0
echo MyClass::CONST_VALUE;
?>
Two special keywords self and parent are used to access members or methods from inside the
class definition.
<?php
class OtherClass extends MyClass
{
public static $my_static = 'static var';
$classname = 'OtherClass';
echo $classname::doubleColon(); // As of PHP 5.3.0
OtherClass::doubleColon();
?>
When an extending class overrides the parents definition of a method, PHP will not call the
parent's method. It's up to the extended class on whether or not the parent's method is called.
This also applies to Constructors and Destructors, Overloading, and Magic method definitions.
Static Keyword
Declaring class members or methods as static makes them accessible without needing an
instantiation of the class. A member declared as static can not be accessed with an instantiated
class object (though a static method can).
For compatibility with PHP 4, if no visibility declaration is used, then the member or method will
be treated as if it was declared as public.
Because static methods are callable without an instance of the object created, the pseudo
variable $this is not available inside the method declared as static.
Static properties cannot be accessed through the object using the arrow operator ->.
<?php
class Foo
{
public static $my_static = 'foo';
<?php
class Foo {
public static function aStaticMethod() {
// ...
}
}
Foo::aStaticMethod();
$classname = 'Foo';
$classname::aStaticMethod(); // As of PHP 5.3.0
?>
Class Constants
It is possible to define constant values on a per-class basis remaining the same and
unchangeable. Constants differ from normal variables in that you don't use the $ symbol to
declare or use them.
The value must be a constant expression, not (for example) a variable, a class member, result
of a mathematical operation or a function call.
As of PHP 5.3.0, it's possible to reference the class using a variable. The variable's value can
not be a keyword (e.g. self, parent and static).
<?php
class MyClass
{
const constant = 'constant value';
function showConstant() {
echo self::constant . "\n";
}
}
$classname = "MyClass";
echo $classname::constant . "\n"; // As of PHP 5.3.0
<?php
class foo {
// As of PHP 5.3.0
const bar = <<<'EOT'
bar
EOT;
}
?>
Class Abstraction
PHP 5 introduces abstract classes and methods. It is not allowed to create an instance of a
class that has been defined as abstract. Any class that contains at least one abstract method
must also be abstract. Methods defined as abstract simply declare the method's signature they
cannot define the implementation.
When inheriting from an abstract class, all methods marked abstract in the parent's class
declaration must be defined by the child; additionally, these methods must be defined with the
same (or a less restricted) visibility. For example, if the abstract method is defined as protected,
the function implementation must be defined as either protected or public, but not private.
<?php
abstract class AbstractClass
{
// Force Extending class to define this method
abstract protected function getValue();
abstract protected function prefixValue($prefix);
// Common method
public function printOut() {
print $this->getValue() . "\n";
}
}
ConcreteClass1
FOO_ConcreteClass1
ConcreteClass2
FOO_ConcreteClass2
Old code that has no user-defined classes or functions named 'abstract' should run without
modifications.
Object Interfaces
Object interfaces allow you to create code which specifies which methods a class must
implement, without having to define how these methods are handled.
Interfaces are defined using the interface keyword, in the same way as a standard class, but
without any of the methods having their contents defined.
All methods declared in an interface must be public, this is the nature of an interface.
implements
To implement an interface, the implements operator is used. All methods in the interface must
be implemented within a class; failure to do so will result in a fatal error. Classes may implement
more than one interface if desired by separating each interface with a comma.
Note: A class cannot implement two interfaces that share function names, since it would cause
ambiguity.
Examples
<?php
// Declare the interface 'iTemplate'
interface iTemplate
{
public function setVariable($name, $var);
public function getHtml($template);
}
return $template;
}
}
?>
Overloading
Overloading in PHP provides means to dynamically "create" members and methods. These
dynamic entities are processed via magic methods one can establish in a class for various
action types.
The overloading methods are invoked when interacting with members or methods that have not
been declared or are not visible in the current scope. The rest of this section will use the terms
"inaccessible members" and "inaccessible methods" to refer to this combination of declaration
and visibility.
Note: None of the arguments of these magic methods can be passed by reference.
Note: PHP's interpretation of "overloading" is different than most object oriented languages.
Overloading traditionally provides the ability to have multiple methods with the same name but
different quantities and types of arguments.
ChangeLog
Version Description
5.1.0 Added __isset() and __unset().
Version Description
5.3.0 Added __callStatic().
Member overloading
The $name argument is the name of the member being interacted with. The __set() method's
$value argument specifies the value the $name'ed member should be set to.
Member overloading only works in object context. These magic methods will not be triggered in
static context. Therefore these methods can not be declared static.
<?php
class MemberTest {
/** Location for overloaded data. */
private $data = array();
$trace = debug_backtrace();
trigger_error(
'Undefined property: ' . $name .
' in ' . $trace[0]['file'] .
' on line ' . $trace[0]['line'],
E_USER_NOTICE);
return null;
}
echo "<pre>\n";
$obj->a = 1;
echo $obj->a . "\n";
var_dump(isset($obj->a));
unset($obj->a);
var_dump(isset($obj->a));
Method overloading
The $name argument is the name of the method being called. The $arguments argument is an
enumerated array containing the parameters passed to the $name'ed method.
<?php
class MethodTest {
public function __call($name, $arguments) {
// Note: value of $name is case sensitive.
echo "Calling object method '$name' "
. implode(', ', $arguments). "\n";
}
PHP 5 provides a way for objects to be defined so it is possible to iterate through a list of items,
with, for example a foreach statement. By default, all visible properties will be used for the
iteration.
<?php
class MyClass
{
public $var1 = 'value 1';
public $var2 = 'value 2';
public $var3 = 'value 3';
function iterateVisible() {
echo "MyClass::iterateVisible:\n";
foreach($this as $key => $value) {
print "$key => $value\n";
}
}
}
$class->iterateVisible();
?>
MyClass::iterateVisible:
var1 => value 1
var2 => value 2
var3 => value 3
protected => protected var
private => private var
As the output shows, the foreach iterated through all visible variables that can be accessed. To
take it a step further you can implement one of PHP 5's internal interface named Iterator. This
allows the object to decide what and how the object will be iterated.
<?php
class MyIterator implements Iterator
{
private $var = array();
$values = array(1,2,3);
$it = new MyIterator($values);
rewinding
current: 1
valid: 1
current: 1
key: 0
0: 1
next: 2
current: 2
valid: 1
current: 2
key: 1
1: 2
next: 3
current: 3
valid: 1
current: 3
key: 2
2: 3
next:
current:
valid:
You can also define your class so that it doesn't have to define all the Iterator functions by
simply implementing the PHP 5 IteratorAggregate interface.
<?php
class MyCollection implements IteratorAggregate
{
private $items = array();
private $count = 0;
// Required definition of interface IteratorAggregate
public function getIterator() {
return new MyIterator($this->items);
}
rewinding
current: value 1
valid: 1
current: value 1
key: 0
key/value: [0 -> value 1]
next: value 2
current: value 2
valid: 1
current: value 2
key: 1
key/value: [1 -> value 2]
next: value 3
current: value 3
valid: 1
current: value 3
key: 2
key/value: [2 -> value 3]
next:
current:
valid:
Patterns
Patterns are ways to describe best practices and good designs. They show a flexible solution to
common programming problems.
Factory
The Factory pattern allows for the instantiation of objects at runtime. It is called a Factory
Pattern since it is responsible for "manufacturing" an object. A Parameterized Factory receives
the name of the class to instantiate as argument.
<?php
class Example
{
// The parameterized factory method
public static function factory($type)
{
if (include_once 'Drivers/' . $type . '.php') {
$classname = 'Driver_' . $type;
return new $classname;
} else {
throw new Exception ('Driver not found');
}
}
}
?>
Defining this method in a class allows drivers to be loaded on the fly. If the Example class was a
database abstraction class, loading a MySQL and SQLite driver could be done as follows:
<?php
// Load a MySQL Driver
$mysql = Example::factory('MySQL');
Singleton
The Singleton pattern applies to situations in which there needs to be a single instance of a
class. The most common example of this is a database connection. Implementing this pattern
allows a programmer to make this single instance easily accessible by many other objects.
<?php
class Example
{
// Hold an instance of the class
private static $instance;
// A private constructor; prevents direct creation of object
private function __construct()
{
echo 'I am constructed';
}
return self::$instance;
}
// Example method
public function bark()
{
echo 'Woof!';
}
?>
<?php
// This would fail because the constructor is private
$test = new Example;
?>
Magic Methods
The function names __construct, __destruct (see Constructors and Destructors), __call,
__callStatic, __get, __set, __isset, __unset (see Overloading), __sleep, __wakeup, __toString,
__set_state and __clone are magical in PHP classes. You cannot have functions with these
names in any of your classes unless you want the magic functionality associated with them.
Caution
PHP reserves all function names starting with __ as magical. It is recommended that you do not
use function names with __ in PHP unless you want some documented magic functionality.
serialize() checks if your class has a function with the magic name __sleep. If so, that function is
executed prior to any serialization. It can clean up the object and is supposed to return an array
with the names of all variables of that object that should be serialized. If the method doesn't
return anything then NULL is serialized and E_NOTICE is issued.
The intended use of __sleep is to commit pending data or perform similar cleanup tasks. Also,
the function is useful if you have very large objects which do not need to be saved completely.
Conversely, unserialize() checks for the presence of a function with the magic name __wakeup.
If present, this function can reconstruct any resources that the object may have.
The intended use of __wakeup is to reestablish any database connections that may have been
lost during serialization and perform other reinitialization tasks.
<?php
class Connection {
protected $link;
private $server, $username, $password, $db;
__toString
The __toString method allows a class to decide how it will react when it is converted to a string.
<?php
// Declare a simple class
class TestClass
{
public $foo;
Hello
It is worth noting that before PHP 5.2.0 the __toString method was only called when it was
directly combined with echo() or print(). Since PHP 5.2.0, it is called in any string context (e.g. in
printf() with %s modifier) but not in other types contexts (e.g. with %d modifier). Since PHP
5.2.0, converting objects without __toString method to string would cause
E_RECOVERABLE_ERROR.
__set_state
This static method is called for classes exported by var_export() since PHP 5.1.0.
The only parameter of this method is an array containing exported properties in the form
array('property' => value, ...).
class A
{
public $var1;
public $var2;
$a = new A;
$a->var1 = 5;
$a->var2 = 'foo';
?>
object(A)#2 (2) {
["var1"]=>
int(5)
["var2"]=>
string(3) "foo"
}
Final Keyword
PHP 5 introduces the final keyword, which prevents child classes from overriding a method by
prefixing the definition with final. If the class itself is being defined final then it cannot be
extended.
<?php
class BaseClass {
public function test() {
echo "BaseClass::test() called\n";
}
final public function moreTesting() {
echo "BaseClass::moreTesting() called\n";
}
}
<?php
final class BaseClass {
public function test() {
echo "BaseClass::test() called\n";
}
Object cloning
Creating a copy of an object with fully replicated properties is not always the wanted behavior. A
good example of the need for copy constructors, is if you have an object which represents a
GTK window and the object holds the resource of this GTK window, when you create a
duplicate you might want to create a new window with the same properties and have the new
object hold the resource of the new window. Another example is if your object holds a reference
to another object which it uses and when you replicate the parent object you want to create a
new instance of this other object so that the replica has its own separate copy.
An object copy is created by using the clone keyword (which calls the object's __clone() method
if possible). An object's __clone() method cannot be called directly.
When an object is cloned, PHP 5 will perform a shallow copy of all of the object's properties.
Any properties that are references to other variables, will remain references. If a __clone()
method is defined, then the newly created object's __clone() method will be called, to allow any
necessary properties that need to be changed.
Example #1 Cloning an object
<?php
class SubObject
{
static $instances = 0;
public $instance;
class MyCloneable
{
public $object1;
public $object2;
function __clone()
{
// Force a copy of this->object, otherwise
// it will point to same object.
$this->object1 = clone $this->object1;
}
}
print("Original Object:\n");
print_r($obj);
print("Cloned Object:\n");
print_r($obj2);
?>
Original Object:
MyCloneable Object
(
[object1] => SubObject Object
(
[instance] => 1
)
[object2] => SubObject Object
(
[instance] => 2
)
)
Cloned Object:
MyCloneable Object
(
[object1] => SubObject Object
(
[instance] => 3
)
Comparing objects
In PHP 5, object comparison is more complicated than in PHP 4 and more in accordance to
what one will expect from an Object Oriented Language (not that PHP 5 is such a language).
When using the comparison operator (==), object variables are compared in a simple manner,
namely: Two object instances are equal if they have the same attributes and values, and are
instances of the same class.
On the other hand, when using the identity operator (===), object variables are identical if and
only if they refer to the same instance of the same class.
<?php
function bool2str($bool)
{
if ($bool === false) {
return 'FALSE';
} else {
return 'TRUE';
}
}
class Flag
{
public $flag;
class OtherFlag
{
public $flag;
$o = new Flag();
$p = new Flag();
$q = $o;
$r = new OtherFlag();