object oriented php: an introduction
TRANSCRIPT
bgw-revised
An Introduction
Object OrientedPHP
Who's this guy, then?
PHP Developer since 2000; full-time since 2003
PHP Developer for Zend Technologies since 2005
Zend Framework contributor since January 2006
Zend Framework project lead since April 2009
I live and breathe OOP daily
Who Are You?
How many of you have used OOP before?
How many of you use OOP regularly?
If you're not using OOP, why are you interested?
What is OOP?
Object Oriented Programming
Models software concepts as discrete entities, containing attributes and capable of performing actions that may optionally use those attributes.
Start with what you know
Constants and Variables
define(FOO, 'foo');define(BAR, 'bar');$value = 'bar';
switch ($value) { case FOO: // do something; break; case BAR: // do something else break;}
Associative Arrays
$person = array( 'last_name' => "Weier O'Phinney", 'first_name' => "Matthew", 'occupation' => 'PHP Developer', 'gender' => 'Male', 'email' => 'matthew@example,com',);
Functions
function mail($to, $subject, $body){ // ... do some stuff // optionally return something: return true;}
Objects group related subjects
Start with a class declaration
class Person{}
Define some common class
member variables
class Person{ public $firstName; public $lastName; public $occupation; public $gender; public $email;}
Some types of class members
Variables
Declared using a visibility operator and normal variable naming
Constants
Declared with the const keyword, and no quotes
Methods
Declared with the function keyword
define methods, which are functions inside a class
class Person{ // ... attributes ... public function boast() { return sprintf('%s %s is a %s', $this->firstName, $this->lastName, $this->occupation ); }}
Instance variables!
Use your objects!
$matthew = new Person();$matthew->firstName =
'Matthew';$matthew->lastName = "Weier
O'Phinney";$matthew->email =
'[email protected]';$matthew->gender =
'male';$matthew->occupation = 'PHP Developer';
echo $matthew->boast();// Matthew Weier O'Phinney is a PHP
Developer
Why bother?
It's good programming
Scope and encapsulation
Re-use
(both re-using a class by instantiating many objects, and class
extension)
Type enforcement
Testability and maintenance
Some words on scope
Methods have access to:Whatever is passed to them
Any class member variables, constants, or methods (with respect to visibility)
Use $this-> within a class to access member variables and methods (unless statically declared); use -> when consuming an instance
Use self:: to access member constants
What is this visibility stuff?
Determines scope in which a class member may be accessed.Public: can be accessed via instances, anywhere within the class definition, and by any extending class.
Protected: can be accessed within the class definition, and by extending classes.
Private: may only be accessed and modified within the defining class.
Extension?
Use the extends keyword:
class Matthew
extends Person
Extends keyword!
Extension: override properties
class Matthew extends Person{ public $firstName = 'Matthew'; public $lastName = "Weier O'Phinney"; public $occupation = 'PHP Developer'; public $email = '[email protected]'; public $gender = 'male';}
Extension: override methods
class Matthew extends Person{ public function boast() { // get parent value from method $boast = parent::boast(); $boast .= ', and wrote this presentation'; return $boast; }}
Access the original method!
Extension: use the new class
$matthew = new Matthew();echo $matthew->boast();// Matthew
Weier O'Phinney is a PHP Developer,
// and wrote this presentation
Note:
using Matthew, not Person!boast() now says something new!
Abstraction
A formal way of defining extension points
Two types:Interfaces
Abstract Classes
Interfaces
Defines a public contract for classes that implement it
Ensures consuming classes will always have specific methods available
A sample interface
interface Animal{ public function makeNoise(); public function eat($food);}
Interface keyword!
Interfaces may extend
other interfaces
interface Collection
extends Countable,
IteratorAggregate{}
Collection now inherits methods
from Countable and IteratorAggregate
Implementing an interface means
defining the interfaces methods
class Family
extends Order
implements Collection{ // defined by Countable public function
count() {}
// defined by IteratorAggregate public function getIterator() {} }
implements keyword; this object follows that contract
Abstract Classes
Sometimes it's useful to create a base set of functionality.
At the same time, you may want to leave certain details up to implementing classes.
Sample Abstract Class
abstract class Person{ public $firstName; public $lastName; public $email; public $occupation; public $gender;
public function speak() {
/* implementation in here */ } // let extension define this,
though: abstract public function eat($food);}
abstract keyword; extending class must implement
Abstract classes can also
implement interfaces
abstract class Family
extends Order
implements Collection{}
Magic methods
Always prefixed by __ (double underscore)
Some tie into various object states (initialization, destruction, cloning)
Some allow "overloading" the functionality of the object (set or get "virtual" members; call "virtual" methods; etc.)
Object initialization
public function __construct(
$firstName, $lastName
) { $this->firstName = $firstName; $this->lastName =
$lastName;}
Magic method: constructor
And on the subjects of
scope and inheritance...
STATIC members:Class members that do not require an object instance in order to operate.
Global state (i.e., does not vary between instances); use rarely and wisely.
Uses the "Paamayim Nekudotayim" operator (`::`) for scope resolution
Static example
class Registry{ protected static $values = array();
public static function set($name, $value) { static::$values[$name] = $value; }
public static function get($name) { if (isset(static::$values[$name])) { return static::$values[$name]; } return null; }}Registry::set('foo', 'bar');echo Registry::get('foo'); // 'bar'
The type is small because I don't want you to use statics. :)
Type validation
PHP allows you to typehint on any class, abstract class, or interface name.
if (!$matthew instanceof Person) { echo "Imposter!";}
Parting remarks
Keep your objects discrete and concise
All members should be related to a discrete subject
Methods should not do too much
Too many members often means you're mixing concerns, and should separate into more classes
Statics: don't do them
Static functionality is appealing and seductive, but that way leads to the Dark Side
Magic methods
Learn the magic methods, but don't lean to heavily on themExcept in the case of __construct(), which is almost always a good idea.
Learn the SPL
Some SPL interfaces allow array-like access to objects, including iteration, array access to properties, etc.
Objects like ArrayObject, SplStack, and others can be huge time savers.
Solutions based off of SPL will almost always be faster than userland code.
Use OOP
but don't forget your procedural roots;
if a function will do, use it.
Resources
http://thinkvitamin.com/author/lornajanemitchell/
http://php.net/oop
http://php.net/spl
Matthew Weier O'Phinney
btv php