Learning Objectives – after this chapter you will be able to:
- Define classes with properties, methods and constants, and create objects with
new. - Use the pseudo-variable
$this, constructors and destructors. - Control access with
public,protectedandprivate. - Inherit with
extends, override methods and call the parent withparent::. - Use the scope resolution operator
::,self,staticmembers and autoloading.
Classes and Objects
Object-oriented programming (OOP) organises a program around objects that combine data and the functions that work on that data. A class is the blueprint; an object is an instance created from it. A Car class describes what every car has (colour, speed) and can do (accelerate, brake); each actual car is an object.
A basic class definition begins with the keyword class, followed by a class name and a pair of curly braces that enclose the definitions of the properties (variables) and methods (functions) of the class. The class name can be any valid label that is not a PHP reserved word: it starts with a letter or underscore, followed by letters, numbers or underscores. A class may contain its own constants, properties and methods.
<?php
class SimpleClass
{
// property declaration
public $var = 'a default value';
// method declaration
public function displayVar()
{
echo $this->var;
}
}
$obj = new SimpleClass();
$obj->displayVar();
echo "<br>";
$obj->var = "a new value"; // change a public property
$obj->displayVar();
?>a default value a new value
The Pseudo-Variable $this
$this is available when a method is called from within an object context. It is a reference to the calling object – the object on which the method was called. Inside a class, properties and methods are accessed as $this->property and $this->method().
<?php
class A
{
function foo()
{
if (isset($this)) {
echo '$this is defined (' . get_class($this) . ")<br>";
} else {
echo "\$this is not defined.<br>";
}
}
}
$a = new A();
$a->foo();
?>$this is defined (A)
In PHP 5 a non-static method could also be called statically (A::foo()), and then $this was not defined. In PHP 8 calling a non-static method statically throws an Error, so only the object call shown above is valid.
Creating Objects – new
To create an instance of a class, the new keyword is used. An object is always created unless the class has a constructor that throws an exception. Classes should be defined before instantiation. If a string containing the name of a class is used with new, an instance of that class is created (if the class is in a namespace, its fully qualified name must be used).
<?php
class Foo { public $name = "Foo object"; }
$instance = new Foo();
$className = 'Foo';
$second = new $className(); // same as new Foo()
echo $instance->name . "<br>";
echo get_class($second) . "<br>";
var_dump($instance instanceof Foo);
?>Foo object Foo bool(true)
Properties
Class member variables are called properties (also attributes or fields). They are defined with one of the keywords public, protected or private, optionally followed by a type, and the variable. A property may have an initial value, which must be a constant expression – something PHP can evaluate at compile time without run-time information.
class SimpleClass
{
// valid property declarations (constant expressions):
public $var1 = 'hello ' . 'world'; // allowed since PHP 5.6
public $var2 = <<<EOD
hello world
EOD;
public $var3 = 1 + 2; // allowed since PHP 5.6
public $var6 = MY_CONSTANT;
public $var7 = array(true, false);
public int $count = 0; // typed property (PHP 7.4)
// invalid property declarations:
// public $var4 = self::myStaticMethod(); – function call
// public $var5 = $myVar; – variable
}PHP 4 declared properties with var. PHP 5 and later still accept var and treat it as public. Modern code always writes an explicit visibility keyword.
Within class methods, non-static properties are accessed with $this->property; static properties with self::$property.
Class Constants
It is possible to define constant values per class that remain the same and unchangeable. Constants differ from normal variables in that you do not use the $ symbol to declare or use them. The value must be a constant expression. Interfaces can have constants too. A constant is accessed with ClassName::CONSTANT (or self::CONSTANT inside the class); since PHP 5.3 also through a variable holding the class name or an object.
<?php
class MyClass
{
const CONSTANT = 'constant value';
const GST = 18;
function showConstant()
{
echo self::CONSTANT . "<br>";
}
}
echo MyClass::CONSTANT . "<br>";
$classname = "MyClass";
echo $classname::CONSTANT . "<br>";
$class = new MyClass();
$class->showConstant();
echo $class::CONSTANT . "<br>";
echo "GST rate: " . MyClass::GST . "%";
?>constant value constant value constant value constant value GST rate: 18%
Constructors and Destructors
Constructor
A constructor is a special method named __construct(). Classes that have a constructor call it on each newly created object, so it is the right place for any initialisation the object needs before it is used.
public function __construct(mixed ...$args)
Parent constructors are not called implicitly if the child class defines a constructor. To run the parent constructor, call parent::__construct() inside the child constructor.
<?php
class BaseClass
{
function __construct()
{
print "In BaseClass constructor<br>";
}
}
class SubClass extends BaseClass
{
function __construct()
{
parent::__construct();
print "In SubClass constructor<br>";
}
}
$obj = new BaseClass();
$obj = new SubClass();
?>In BaseClass constructor In BaseClass constructor In SubClass constructor
PHP 8 change. PHP 4 used a method with the same name as the class as its constructor. PHP 5 still accepted these, PHP 7 deprecated them, and PHP 8 removed them – such a method is now just an ordinary method. Always use __construct().
Constructor with parameters and property promotion
Constructors usually receive the initial values of properties. PHP 8 constructor property promotion declares and assigns properties directly in the constructor's parameter list:
<?php
class Student
{
public function __construct(
public string $name,
public int $roll,
private float $fees = 0
) {}
public function show(): string
{
return "Roll $this->roll: $this->name (fees Rs. $this->fees)";
}
}
$s1 = new Student("Asha", 101, 4500);
$s2 = new Student("Ravi", 102);
echo $s1->show() . "<br>";
echo $s2->show();
?>Roll 101: Asha (fees Rs. 4500) Roll 102: Ravi (fees Rs. 0)
Destructor
A destructor, __destruct(), is called as soon as there are no other references to an object, when the object is explicitly destroyed (for example with unset()), or in any order during the shutdown sequence at the end of the script.
<?php
class MyDestructableClass
{
public $name;
function __construct()
{
print "In constructor<br>";
$this->name = "MyDestructableClass";
}
function __destruct()
{
print "Destroying " . $this->name . "<br>";
}
}
$obj = new MyDestructableClass();
echo "Working with the object...<br>";
unset($obj); // destructor runs here
echo "End of script.";
?>In constructor Working with the object... Destroying MyDestructableClass End of script.
- Like constructors, parent destructors are not called implicitly; call
parent::__destruct()explicitly. - The destructor is called even if the script is stopped with
exit(). - Destructors called during script shutdown run after the HTTP headers have been sent, and the working directory may be different with some server APIs (e.g. Apache).
Visibility
The visibility of a property, method or constant is defined by prefixing its declaration with:
| Keyword | Accessible from |
|---|---|
| public | everywhere – inside the class, in child classes and from outside |
| protected | only inside the class itself and in inherited (child) and parent classes |
| private | only inside the class that defines the member |
Properties declared with var (without an explicit keyword) are public. Methods without a keyword are public.
<?php
class Account
{
public $holder = "Asha";
protected $type = "Savings";
private $balance = 5000;
public function showBalance() { return "Balance: Rs. $this->balance"; }
}
class SavingsAccount extends Account
{
public function info() { return "$this->holder has a $this->type account"; }
}
$acc = new SavingsAccount();
echo $acc->holder . "<br>";
echo $acc->info() . "<br>";
echo $acc->showBalance() . "<br>";
echo $acc->balance; // private – not accessible
?>Asha Asha has a Savings account Balance: Rs. 5000 Warning: Undefined property: SavingsAccount::$balance in /opt/lampp/htdocs/phpbook/ch17/visibility.php on line 18
The last line fails because $balance is private to Account: from outside the class it is invisible, so PHP reports it as an undefined property of SavingsAccount. (Reading a private property directly on an Account object throws the error "Cannot access private property".) Hiding data and exposing it only through methods is called encapsulation.
Inheritance – extends
Inheritance is a well-established programming principle. When you extend a class, the subclass inherits all public and protected methods and properties of the parent class. Unless the subclass overrides those methods, they keep their original functionality. This lets you define and abstract shared functionality once and add extra behaviour in similar classes without re-implementing everything.
- A class inherits from another with the keyword
extends. - PHP supports single inheritance: a class can extend only one base class (traits, Chapter 18, provide reuse from several sources).
- Inherited methods and properties can be overridden by re-declaring them with the same name. A method declared
finalin the parent cannot be overridden. - The overridden parent method is still reachable with
parent::method().
Unless autoloading is used, classes must be defined before they are used. If a class extends another, the parent class must be declared before the child class. When overriding a method, its signature must be compatible with the parent's – in PHP 8 an incompatible signature is a fatal error (constructors are exempt).
<?php
class Foo
{
public function printItem($string)
{
echo 'Foo: ' . $string . "<br>";
}
public function printPHP()
{
echo 'PHP is great.' . "<br>";
}
}
class Bar extends Foo
{
public function printItem($string)
{
echo 'Bar: ' . $string . "<br>";
}
}
$foo = new Foo();
$bar = new Bar();
$foo->printItem('baz'); // Output: 'Foo: baz'
$foo->printPHP(); // Output: 'PHP is great'
$bar->printItem('baz'); // Output: 'Bar: baz'
$bar->printPHP(); // Output: 'PHP is great'
?>Foo: baz PHP is great. Bar: baz PHP is great.
<?php
class SimpleClass
{
public $var = 'a default value';
public function displayVar() { echo $this->var . "<br>"; }
}
class ExtendClass extends SimpleClass
{
// Redefine the parent method
function displayVar()
{
echo "Extending class<br>";
parent::displayVar();
}
}
$extended = new ExtendClass();
$extended->displayVar();
?>Extending class a default value
Scope Resolution Operator (::)
The scope resolution operator, in simpler terms the double colon, is a token that allows access to static, constant and overridden properties or methods of a class. From outside the class, use the class name (or, since PHP 5.3, a variable containing it):
<?php
class MyClass
{
const CONST_VALUE = 'A constant value';
}
$classname = 'MyClass';
echo $classname::CONST_VALUE . "<br>";
echo MyClass::CONST_VALUE;
?>A constant value A constant value
Inside the class definition two special keywords are used: self refers to the current class and parent to the parent class.
<?php
class MyClass
{
const CONST_VALUE = 'A constant value';
}
class OtherClass extends MyClass
{
public static $my_static = 'static var';
public static function doubleColon()
{
echo parent::CONST_VALUE . "<br>";
echo self::$my_static . "<br>";
}
}
$classname = 'OtherClass';
$classname::doubleColon();
OtherClass::doubleColon();
?>A constant value static var A constant value static var
When a child class overrides a parent's method, PHP does not call the parent's method automatically – the child decides whether to call it. This also applies to constructors, destructors and magic methods.
<?php
class MyClass
{
protected function myFunc()
{
echo "MyClass::myFunc()<br>";
}
}
class OtherClass extends MyClass
{
// Override parent's definition
public function myFunc()
{
// But still call the parent function
parent::myFunc();
echo "OtherClass::myFunc()<br>";
}
}
$class = new OtherClass();
$class->myFunc();
?>MyClass::myFunc() OtherClass::myFunc()
The static Keyword
Declaring properties or methods as static makes them accessible without creating an object of the class. Static members belong to the class, not to individual objects, so a static property is shared by all objects.
- Because static methods can be called without an object,
$thisis not available inside them. - Static properties are accessed with
ClassName::$propertyorself::$property– not with the arrow operator->. - In PHP 8 calling a non-static method statically throws an
Error.
<?php
class Foo
{
public static $my_static = 'foo';
public function staticValue()
{
return self::$my_static;
}
}
class Bar extends Foo
{
public function fooStatic()
{
return parent::$my_static;
}
}
print Foo::$my_static . "<br>";
$foo = new Foo();
print $foo->staticValue() . "<br>";
print $foo::$my_static . "<br>";
$classname = 'Foo';
print $classname::$my_static . "<br>";
print Bar::$my_static . "<br>";
$bar = new Bar();
print $bar->fooStatic() . "<br>";
print $foo->my_static . "<br>"; // Undefined property – static is not accessible with ->
?>foo foo foo foo foo foo Notice: Accessing static property Foo::$my_static as non static in /opt/lampp/htdocs/phpbook/ch17/static.php on line 26 Warning: Undefined property: Foo::$my_static in /opt/lampp/htdocs/phpbook/ch17/static.php on line 26
A typical use of static members is a counter shared by all objects:
<?php
class Visitor
{
public static int $count = 0;
public function __construct() { self::$count++; }
public static function total(): string
{
return "Visitors created: " . self::$count;
}
}
new Visitor(); new Visitor(); new Visitor();
echo Visitor::total();
?>Visitors created: 3
Autoloading Classes
Many developers create one PHP source file per class. An annoyance is having to write a long list of include/require statements at the beginning of each script – one for each class.
PHP can load classes automatically the first time they are used. You register an autoloader function with spl_autoload_register(); it is called whenever you use a class or interface that has not been defined yet, giving PHP a last chance to load it before failing with an error.
PHP 8 change. Older notes use a function named __autoload(). It was deprecated in PHP 7.2 and removed in PHP 8.0. Use spl_autoload_register().
<?php
class MyClass1
{
public function hello() { return "MyClass1 loaded from MyClass1.php"; }
}<?php
spl_autoload_register(function ($class_name) {
echo "Autoloader: loading $class_name<br>";
include $class_name . '.php';
});
$obj = new MyClass1();
$obj2 = new MyClass2();
echo $obj->hello() . "<br>";
echo $obj2->hello();
?>Autoloader: loading MyClass1 Autoloader: loading MyClass2 MyClass1 loaded from MyClass1.php MyClass2 loaded from MyClass2.php
The autoloader may also throw an exception, which can be caught with try/catch:
<?php
spl_autoload_register(function ($name) {
echo "Want to load $name.<br>";
throw new Exception("Unable to load $name.");
});
try {
$obj = new NonLoadableClass();
} catch (Exception $e) {
echo $e->getMessage();
}
?>Want to load NonLoadableClass. Unable to load NonLoadableClass.
If a class name used by the autoloader comes from user input (for example in call_user_func()), it may contain dangerous characters such as ../. Never pass user input to an autoloader without checking it. In real projects, Composer generates a standard (PSR-4) autoloader for you.
Key Takeaways
- A class is a blueprint with constants, properties and methods;
newcreates objects. $thisrefers to the current object;self::to the current class;parent::to the parent class.__construct()initialises objects (PHP 8 promotion:public function __construct(public string $name));__destruct()runs when the object is destroyed.- Old class-name constructors and
__autoload()no longer work in PHP 8. public,protectedandprivatecontrol access – the basis of encapsulation.extendsgives single inheritance; methods can be overridden;finalprevents it.staticmembers belong to the class and are used with::.spl_autoload_register()loads class files automatically.
Program File
Extract the ZIP into C:\xampp\htdocs. It creates the folder phpbook/ch17 used in the file labels above; open the programs at http://localhost/phpbook/… with Apache (and MySQL, where needed) started in the XAMPP Control Panel.
Question / Answer (15 questions)
MCQ Test : Check Your Understanding (5 questions)
Select an option and press Check Answer, or answer all questions and press Submit Test to see your score. Each answer comes with an explanation.
Bibliography/References
The notes on this page are the author’s own compilation from the e-book PHP: Basics to Advance. Every program was run on Apache with PHP 8 and MariaDB, and the output shown is the real result of that run. The works listed below were consulted and are cited for attribution and further reading. Product names and trademarks belong to their respective owners.
- The PHP Group. (n.d.). PHP Manual – Classes and Objects. https://www.php.net/manual/en/language.oop5.php
- The PHP Group. (n.d.). PHP Manual – Constructors and Destructors. https://www.php.net/manual/en/language.oop5.decon.php
- The PHP Group. (n.d.). PHP Manual – Visibility. https://www.php.net/manual/en/language.oop5.visibility.php
- The PHP Group. (n.d.). PHP Manual – Scope Resolution Operator (::). https://www.php.net/manual/en/language.oop5.paamayim-nekudotayim.php
- The PHP Group. (n.d.). PHP Manual – Autoloading Classes. https://www.php.net/manual/en/language.oop5.autoload.php
- The PHP Group. (n.d.). PHP Manual – Backward incompatible changes (PHP 8.0). https://www.php.net/manual/en/migration80.incompatible.php