Martin Kruliš This is an Object Oriented system. If we change something, the users object by Martin Kruliš (v1.0)1
First attempt made in PHP 4 ◦ Poor design, failed Current implementation in PHP 5 ◦ Design is inspired by languages like Java or C# ◦ Adaptations for interpreted type-free language E.g., there are no “virtual” methods ◦ Powerful in combination with PHP-specific features For instance with variable variables: $obj = new $className(); $obj->$methodName(); by Martin Kruliš (v1.0)2
class Foo { public $var = 0; // a member variable public function bar() { // a method echo $this->var; } $instance = new Foo(); // create new instance $instance->var = 42; $instance->bar(); $instance = null; by Martin Kruliš (v1.0)3 member visibility
Member Visibility Type (is mandatory) ◦ public – accessible from anywhere ◦ protected – access. from within and derived classes ◦ private – only accessible from within the class Implicit Member Declaration ◦ Created as public by default class Foo { private $bar; } $foo = new Foo(); $foo->bar = 1; // Error! 'bar' is private $foo->barbar = 42; // OK, new member is created by Martin Kruliš (v1.0)4
Visibility Type ◦ The same meaning as for variables ◦ Optional, set as public if missing Accessing the Object Instance ◦ Current object instance is available through $this ◦ It must be used to access member variables To distinguish members from local variables No Overloading ◦ Same as for functions (incl. variable arguments) by Martin Kruliš (v1.0)5
Standard Inheritance Model ◦ Each class may have only one parent class Multi-inheritance is achieved by interfaces and traits Overriding Methods ◦ All methods act as if they are virtual ◦ parent::method() – calling overridden version AncestorClass::method() – calling explicit version ◦ Methods tagged as final cannot be overridden class MyFoo extends Foo { public function Bar() { parent::Bar(); } by Martin Kruliš (v1.0)6
Special Method __construct() ◦ Used to initialize the object ◦ Called automatically (by the new operator) ◦ May have arguments Same behavior as regular method (e.g., no overloading) ◦ Does not have to be defined Parent’s constructor or implicit constructor is used ◦ Parent’s constructor is not called implicitly ◦ Constructor should be public Except for some special cases like Singleton or Factory Method design patterns by Martin Kruliš (v1.0)7
Special Method __destruct() ◦ Called when the object is garbage-collected When ref. count reaches 0 or at the end of the script ◦ Does not have to be defined Parent’s destructor or implicit destructor is used ◦ Destructor should not throw exceptions Since they may not be handled properly ◦ Parent’s destructor is not called implicitly ◦ Destructor should be public And there are no reasonable exceptions by Martin Kruliš (v1.0)8 Example 1
Member Variables with Constant Values ◦ Declared by const prefix ◦ No visibility declaration, treated as public ◦ Accessed from class using :: operator By class name or by self identifier from within class Foo { const BAR = 42; function echoBar() { echo self::BAR; } } echo Foo::BAR; by Martin Kruliš (v1.0)9
Static (Class) Members ◦ Declared by static keyword before the member ◦ Accessed by :: operator (like constants) E.g., MyClass::$statVar or MyClass::myFunc() ◦ One instance, no matter how many objects class has I.e., static methods does not have $this ◦ The same types of visibility as regular members ◦ Small differences in inheritance class A { static public $x; } class B extends A { static public $x; } class C extends A {} … C::$x = 42; by Martin Kruliš (v1.0)10 new variable same as A::$x Example 2
Late Binding for Static Calls ◦ When static:: is used instead of self:: class A { public static function who() { echo __CLASS__; } public static function test() { self::who(); } } class B extends A { public static function who() { echo __CLASS__; } } B::test(); by Martin Kruliš (v1.0)11 Prints ‘ A ’ static::who(); Prints ‘ B ’
class A { function foo() { echo (isset($this)) ? 'dynamic' : 'static'; } class B { function bar() { A::foo(); // static call } A::foo(); // prints 'static' $obj = new B(); $obj->bar(); // prints 'dynamic' by Martin Kruliš (v1.0)12 This is only a mental exercise. Do not call regular methods statically!
Abstract Classes and Methods ◦ Prefixed with keyword abstract ◦ Abstract class cannot be instantiated ◦ Abstract method has no body It is expected to be implemented in derived class abstract class AbstractClass { abstract function foo(); } class ConcreteClass extends AbstractClass { function foo() { … foo body … } } $obj = new ConcreteClass(); by Martin Kruliš (v1.0)13
Interfaces ◦ List of public methods a class must implement ◦ Interfaces may be extended like classes Using the extends operator interface IFoo { public function bar($goo); } class Foo implements IFoo { public function bar($goo) {... } by Martin Kruliš (v1.0)14
Iterating through Member Variables ◦ By foreach construct (like through arrays) Keys are strings with the name of the member Iteration visits only visible members ◦ Custom iteration can be implemented The class must implement interface Traversable class MyClass { public $var1 = 1; public $var2 = 2; private $var3 = 3; } $obj = new MyClass(); foreach ($obj as $key => $value) {... } by Martin Kruliš (v1.0)15 Example 3
Reference Passing Principle ◦ Assignment copies reference, not the object ◦ Object copy must be invoked explicitly, by cloning $foo = new Foo(); $foo2 = clone $foo; Shallow vs. Full Copy ◦ Cloning process creates shallow copy ◦ Post-cloning operations may be implemented in method __clone(), which is invoked on the copy public function __clone() { $this->innerObj = clone $this->innerObj; } by Martin Kruliš (v1.0)16 Example 4
Member Variables Accessors ◦ __get() – control read-access to members ◦ __set() – control write-access to members ◦ __isset() – isset() override for members ◦ __unset() – unset() override for members ◦ Overrides only access to member variables, which are not declared or not visible Declared variables are accessed directly ◦ Only for regular members, not for static by Martin Kruliš (v1.0)17
Method Invocation Override ◦ __call() – intercepts calls to not visible methods ◦ __callStatic() – the same for static methods ◦ __invoke() – when object is called as function Object (De)Serialization ◦ __sleep() – invoked when the object is being serialized (to a persistent storage) ◦ __wakeup() – invoked when the object is being deserialized (from a persistent storage) ◦ __toString() – returns string representation of the object (e.g., so it can be printed) by Martin Kruliš (v1.0)18 Example 5 PHP 5.4
Reference Comparison Behavior ◦ $object1 == $object2 True if both object are of the same class and all member variables are equal ( == ) ◦ $object1 === $object2 True if both variables hold a reference to exactly the same object ◦ Behavior of != and !== operators can be easily extrapolated by Martin Kruliš (v1.0)19
Controlling Types of Function Arguments ◦ Function (method) arguments may be prefixed with Class/interface ~ the argument must be an object of that class, derived class, or it must implement the interface array keyword ~ the argument must be an array callable keyword ~ the argument must be invokeable I.e., function, or object with __invoke() method ◦ The type of the calling argument is enforced Noncompliance triggers PHP fatal error function foo(MyClass $obj, array $params) {... } by Martin Kruliš (v1.0)20 PHP 5.4
Operator instanceof ◦ Verifies whether object is an instance of given class or derived class, or implements given interface if ($foo instanceof FooClass)... Functions Testing Types ◦ get_class() – returns class name as string ◦ get_parent_class() – name of the parent class ◦ is_a() – verifies that object is of given class ◦ is_subclass_of() – like is_a(), but checks also derived classes by Martin Kruliš (v1.0)21
Traits ◦ Class-like mechanism for code reuse Horizontal composition of behavior (similar to Mixins) ◦ Trait Special class that cannot be instantiated May contain both member variables and methods It can be added to regular classes trait SayHello { public function helloWorld() { echo 'Hello World'; } } class myClass { use SayHello; by Martin Kruliš (v1.0)22 PHP 5.4
Testing Existence ◦ class_exists(), interface_exists() ◦ method_exists() Listings ◦ get_declared_classes(), get_declared_interfaces() ◦ get_class_methods() ◦ get_object_vars() ◦ get_class_vars() Indirect Method Calls call_user_func_array(array($obj, 'methodName'), $params); by Martin Kruliš (v1.0)23
TODO!!! by Martin Kruliš (v1.0)24
Automatic Loading of Classes ◦ Useful for libraries, reduces the number of includes ◦ Global function __autoload() spl_autoload_register() register multiple handlers function __autoload($className) { include 'libs/'. $className. '.php'; } function __autoload($className) { log("Class $className is not defined!"); } by Martin Kruliš (v1.0)25
Namespaces ◦ Another way how to encapsulate space of identifiers Affect classes, traits, interfaces, functions, constants Similar to directories and files ◦ Declaration: namespace identifier; First statement in the file Identifier may be hierarchical (separator is backslash) ◦ Dereferencing myClass -> currentNS\myClass name\space\myClass -> currentNS\name\space\myClass \name\space\myClass – absolute path, no modifications ◦ Aliasing – use identifier [as identifier]; by Martin Kruliš (v1.0)26
Custom Iterators ◦ The foreach construct is powerful But it iterates over structures (arrays and objects) ◦ Custom iterator can be built ( Iterator interface) Both memory demanding and tedious ◦ Generator is a function that yields values It can be used in foreach construct function my_generator($n) { for ($i = 0; $i < $n; ++$i) yield $i; } foreach (my_generator(42) as $value) by Martin Kruliš (v1.0)27 Returns next value Local context is preserved PHP 5.5
by Martin Kruliš (v1.0)28