The image part with relationship ID rId7 was not found in the file.
Version 1.4
icemalta.com
The image part with relationship ID rId2 was not found in the file.
Module 2:
PHP Foundations
MySuccess Website Developer
PRESENTED BY
Keith Vassallo
The image part with relationship ID rId7 was not found in the file.
icemalta.com
The image part with relationship ID rId2 was not found in the file.
Object Oriented
Programming, Part 2
Topic 10
PRESENTED BY
Keith Vassallo
The image part with relationship ID rId7 was not found in the file.
icemalta.com
Object Oriented Programming, Part 2
- Inheritance.
- Namespaces.
- Introspection.
- PDO.
- PDO Fundamentals.
- Exception Handling.
- PDO Queries and Prepared Statements.
- CRUD.
In this topic
The image part with relationship ID rId7 was not found in the file.
icemalta.com
The image part with relationship ID rId2 was not found in the file.
Inheritance
10.1
The image part with relationship ID rId7 was not found in the file.
icemalta.com
Properties and methods of a particular class can be inherited by another
class.
The extends keyword followed by the name of the base class is used in the
new class definition.
Inheritance
class TeamLead extends Employee {
private $bonusEntitlement;
}
Note:
- Instances of the TeamLead class have access to all public/protected
members of the Employee class.
- If a subclass contains a member having the same name as one in its super
class, the subclass members takes preference.
- It is then said that the subclass member overrides the member in the
parent class.
The image part with relationship ID rId7 was not found in the file.
icemalta.com
To access a method in the parent class, the parent::method() notation
should be used.
Inheritance
In this example, the getSalary() method in the TeamLead class is
overriding the getSalary() method of the Employee class. This is due to
the fact that both methods have the same name and the same number of
arguments.
If the method has the same name but different arguments, then both can
co-exist, and PHP can decide which method to call based on the number of
arguments forwarded. This is called method overloading.
class TeamLead extends Employee {
private $bonusEntitlement;
public function getSalary(int $hours, int $overtime = 0) {
return parent::getSalary($hours, $overtime) + $this->bonusEntitlement;
}
}
The image part with relationship ID rId7 was not found in the file.
icemalta.com
Consider the following code:
Simple Polymorphism
What will this code output?
class A {
public function classNameIs() {
echo "[A]";
}
public function echoClassName() {
$this->classNameIs();
}
}
class B extends A {
public function classNameIs() {
echo "[B]";
}
}
$classObj = new B();
$classObj->echoClassName();
The image part with relationship ID rId7 was not found in the file.
icemalta.com
An object of class B is created.
The $this pointer always references the current object and since the object
is of type B, the version of classNameIs() called is the one defined in class B.
This is a simple example of how polymorphism works in OOP.
If instead of using $this->classNameIs(), the keyword self is used
(self::classNameIs();), the method called would be the one in class A.
This means that when using self, the version of the method called is the
one in the superclass.
This further infers that the keyword self is essentially turning off
polymorphic behaviour.
Simple Polymorphism
The image part with relationship ID rId7 was not found in the file.
icemalta.com
The image part with relationship ID rId2 was not found in the file.
Namespaces
10.2
The image part with relationship ID rId7 was not found in the file.
icemalta.com
Consider a situation where a class A needs to be used and another class with
the same name, A, needs to be implemented.
This naturally results in a naming collision, as PHP does not directly allow
for two or more classes to have the same name.
PHP namespaces can be used to work around this issue.
A normal class definition, such as the ones we’ve created so far, can be seen
as being in the ‘global’ namespace.
To add a namespace, we can now place a declaration as the very first line of
the file.
Namespaces
<?php
namespace MyProject;
class A {
public function classNameIs() {
echo "[A]";
}
...
The image part with relationship ID rId7 was not found in the file.
icemalta.com
To use the class A from the namespace MyProject, we can now use:
Namespaces
$objectA1 = new MyProject\A();
PHP operations are performed relative to the current namespace.
For example:
<?php
namespace MyProject;
$objectA1 = new A();
To use a class from the global namespace, prefix it with a backslash \
$objectA2 = new \A();
To use a class from another namespace, prefix the namespace.
<?php
namespace MyProject;
$objectB1 = new \Common\B();
The image part with relationship ID rId7 was not found in the file.
icemalta.com
The use keyword can be used to avoid having to instantiate a class using the
fully qualified path.
Namespaces
<?php
namespace MyProject;
use \Common\B;
$objectB1 = new B();
An alias to the fully qualified class path can be created using the as keyword.
<?php
namespace MyProject;
use \Common\B as FileIO;
$fileHandler = new FileIO();
The image part with relationship ID rId7 was not found in the file.
icemalta.com
Multiple namespaces can be defined by enclosing the namespace code in
between braces.
Namespaces
<?php
namespace A {
class A {
public function say() {
print "Namespace A::A - Hello<br>";
}
}
}
namespace B {
class A {
public function say() {
print "Namespace B::A - Hello<br>";
}
}
}
$object1 = new \A\A();
$object2 = new \B\A();
The image part with relationship ID rId7 was not found in the file.
icemalta.com
The image part with relationship ID rId2 was not found in the file.
Introspection
10.3
The image part with relationship ID rId7 was not found in the file.
icemalta.com
Introspection aids in examining an objects characteristics such as:
- Name.
- Parent Class (if available).
- Fields.
- Methods.
Information about the class can be discovered at runtime.
Introspection is sometimes called reflection.
Introspection
The image part with relationship ID rId7 was not found in the file.
icemalta.com
class_exists(string $class_name [, bool $autoload = true])
- This function is used to determine if a class exists.
get_class_methods(mixed $class_or_object_name)
- Retrieves the properties and methods defined in a class, returns an array.
get_class_vars(string $class_name)
- Returns an associative array of declared fields and their values.
get_parent_class( [ mixed $object] )
- Returns the name of the parent class if this exists, or false otherwise.
Introspection Highlights
The image part with relationship ID rId7 was not found in the file.
icemalta.com
is_object(mixed $var)
- Returns true if $var is an object.
get_class([object $object = null])
- Returns the name of the class of an object.
- The argument is optional as this can be omitted when inside a class.
method_exists(mixed $object, string $method_name)
- Reveals if a method for a given object exists.
get_object_vars(object $object)
- Returns the fields of an object as an associative array.
Introspection Highlights
The image part with relationship ID rId7 was not found in the file.
icemalta.com
The image part with relationship ID rId2 was not found in the file.
PDO
10.4
The image part with relationship ID rId7 was not found in the file.
icemalta.com
Historically, PHP has provided many ways to access databases. There are
three different APIs which allow a PHP programmer to access a MySQL
database:
- mysql
- mysqli (MySQL Improved)
- PDO (PHP Data Objects)
A large number of web applications have been built around the use of the
traditional mysql(i) API.
Introspection
The image part with relationship ID rId7 was not found in the file.
icemalta.com
The mysql API makes for retrieving records from a database fairly easy:
The mysql API
/* Connect to database */
if (! mysql_connect('localhost', 'root', 'root')) {
printf("(EE) Could not connect. Error: %s.<br>", mysql_error());
exit(1);
}
/* Switch to database */
if (! mysql_select_db('CD_INVENTORY')) {
printf("Could not select database<br>");
exit(1);
}
/* Perform a simple query */
$query = "SELECT * FROM tblCd";
if (!($result = mysql_query($query))) {
printf("(EE) Query failed. Error: %s.<br>", mysql_error());
}
/* Print required information */
while ($row = mysql_fetch_object($result)) {
printf("Value: %s.<br>", $row->cdTitle);
}
The image part with relationship ID rId7 was not found in the file.
icemalta.com
When run, this simple program should connect to MySQL, switch to the
database CD_INVENTORY and perform a SELECT * (all) on the table tblCd.
The values corresponding to the column cdTitle are printer.
Although this method is straightforward, the following issues have made
using alternatives (specifically PDO) the best way forward:
- The extension has been deprecated since PHP 5.5.
- Using the mysql API, escaping user input has to be taken care of by the
programmer, which can be an area of potential concern (lacks prepared
statements).
- The API naturally works with a MySQL database, so large systems built
entirely using this API may be hard to convert to another DBMS.
The mysql API
The image part with relationship ID rId7 was not found in the file.
icemalta.com
The PDO extension supports any database which has a PDO driver.
The following are some of the available drivers:
PHP Data Objects
Driver
DBMS
PDO_IBM
IBM DB2
PDO_MYSQL
MySQL 3.x, 4.x, 5.x
PDO_PGSQL
PostgreSQL
PDO_SQLITE
SQLite 2,3
The image part with relationship ID rId7 was not found in the file.
icemalta.com
PHP strongly supports object-oriented coding methods. Using OOP-design
concepts makes code testing better and makes code reusable, facilitating code
integration.
PDO makes the database layer of a system object-oriented and hence
reusable.
PDO allows parameter binding where placeholders are replaces with the
value of a variable inside a query. This is advantageous in that the number of
placeholders is not required to be known at runtime, and this adds a further
layer of security against SQL injection.
PDO fetches data from a table into an object.
PDO
The image part with relationship ID rId7 was not found in the file.
icemalta.com
The image part with relationship ID rId2 was not found in the file.
PDO Fundamentals
10.5
The image part with relationship ID rId7 was not found in the file.
icemalta.com
Using PDO involves adopting the following steps:
- Connect to the database (i.e. correctly setting up a connection).
- Use prepared statements and binding parameters to safeguard against
malformed user input.
- Execute a query.
To connect to a database using PDO, a PDO object needs to be requested.
The PDO constructor is as follows:
PDO Fundamentals
public function __construct(
string $dsn
[, string $username
[, string $password
[, array $options]]])
The image part with relationship ID rId7 was not found in the file.
icemalta.com
The string $dsn contains information on how to connect to the database.
The DSN (Data Source Name) is made up of the PDO driver name, a colon,
and the PDO driver-specific connection syntax.
The PDO_MYSQL DSN contains:
PDO Fundamentals
Member
Description
DSN
prefix
A string
– ‘mysql:
host
The hostname on which the database server resides.
port
The port number where the database server is listening.
dbname
The
database name.
unix_socket
MySQL
unix socket (should not be used with host or port).
charset
The character set.
The image part with relationship ID rId7 was not found in the file.
icemalta.com
The advantage of using PDO is immediately apparent:
- If MySQL needs to be replaced by another DBMS, the $dsn string is
updated to reflect the new DSN prefix.
Good programmers safe-guard against errors which may be returned when
using resources.
What happens if a connection to the database cannot be established?
- A try/catch block helps in ensuring the program reports back an error and
exits gracefully.
PDO Fundamentals
The image part with relationship ID rId7 was not found in the file.
icemalta.com
The image part with relationship ID rId2 was not found in the file.
Exception Handling
10.6
The image part with relationship ID rId7 was not found in the file.
icemalta.com
Predicting how code behaves in every scenario is not always possible.
One way to handle a situation which leads to failure is to write an exception
handler.
Basic exception handlers use try/catch blocks to enclose areas of code in a
way which allows the program to detect problems and act properly.
In PHP, exceptions are represented by the class Exception and can be
raised using the keyword throw.
The class Exception can be extended to create custom exception types for
safeguarding against program-specific errors.
Exceptions which are thrown and not properly handled generate an E_FATAL
error and the message ‘Uncaught Exception’ is shown.
Exception Handling
The image part with relationship ID rId7 was not found in the file.
icemalta.com
Code that triggers an exception is placed within a try block.
Code to handle the exception is placed within a catch block.
The Exception class provides six methods to retrieve information about
why an exception is raised:
Exception Handling
Method
Description
getMessage
()
Returns the exception’s message.
getCode
()
Returns the exception’s error code.
getLine
()
Returns the line number where the exception
was thrown.
getFile
()
Returns the name of the file where the exception
was thrown.
getTrace
()
Returns the exception’s stack trace as an array.
getTraceAsString()
Returns the exception’s stack
trace as a string.
The image part with relationship ID rId7 was not found in the file.
icemalta.com
When a program makes use of PDO calls, it is advisable to provide a way to
handle errors.
Errors can be checked after each PDO call or exceptions can be thrown,
which is the easier approach.
The default error mode for PDO is PDO::ERRMODE_SILENT.
An error raised by PDO is represented by the PDOException class which
extends RuntimeException.
To use this exception, attributes need to be set up for the PDO-returned
object:
PDO and Exception Handling
$cdInventoryDb->setAttribute (PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
The image part with relationship ID rId7 was not found in the file.
icemalta.com
Enhancing our PDO connection code to include exception handling:
PDO and Exception Handling
$host = 'localhost';
$databaseName = 'CD_INVENTORY';
$dbUsername = 'root';
$dbPassword = 'root';
$dsn = "mysql:host=$host;dbname=$databaseName";
/* Using default options */
try {
$cdInventoryDb = new PDO($dsn, $dbUsername, $dbPassword);
$cdInventoryDb->setAttribute (PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (Exception $exception) {
printf("(EE) Error during connection: %s.<br>", $exception->getMessage());
}
The image part with relationship ID rId7 was not found in the file.
icemalta.com
The image part with relationship ID rId2 was not found in the file.
PDO Queries and
Prepared Statements
10.7
The image part with relationship ID rId7 was not found in the file.
icemalta.com
PDO queries can be categories as:
- Queries that return data from a database, ex: SELECT
- Queries that return a value after an operation on the database, ex: INSERT
The following example returns all values from the table tblCd:
PDO Queries
printf("%20s%20s%20s<br>", 'CD Id', 'CD Title', 'Label id');
foreach($cdInventoryDb->query("SELECT * FROM tblCd") as $record) {
printf("%20s%20s%20s<br>", $record['cdId'], $record['cdTitle'], $record['labelIdFk']);
}
The image part with relationship ID rId7 was not found in the file.
icemalta.com
In the previous example, PDO internally prepares a query statement, runs
and returns the data as an array which can be parsed.
Consider a different scenario where the value of labelIdFk is retrieved via a
form.
For example:
Prepared Statements
$labelId = 1; //The value was typed in by the user
printf("%20s%20s%20s<br>", 'CD Id', 'CD Title', 'Label id');
foreach($cdInventoryDb->query("SELECT * FROM tblCd WHERE labelIdFk = $labelId") as $record) {
printf("%20s%20s%20s<br>", $record['cdId'], $record['cdTitle'], $record['labelIdFk']);
}
This will extract records which correspond to the labelIdFk = 1 caluse.
The image part with relationship ID rId7 was not found in the file.
icemalta.com
Consider now:
Prepared Statements
The SQL injection attack above produces catastrophic results since the value
of $labelId is substituted directly in the query.
Forwarded data may alter the program with very negative consequences.
$labelId = '1; DROP TABLE tblCd;'; //The value was typed in by the user
printf("%20s%20s%20s<br>", 'CD Id', 'CD Title', 'Label id');
foreach($cdInventoryDb->query("SELECT * FROM tblCd WHERE labelIdFk = $labelId") as $record) {
printf("%20s%20s%20s<br>", $record['cdId'], $record['cdTitle'], $record['labelIdFk']);
}
The image part with relationship ID rId7 was not found in the file.
icemalta.com
Prepared statements and binding parameters help prevent such issues:
Prepared Statements
PDO will prepare a statement and send it, including the named parameter
:label_id to the DBMS.
The DBMS parses and compiles this query after which the parameter can be
passed and the query executed.
Parameters need not be named. These are referred to as numbered
placeholders:
$labelId = '1; DROP TABLE tblCd;'; //The value was typed in by the user
$cdInventoryPS = $cdInventoryDb->prepare("SELECT * FROM tblCd WHERE labelIdFk = :label_id");
$cdInventoryPS->execute(array($labelId));
printf("%20s%20s%20s<br>", 'CD Id', 'CD Title', 'Label id');
foreach($cdInventoryPS->fetchAll() as $record) {
printf("%20s%20s%20s<br>", $record['cdId'], $record['cdTitle'], $record['labelIdFk']);
}
$labelId = '1; DROP TABLE tblCd;'; //The value was typed in by the user
$cdInventoryPS = $cdInventoryDb->prepare("SELECT * FROM tblCd WHERE labelIdFk = ?");
$cdInventoryPS->execute(array($labelId));
The image part with relationship ID rId7 was not found in the file.
icemalta.com
The method bindParam() can be used to break down the process of using
named parameters.
Prepared Statements
$cdInventoryPS = $cdInventoryDb->prepare("SELECT * FROM tblCd WHERE labelIdFk = :label_id");
$cdInventoryPS->bindParam(':label_id', $labelId, PDO::PARAM_INT);
$cdInventoryPS->execute();
The third argument accepted by bindParam() is optional. PHP will attempt
to use the best data type available if it is omitted.
The image part with relationship ID rId7 was not found in the file.
icemalta.com
PDO provides a straightforward mechanism to preform multiple executions:
Multiple Executions
try {
$cdInventoryDb = new PDO($dsn, $dbUsername, $dbPassword);
$cdInventoryDb->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$cdInventoryPS = $cdInventoryDb->prepare("SELECT * FROM tblCd WHERE labelIdFk = :label_id");
$cdInventoryPS->bindParam(':label_id', $labelId);
/* Query 1 */
$labelId = 1;
$cdInventoryPS->execute();
while ($record = $cdInventoryPS->fetch()) {
printf("%20s%20s%20s<br>", $record['cdId'], $record['cdTitle'], $record['labelIdFk']);
}
/* Query 2 */
$labelId = 2;
$cdInventoryPS->execute();
while ($record = $cdInventoryPS->fetch()) {
printf("%20s%20s%20s<br>", $record['cdId'], $record['cdTitle'], $record['labelIdFk']);
}
} catch (Exception $exception) {
printf("(EE) Error during connection: %s.<br>", $exception->getMessage());
}
The image part with relationship ID rId7 was not found in the file.
icemalta.com
Some drivers do not support prepared statements, or do not support them
properly.
PDO by default uses emulation to carry out tasks requiring prepared
statements where a query is sent to MySQL as proper SQL.
This behaviour can be turned off by setting the following attribute before the
error mode.
Prepared Statement Emulation
What happens in this mode is that a real or native prepared statement is
issued.
- When prepare() is later called, the query together with any placeholders
are sent to the DBMS.
- The actual data is then transferred during the execute() run.
Both methods have their pros and cons.
$cdInventoryDb = new PDO($dsn, $dbUsername, $dbPassword);
$cdInventoryDb->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$cdInventoryDb->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
The image part with relationship ID rId7 was not found in the file.
icemalta.com
The image part with relationship ID rId2 was not found in the file.
CRUD
10.8
The image part with relationship ID rId7 was not found in the file.
icemalta.com
CRUD stands for Create, Read, Update and Delete and is nothing more than
a group of operations performed on a database:
- C Create or insert a new row in a database.
- R Read or retrieve database records.
- U Update a particular record.
- D Delete or remove a particular record.
The following examples explain the various operations.
CRUD
The image part with relationship ID rId7 was not found in the file.
icemalta.com
Create (INSERT)
try {
$cdInventoryDb = new PDO($dsn, $dbUsername, $dbPassword);
$cdInventoryDb->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
/* Prepare the query */
$cdInventoryPs = $cdInventoryDb->prepare(
"INSERT INTO tblRecordLabel (labelName) VALUES (:label_name)");
$cdInventoryPs->bindParam(':label_name', $labelName, PDO::PARAM_STR);
/* Run the query */
$labelName = 'TestLabel';
$cdInventoryPs->execute();
/* Print rows affected */
printf("Rows affected: %d.<br>", $cdInventoryPs->rowCount());
} catch (Exception $exception) {
printf("(EE) Error during connection: %s.<br>", $exception->getMessage());
}
The image part with relationship ID rId7 was not found in the file.
icemalta.com
Update
try {
$cdInventoryDb = new PDO($dsn, $dbUsername, $dbPassword);
$cdInventoryDb->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
/* Prepare the query */
$cdInventoryPs = $cdInventoryDb->prepare(
"UPDATE tblRecordLabel SET labelName = :label_name
WHERE labelId = :label_id");
$cdInventoryPs->bindParam(':label_name', $labelName, PDO::PARAM_STR);
$cdInventoryPs->bindParam(':label_id', $labelId, PDO::PARAM_INT);
/* Run the query */
$labelName = 'NewLabel';
$labelId = 8;
$cdInventoryPs->execute();
/* Print rows affected */
printf("Rows affected: %d.<br>", $cdInventoryPs->rowCount());
} catch (Exception $exception) {
printf("(EE) Error during connection: %s.<br>", $exception->getMessage());
}
The image part with relationship ID rId7 was not found in the file.
icemalta.com
Delete
try {
$cdInventoryDb = new PDO($dsn, $dbUsername, $dbPassword);
$cdInventoryDb->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
/* Prepare the query */
$cdInventoryPs = $cdInventoryDb->prepare(
"DELETE FROM tblRecordLabel WHERE labelId = :label_id");
$cdInventoryPs->bindParam(':label_id', $labelId, PDO::PARAM_INT);
/* Run the query */
$labelId = 8;
$cdInventoryPs->execute();
/* Print rows affected */
printf("Rows affected: %d.<br>", $cdInventoryPs->rowCount());
} catch (Exception $exception) {
printf("(EE) Error during connection: %s.<br>", $exception->getMessage());
}
The image part with relationship ID rId7 was not found in the file.
icemalta.com
The image part with relationship ID rId2 was not found in the file.
Next up: PHP and Web Development
Great work, you’ve completed this topic!
The image part with relationship ID rId7 was not found in the file.
icemalta.com
The image part with relationship ID rId2 was not found in the file.
© 2011-2017 Institute of Computer Education Ltd.
The contents of this document are copyright to the Institute of Computer Education Ltd, unless otherwise stated, and must not be reproduced without permission.
Every effort has been made to trace all of the copyright holders, but if any have been inadvertently overlooked the Institute of Computer Education Ltd. will be pleased to make the necessary arrangements at the first
opportunity. Please contact us directly. While the Institute of Computer Education Ltd. has taken all reasonable care in the preparation of this work, the Institute of Computer Education Ltd. makes no representation,
express or implied, with regard to the accuracy of the information contained in this work and cannot accept any legal responsibility or liability for any errors or omissions from the work or the consequences thereof. The
reader assumes sole responsibility for the selection of these materials to achieve its intended results. Products and services that are referred to in this work may be either trademarks and/or registered trademarks of
their respective owners. The editors and author/s make no claim to these trademarks.
© 2011-2017 Institute of Computer Education Ltd.
Version 1.0 | Keith Vassallo
Version 1.1 | Noel de Gabriele & Keith Vassallo
Version 1.2 | Karl Vassallo-Grant
Version 1.3 | Emanuel Scicluna & Keith Vassallo
Version 1.4 | Emanuel Scicluna & Keith Vassallo