This is a series of notes that I’ve taken from the excellent “The Net Ninja” tutorials on youtube with regards to PHP OOP.
Once an object is instantiated, the php function get_class can identify what class an object belongs to.
<?php
class User {
}
$userOne = new User();
echo 'The class is '.get_class($userOne);
?>
<html>
<head>
<title>OOP</title>
</head>
<body>
</body>
</html>
PHP OOP 2
Accessing properties of an object, use the -> syntax
<?php
class User {
/* 'public' means these properties will be accesible
to each instance of the class */
public $username = 'james';
public $email = 'james@james.com';
}
$userOne = new User();
$userTwo = new User();
/* access a property from the object */
echo $userOne->username . '<BR>';
echo $userOne->email . '<BR>';
?>
Adding a function, known as a method in a class is easy.
<?php
class User {
/* 'public' means these properties will be accesible
to each instance of the class */
public $username = 'james';
public $email = 'james@james.com';
public function addFriend() {
return "added a new friend";
}
}
$userOne = new User();
$userTwo = new User();
/* access a property from the object */
echo $userOne->username . '<BR>';
echo $userOne->email . '<BR>';
echo $userOne->addFriend() . '<BR>';
?>
Accessing properties within the class file. Again we use -> but also use the this key word referring to the particular object that was instantiated.
<?php
class User {
/* 'public' means these properties will be accesible
to each instance of the class */
public $username = 'james';
public $email = 'james@james.com';
public function addFriend() {
return "$this->username added a new friend";
}
}
$userOne = new User();
$userTwo = new User();
/* access a property from the object */
echo $userOne->username . '<BR>';
echo $userOne->email . '<BR>';
echo $userOne->addFriend() . '<BR>';
?>
<html>
<head>
<title>OOP</title>
</head>
<body>
</body>
</html>
PHP Function get_class_vars will return all the class properties as an array and get_class_methods will return all the methods.
<?php
class User {
/* 'public' means these properties will be accesible
to each instance of the class */
public $username = 'james';
public $email = 'james@james.com';
public function addFriend() {
return "$this->username added a new friend";
}
}
$userOne = new User();
$userTwo = new User();
/* access a property from the object */
echo $userOne->username . '<BR>';
echo $userOne->email . '<BR>';
echo $userOne->addFriend() . '<BR>';
print_r(get_class_vars('User'));
print_r(get_class_methods('User'));
?>
Changing the property values on an instance of a class.
It is only possible to do this as these properties are exposed as public.
This is not a great way to change the property values of a class file, it’s better to do this using a constructor where we change these values as the object is instantiated (created).
<?php
class User {
/* 'public' means these properties will be accesible
to each instance of the class */
public $username = 'james';
public $email = 'james@james.com';
public function addFriend() {
return "$this->username added a new friend";
}
}
$userOne = new User();
$userTwo = new User();
/* access a property from the object */
echo $userOne->username . '<BR>';
echo $userOne->email . '<BR>';
echo $userOne->addFriend() . '<BR>';
$userTwo->username = 'em';
$userTwo->email = 'em@em.com';
echo $userTwo->username . '<BR>';
echo $userTwo->email . '<BR>';
echo $userTwo->addFriend() . '<BR>';
//print_r(get_class_vars('User'));
//print_r(get_class_methods('User'));
?>
PHP OOP 4 – Constructors
The constructor is a special function that is executed when the class is instantiated.
<?php
class User {
/* 'public' means these properties will be accesible
to each instance of the class */
public $username = 'james';
public $email = 'james@james.com';
public function __construct($username,$email){
$this->username = $username;
$this->email = $email;
}
public function addFriend() {
return "$this->username added a new friend";
}
}
$userOne = new User('aaa','aaa@aaa.com');
$userTwo = new User('bbb','bbb@bbb.com');
/* access a property from the object */
echo $userOne->username . '<BR>';
echo $userOne->email . '<BR>';
echo $userOne->addFriend() . '<BR>';
echo $userTwo->username . '<BR>';
echo $userTwo->email . '<BR>';
echo $userTwo->addFriend() . '<BR>';
?>
PHP OOP 5 – Access modifiers
Public – properties and methods can be accessed inside and outside of the class. Properties can also be updated outside of the class.
Private – property cannot be accessed outside of the class, but it can be used internally.
<?php
class User {
public $username;
private $email;
public function __construct($username,$email){
$this->username = $username;
$this->email = $email;
}
public function addFriend() {
return "$this->username added a new friend";
}
}
$userOne = new User('aaa','aaa@aaa.com');
$userTwo = new User('bbb','bbb@bbb.com');
/* access a property from the object */
echo $userOne->username . '<BR>';
echo $userOne->email . '<BR>';
echo $userOne->addFriend() . '<BR>';
?>
The error is thrown because email cannot be accessed from outside the class.
However, the following does still work:
<?php
class User {
public $username;
private $email;
public function __construct($username,$email){
$this->username = $username;
$this->email = $email;
}
public function addFriend() {
return "$this->email added a new friend";
}
}
$userOne = new User('aaa','aaa@aaa.com');
$userTwo = new User('bbb','bbb@bbb.com');
echo $userOne->addFriend() . '<BR>';
?>
The reason why this works is that from outside the class, we are calling a public method which uses a private property.
Making properties private is good, it prevents properties being changed from outside of the class. If a public method is called that uses a private property, this is acceptable.
Because we can no longer access the properties just to output them to the screen, we have to use get and set methods to do this.
There is a third modifier called protected.
PHP OOP 6 – Getters and Setters
<?php
class User {
public $username;
private $email;
public function __construct($username,$email){
$this->username = $username;
$this->email = $email;
}
public function addFriend() {
return "$this->email added a new friend";
}
public function getEmail(){
return $this->email;
}
}
?>
<?php
$userOne = new User ('james','james@james.com');
$userTwo = new User ('em','em@em.com');
echo $userOne->getEmail() . '<br>';
echo $userTwo->getEmail() . '<br>';
?>
<?php
class User {
public $username;
private $email;
public function __construct($username,$email){
$this->username = $username;
$this->email = $email;
}
public function addFriend() {
return "$this->email added a new friend";
}
public function getEmail(){
return $this->email;
}
public function setEmail($email){
if(strpos($email, '@')>-1){
$this->email = $email;
}
}
}
?>
<?php
$userOne = new User ('james','james@james.com');
$userTwo = new User ('em','em@em.com');
$userOne->setEmail('j@j.com');
echo $userOne->getEmail() . '<br>';
echo $userTwo->getEmail() . '<br>';
?>
If we remove the @ symbol from the setEmail, the email stays as the original that was passed with the constructor and isn’t updated.
PHP OOP 7 – inheritance
When one class inherits properties and methods from another class.
<?php
class User {
public $username;
private $email;
public function __construct($username,$email){
$this->username = $username;
$this->email = $email;
}
public function addFriend() {
return "$this->email added a new friend";
}
public function getEmail(){
return $this->email;
}
public function setEmail($email){
if(strpos($email, '@')>-1){
$this->email = $email;
}
}
}
class AdminUser extends User {
}
?>
<?php
$userOne = new User ('james','james@james.com');
$userTwo = new User ('em','em@em.com');
$userThree = new AdminUser ('admin','admin@admin.com');
echo $userThree->username. '<br>';
echo $userThree->getEmail(). '<br>';
?>
In the above, even though the AdminUser class does no have a constructor, it has inherited the constructor from the parent class User.
With the following code, we re-write the contructor in the AdminUser to include the username, and email, AND the level (admin level for example), however all we see is output of the level.
This is because the new constructor in the AdminUser class is overriding the constructor in the User class.
When we create and object of the AdminUser class, it’s no longer saying we don’t have a constructor so we’ll use the constructor of the parent class, it’s using the contructor of the AdminUser class.
<?php
class User {
public $username;
private $email;
public function __construct($username,$email){
$this->username = $username;
$this->email = $email;
}
public function addFriend() {
return "$this->email added a new friend";
}
public function getEmail(){
return $this->email;
}
public function setEmail($email){
if(strpos($email, '@')>-1){
$this->email = $email;
}
}
}
class AdminUser extends User {
public $level;
public function __construct($username, $email, $level){
$this->level = $level;
}
}
?>
<?php
$userOne = new User ('james','james@james.com');
$userTwo = new User ('em','em@em.com');
$userThree = new AdminUser ('admin','admin@admin.com',5);
echo $userThree->username. '<br>';
echo $userThree->getEmail(). '<br>';
echo $userThree->level. '<br>';
?>
… so we need a way to call the constructor of AdminUser for the level property and the constructor of User for the username and email properties.
We do that using the parent:: as higlighted in the code below.
<?php
class User {
public $username;
private $email;
public function __construct($username,$email){
$this->username = $username;
$this->email = $email;
}
public function addFriend() {
return "$this->email added a new friend";
}
public function getEmail(){
return $this->email;
}
public function setEmail($email){
if(strpos($email, '@')>-1){
$this->email = $email;
}
}
}
class AdminUser extends User {
public $level;
public function __construct($username, $email, $level){
$this->level = $level;
parent::__construct($username, $email);
}
}
?>
<?php
$userOne = new User ('james','james@james.com');
$userTwo = new User ('em','em@em.com');
$userThree = new AdminUser ('admin','admin@admin.com',5);
echo $userThree->username. '<br>';
echo $userThree->getEmail(). '<br>';
echo $userThree->level. '<br>';
?>
PHP OOP8 – Overriding properties and methods
To override a property value, we can just re-define it in the class itself.
Before overriding:
<?php
class User {
public $username;
private $email;
public $role='member';
public function __construct($username,$email){
$this->username = $username;
$this->email = $email;
}
public function addFriend() {
return "$this->email added a new friend";
}
public function getEmail(){
return $this->email;
}
public function setEmail($email){
if(strpos($email, '@')>-1){
$this->email = $email;
}
}
}
class AdminUser extends User {
public $level;
public function __construct($username, $email, $level){
$this->level = $level;
parent::__construct($username, $email);
}
}
?>
<?php
$userOne = new User ('james','james@james.com');
$userTwo = new User ('em','em@em.com');
$userThree = new AdminUser ('admin','admin@admin.com',5);
echo $userOne->role. '<br>';
echo $userThree->role. '<br>';
?>
After overriding:
<?php
class User {
public $username;
private $email;
public $role='member';
public function __construct($username,$email){
$this->username = $username;
$this->email = $email;
}
public function addFriend() {
return "$this->email added a new friend";
}
public function getEmail(){
return $this->email;
}
public function setEmail($email){
if(strpos($email, '@')>-1){
$this->email = $email;
}
}
}
class AdminUser extends User {
public $level;
public $role='admin';
public function __construct($username, $email, $level){
$this->level = $level;
parent::__construct($username, $email);
}
}
?>
<?php
$userOne = new User ('james','james@james.com');
$userTwo = new User ('em','em@em.com');
$userThree = new AdminUser ('admin','admin@admin.com',5);
echo $userOne->role. '<br>';
echo $userThree->role. '<br>';
?>
Overriding methods
<?php
class User {
public $username;
private $email;
public $role='member';
public function __construct($username,$email){
$this->username = $username;
$this->email = $email;
}
public function addFriend() {
return "$this->email added a new friend";
}
public function message(){
return "$this->email sent a new message";
}
public function getEmail(){
return $this->email;
}
public function setEmail($email){
if(strpos($email, '@')>-1){
$this->email = $email;
}
}
}
class AdminUser extends User {
public $level;
public $role='admin';
public function __construct($username, $email, $level){
$this->level = $level;
parent::__construct($username, $email);
}
}
?>
<?php
$userOne = new User ('james','james@james.com');
$userTwo = new User ('em','em@em.com');
$userThree = new AdminUser ('admin','admin@admin.com',5);
echo $userOne->role. '<br>';
echo $userThree->role. '<br>';
echo $userOne->message() . '<br>';
echo $userTwo->message() . '<br>';
echo $userThree->message() . '<br>';
?>
The result above is as expected because of inheritance. But what do we do if we want to override the message method? As before, we simple re-write the method in the child class (as we did with the property)…however, it’s not quite that simple.
<?php
class User {
public $username;
private $email;
public $role='member';
public function __construct($username,$email){
$this->username = $username;
$this->email = $email;
}
public function addFriend() {
return "$this->email added a new friend";
}
public function message(){
return "$this->email sent a new message";
}
public function getEmail(){
return $this->email;
}
public function setEmail($email){
if(strpos($email, '@')>-1){
$this->email = $email;
}
}
}
class AdminUser extends User {
public $level;
public $role='admin';
public function __construct($username, $email, $level){
$this->level = $level;
parent::__construct($username, $email);
}
public function message(){
return "$this->email was sent by an admin";
}
}
?>
<?php
$userOne = new User ('james','james@james.com');
$userTwo = new User ('em','em@em.com');
$userThree = new AdminUser ('admin','admin@admin.com',5);
echo $userOne->role. '<br>';
echo $userThree->role. '<br>';
echo $userOne->message() . '<br>';
echo $userTwo->message() . '<br>';
echo $userThree->message() . '<br>';
?>
The above is saying “I can’t access the email property on this instance inside this class”.
The reason why we can’t do it is that it’s not defined in the UserAdmin class and it’s defined as private in the User class.
The solution is the use the access modifier protected
Protected means the property can only be used internally inside it’s class, and can’t be accessed directly outside it’s class, but it does mean that any class that extends the class CAN access it as well.
<?php
class User {
public $username;
protected $email;
public $role='member';
public function __construct($username,$email){
$this->username = $username;
$this->email = $email;
}
public function addFriend() {
return "$this->email added a new friend";
}
public function message(){
return "$this->email sent a new message";
}
public function getEmail(){
return $this->email;
}
public function setEmail($email){
if(strpos($email, '@')>-1){
$this->email = $email;
}
}
}
class AdminUser extends User {
public $level;
public $role='admin';
public function __construct($username, $email, $level){
$this->level = $level;
parent::__construct($username, $email);
}
public function message(){
return "$this->email was sent by an admin";
}
}
?>
PHP OOP9 – Clone and destruct
__construct is known as a ‘magic method’. Here are a few more.
The destruct method is sort of the opposite of the construct method.
The destruct method runs when an object is destroyed. This can be done using unset.
<?php
class User {
public $username;
protected $email;
public $role='member';
public function __construct($username,$email){
$this->username = $username;
$this->email = $email;
}
public function __destruct(){
echo "the user $this->username was removed";
}
public function addFriend() {
return "$this->email added a new friend";
}
public function message(){
return "$this->email sent a new message";
}
public function getEmail(){
return $this->email;
}
public function setEmail($email){
if(strpos($email, '@')>-1){
$this->email = $email;
}
}
}
class AdminUser extends User {
public $level;
public $role='admin';
public function __construct($username, $email, $level){
$this->level = $level;
parent::__construct($username, $email);
}
public function message(){
return "$this->email was sent by an admin";
}
}
?>
<?php
$userOne = new User ('james','james@james.com');
$userTwo = new User ('em','em@em.com');
$userThree = new AdminUser ('admin','admin@admin.com',5);
unset ($userOne);
?>
The output from the above is somewhat suprising.
We expect the user james to be removed, but why the others?
The reason is that once a php file gets to the end of the code, the references are removed, … all of the referenced are removed so the distruct function runs on all the references to the objects.
So we don’t need to unset the references, php takes care of that automatically.
Another ‘magic method’ is clone.
<?php
class User {
public $username;
protected $email;
public $role='member';
public function __construct($username,$email){
$this->username = $username;
$this->email = $email;
}
public function __destruct(){
echo "the user $this->username was removed <br>";
}
/* this method will run just for the instance that is
using and object that is a clone of another one.
can be used for some kind of setup of the new object
(that is a clone of another object)
*/
public function __clone(){
$this->username = $this->username . '(cloned)<br>';
}
public function addFriend() {
return "$this->email added a new friend";
}
public function message(){
return "$this->email sent a new message";
}
public function getEmail(){
return $this->email;
}
public function setEmail($email){
if(strpos($email, '@')>-1){
$this->email = $email;
}
}
}
class AdminUser extends User {
public $level;
public $role='admin';
public function __construct($username, $email, $level){
$this->level = $level;
parent::__construct($username, $email);
}
public function message(){
return "$this->email was sent by an admin";
}
}
?>
<?php
$userOne = new User ('james','james@james.com');
$userTwo = new User ('em','em@em.com');
$userThree = new AdminUser ('admin','admin@admin.com',5);
$userFour = clone $userOne;
echo $userFour->username;
?>
The close method will run just for the instance that is
using and object that is a clone of another one.
can be used for some kind of setup of the new object
(that is a clone of another object)
PHP OOP 10 – Static methods
A static property or method is and property that can be accessed directly and not via an instance of the class.
<?php
class Weather{
public $tempConditions = ['cold','mild','warm'];
public function celciusToFarenheit($c){
}
public function determineTempCondition($f){
}
}
$weatherInstance = new Weather();
print_r($weatherInstance->tempConditions);
?>
The above would be the usual way to access properties of a class. By using static, we can access these properties and methods directly without having to create an instance first. As below:
<?php
class Weather{
public static $tempConditions = ['cold','mild','warm'];
public static function celciusToFarenheit($c){
}
public static function determineTempCondition($f){
}
}
print_r(Weather::$tempConditions);
?>
Accessing a static method
<?php
class Weather{
public static $tempConditions = ['cold','mild','warm'];
public static function celciusToFarenheit($c){
return $c * 9 /5 + 32;
}
public static function determineTempCondition($f){
}
}
//print_r(Weather::$tempConditions);
echo Weather::celciusToFarenheit(20);
?>
To refer to a static variable WITHIN the class, we can’t use $this keyword because there has been no instance of the class created. So we have to use the self keyword.
<?php
class Weather{
public static $tempConditions = ['cold','mild','warm'];
public static function celciusToFarenheit($c){
return $c * 9 /5 + 32;
}
public static function determineTempCondition($f){
if ($f<40){
return self::$tempConditions[0];
} else if ($f<70){
return self::$tempConditions[1];
} else {
return self::$tempConditions[2];
}
}
}
//print_r(Weather::$tempConditions);
//echo Weather::celciusToFarenheit(20);
echo Weather::determineTempCondition(80);
?>