1. OOP and PHP 5.3
South Florida PHP Users Group
Adam Culp
http://www.Geekyboy.com
In this presentation we will talk about OOP, and discuss
the object model progression in PHP from version 4
through the newest 5.3.
I apologize in advance, but this will not be in great detail
though I hope it is enough to help everyone in some
way.
2. Procedural? Really?
• PHP was started as a procedural <?php
function vehicle($wheels, $color, $hp) {
tool to perform quick tasks. // build a car using info provided
Large adoption brought more $car = array(
users who wanted OOP, so here ‘wheels’ => $wheels,
‘color’ => $color,
we are. ‘hp’ => $hp);
– Everything went fairly sequential return $car;
– Took a fair amount of labor within }
code to change values afterward $car = vehicle(4, ‘red’, 240);
– Procedural does make sense for // now continue with code that uses $car
simple tasks, such as CRON jobs to If ($car[‘color’] == ‘red’) {
perform quick tasks. echo ‘Your car is red’;
}
?>
Output:
Your car is red
Possible usage:
Here is the car: <?php print_r($car); ?>
3. OOP the basics
• PHP 4 brought the introduction <?php
Interface mobility {
function setColor($color);
of oop to PHP. }
function setHorsepower($hp);
– Application builds an object class Vehicle implements mobility {
– Helps with DRY (Don’t repeat public $color;
public $horsepower;
yourself) function setColor($color) {
– Simplifies structure, code still can }
$this->color = $color;
be sequential but is more ‘modular’ function setHorsepower($hp) {
– Helps keep code more readable }
$this->horsepower = $hp;
}
– Object can be manipulated easier
prior to use of the object Class Car extends Vehicle {
public $wheel;
– We instantiate the class by creating function addWheel($n) {
a “new” object, then manipulate the }
$this->wheel += $n;
object by calling the different }
“methods” within the class. $myCar = new Car();
$myCar->setColor(‘red’);
$myCar->setHorsepower(250);
$myCar->addWheel(3);
$myCar->addWheel(1);
print_r($myCar);
?>
Output:
Car Object([wheel]=>4[color]=>red[horsepower]=>250)
4. PHP 4 revisit
• PHP 4 had a very basic OOP <?php
class Reference {
presence, and looked something var $reference;
like this ->
// acted as constructor
– Variables need to be defined as function Reference() {
‘var’. $this->reference = ‘dictionary’;
– Constructors carried the same name }
as the Class.
function getReference() {
• Note: the constructor always runs return $this->reference;
“automagically” when the class is }
instantiated }
– No visibility
$rt = new Reference();
– No abstraction $reference = $rt->getReference;
– Very simple and easy to use, but echo ‘reference:’ . $reference;
lacked many features of other OOP ?>
languages at the time.
Output:
reference: dictionary
5. PHP 5.0 brought changes
• With the rollout of PHP 5.0 there were many <?php
class Reference {
changes. const DEFAULT_LANG = ‘eng’;
– Protected data with Visibility private $reference;
• Public (default) – accessed and changed private $lang;
globally public function __construct(Language $lang) {
if($lang ) {
• Protected – access and changed by $this->lang = $lang->esp;
direct descendants } else {
$this->lang = DEFAULT_LANG;
• Private – access and changed within }
class only $this->reference = ‘dictionary’;
}
– Type Hinting – notice how we specify that an
public function getReference() {
object of Language is passed to the return $this->reference;
constructor. This means we must create an }
object using the Language class first.
private function setPrivateReference() {
– Variables no longer need the ‘var’ keyword $this->reference = ‘my_dictionary’;
}
– Constructor now defined using __construct }
call
class Language {
– CONSTANT values may now be assigned public $esp = ‘Spanish’;
per-class, cannot be a variable or property or }
mathematical operation or function call. $lang = new Language();
$rt = new Reference($lang);
$reference = $rt->getReference;
echo ‘reference:’ . $reference;
?>
Output:
Reference: Spanish
6. PHP 5.0 Abstraction
• Abstraction <?php
abstract class Reference {
– Abstraction, if a class contains any abstract public $reference;
methods the class must also be abstract. abstract public function read();
– Abstracted methods must be defined by the public function __construct() {
child class. $this->reference = ‘dictionary’;
}
– Visibility in the method of the child class
must be the same, or less, restricted. final public function getReference() {
return $this->reference;
– “final” keyword prevents child classes from }
overriding a method
protected function setProtectedReference($myReference) {
– “clone” creates a copy of an object rather $this->reference = $myReference;
}
than continuing to use the same object. }
class Letter extends Reference {
public function read($personal) {
$myDictionary = $personal;
parent::setProtectedReference($myDictionary);
return $this->reference;
}
}
$rt = new Letter();
$reference = $rt->read(‘my english dictionary’);
$rt2 = clone $rt;
echo ‘reference:’ . $reference;
?>
Output:
reference: my english dictionary
7. PHP 5.0 Interfaces
• Interface <?php
interface rTemplate
– Interface, specifies which methods a {
public function getReference();
class must implement. public function setProtectedReference();
}
– All methods in interface must be public.
– Multiple interfaces can be implemented class Reference implements rTemplate {
public $reference;
by using comma separation
public function __construct() {
– Interface may contain a CONSTANT, $this->reference = ‘dictionary’;
but may not be overridden by }
implementing class public function getReference() {
return $this->reference;
}
protected function setProtectedReference($myReference) {
$this->reference = $myReference;
}
}
$rt = new Letter();
$reference = $rt->getReference();
echo ‘reference:’ . $reference;
?>
Output:
reference: dictionary
8. PHP 5.0 Exceptions
• <?php
Additional features with PHP 5. function inverse($x) {
– Exceptions – throwing an exception if (!$x) {
throw new Exception(‘Division by zero.’);
to gracefully error out, while } else {
continuing to execute the rest of the return 1/$x;
script even after the error. }
}
• Notice how we still get ‘Hello
World’ even after an exception try {
caused by ‘Division by zero’. echo inverse(5) . “n”;
echo inverse(0) . “n”; // trigger exception
– Exceptions can then be caught for } catch (Exception $e) {
logging, etc. echo ‘Caught exception: ‘, $e->getMessage(), “n”;
}
// continue execution
echo ‘Hello World’;
?>
Output:
0.2
Caught exception: Division by zero.
Hello World
9. Finally, PHP 5.3 features
• Additional features with PHP 5.3
– Namespaces
– Late Static Bindings
– Jump labels (goto)
– Closures
– __callStatic() and __invoke()
– Class Constants
– Nowdoc syntax supported
– Use Heredocs to initialize static
variables and class properties
– Heredocs with double quotes
– Ternary operator shortcut
– HTTP status 200 to 399 = success
– Dynamic access to static methods
– Exception nesting
– mail() logging of sent email
10. Namespaces
• Namespaces <?php
declare (encoding=‘UTF-8’);
– Help create a new layer of code namespace automobile;
encapsulation. class Automobile {
• Keep properties from colliding function setType($type) {
echo __NAMESPACE__ . “n”;
between areas of your code }
• Only classes, interfaces, functions }
and constants are affected namespace automobilecar;
– Anything that does not have a class Car {
namespace is considered in the function toyota() {
echo “test driven”;
Global namespace (namespace = }
“”) }
– Namespace must be declared first $car = new Car
$car->toyota();
(except ‘declare’ statement)
// OR you can use the namespace
– Can define multiple namespaces in
$auto = new automobilecarCar;
the same file. $auto->toyota();
?>
Output:
test drive
test drive
11. Namespaces – cont.
• Namespaces – cont. <?php
namespace automobile;
– You can define that something be class Automobile {
used in the “Global” namespace by function setType($type) {
echo __NAMESPACE__ . “n”;
enclosing a non-labeled namespace }
in {} brackets. (Note: if you have }
multiple namespaces in the same namespace automobilecar;
file they must all use this notation.) use automobile as auto;
– Use namespaces from within other class Car {
namespaces, along with aliasing function toyota() {
echo “test driven”;
}
}
namespace {
//global code, for this to work the examples above would also
need to use bracketed syntax
}
$automobile = new autoAutomobile;
$automobile->setType(‘none’);
?>
Output:
automobile
12. Late Static Bindings
• Late Static Binding <?php
class Automobile {
– Stores the class name of the last private function type() {
echo “Success!n”;
“non-forwarded call”. }
public function test() {
$this->type();
static::type();
}
}
class Car extends Automobile {
// empty
}
Class Truck extends Automobile {
private function type() {
// empty
}
}
$car = new Car;
$car->test();
$truck = new Truck;
$truck->test(); //fails because there is no test() in Truck
?>
Output:
Success!
Success!
Success!
Fatal error: Call to private method Truck::type() from context
‘Automobile’ in {file} on line n
13. Jump Labels (goto)
• Jump Labels (goto) <?php
– Used to jump to another section in // some code here
the program.
goto a;
– Target is specified by a label echo ‘Foo’;
followed by a colon.
– Target must be within the same file // more code here
and context.
• Cannot jump out of a function or a:
method, and cannot jump into one.
– Cannot jump into any sort of loop echo ‘Bar’;
or switch structure, but may jump ?>
out.
Output:
Bar
14. Closures (Anonymous functions)
• Closures (Anonymous functions) <?php
class Cart {
– Allows the creation of functions protected $products = array();
const PRICE_SHIRT = 20.00;
which have no specific name. const PRICE_SCARF = 4.00;
– Most useful as the value of callback public function order() {
$this->products[‘shirt’] = 2;
parameters. $this->products[‘scarf’] = 3;
}
– Can be used as the value of a
variable. public function getTotal($tax) {
$total = 0.00;
– Can inherit variables from the $callback = function ($quantity, $product) use ($tax, &$total) {
parent scope. (Not the same as $pricePerItem =
constant(__CLASS__ . “::PRICE_” . strtoupper($product));
using global variables)
$total += ($pricePerItem * $quantity) * ($tax +1.0);
};
array_walk($this->products, $callback);
return round($total, 2);
}
}
?>
Output:
55.64
15. Nested Exceptions
• Nested Exceptions <?php
class MyException extends Exception {}
– Now your criteria within a “try” can
also have another “try” nested class Test {
within, thus causing two levels of public function testing() {
failure to caught for further logging. try {
try {
throw new MyException(‘foo!’);
} catch (MyException $e) {
throw $e;
}
} catch (Exception $e) {
var_dump($e->getMessage());
}
}
}
$foo = new Test;
$foo->testing();
?>
Output:
String(4) “foo!”
16. New magic methods
• __callStatic()
– Used during overloading. Gives No code to go with this…
warning to enforce public visibility
and non-static declaration. yet. Experiment on your
• Triggered when invoking
inaccessible methods in a static own.
context.
• __invoke()
– Called when a script tries to call an
object as a function
17. Nowdoc
• Nowdoc <?php
– nowdoc is similar to heredoc, but echo <<<‘EOT’
no parsing is done inside a nowdoc. My $foo->foo.
name is “$name”. I am printing some
• Ideal for code snippets or large Now, I am printing some {$foo->bar[1]}.
blocks of text without the need for This should not print a capital ‘A’: /x41
escaping. EOT;
• Best used with static content. ?>
– Uses the same <<< sequence, but
the following identifier is encosed
in single quotes.
Output:
My name is “$name”. I am printing some
$foo->foo.
Now, I am printing some {$foo->bar[1]}.
This should not print a capital ‘A’: /x41
18. Heredoc changes
• Heredoc <?php
// Static variables
– heredoc can now initialize static function foo() {
variables and class static $bar = <<<“LABEL”
properties/constants. Nothing in here…
– Can now be declared (optional) LABEL;
}
using double quotes,
complementing the nowdoc syntax // Class properties/constants
which uses single quotes. Class foo {
const BAR = <<<FOOBAR
Constant example
FOOBAR;
public $baz = <<<FOOBAR
Property example
FOOBAR
}
?>
19. Constants addition
• Constants addition <?php
– A constant may now be declared const TEST = ‘bar’;
outside a class using the ‘const’
keyword instead of ‘declare’. Function foo() {
echo ‘foo’;
}
foo();
echo TEST;
?>
20. Ternary added shortcut
• <?php
Constants added shortcut
– Can now use ternary for simpler $test = true;
returns of evaluation. // old way
– Instead of defining the ‘middle’ part $todo = ($test ? ‘Go’ : ‘Stop’);
of the operation we simply get a ‘1’ echo $todo;
if the first expression is true.
Otherwise we receive what is in the
third part, as we used to. // added shortcut
// if $test = true then we get a true flag, otherwise we get
the second expression as a result
$tada = ($test ?: ‘whatever’);
echo $tada;
?>
Output (true):
Go1
Output (false):
Stopwhatever
21. Questions and Resources
South Florida PHP Users Group
Adam Culp http://www.Geekyboy.com
Email: adam@geekyboy.com
Resources:
http://php.net/manual/en/migration53.new-
features.php