340 likes | 357 Views
Learn how to implement object-oriented programming in PHP, with a focus on design inspired by languages like Java or C#. This tutorial covers the basics, member visibility, objects and references, member variables and functions, inheritance, constructors and destructors, member constants, and static members.
E N D
This is an object-oriented system.If we change something, the users object. Object Oriented PHP Martin Kruliš by Martin Kruliš (v1.3)
Object Oriented PHP • First attempt made in PHP 4 • Poor design, failed • Current implementation in PHP 5 and 7 • Design is inspired by languages like Java or C# • Adaptations for interpreted loosely-typed 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.3)
Syntax Basics member visibility class Foo { public$var = 0; // a member variable publicfunction bar() { // a method echo$this->var; } } $instance = new Foo(); // create new instance $instance->var = 42; $instance->bar(); $instance = null; by Martin Kruliš (v1.3)
Objects & References • Objects Are Reference Types • Like in Java or C# classFoo { public$bar = 0; publicfunction__construct($b) { $this->bar = $b; } } $foo1 = new Foo(10); $foo2 = $foo1; $foo3 = &$foo1; $foo2 = new Foo(20); $foo3 = new Foo(30); objref#2 Foo(20) $foo2 objref#1 objref#3 $foo1 objref#1 Foo(10) Foo(30) $foo3 by Martin Kruliš (v1.3)
Member Variables • 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 classFoo { private $bar; } $foo = newFoo(); $foo->bar = 1;// Error! 'bar'is private $foo->barbar = 42;// OK,new member is created by Martin Kruliš (v1.3)
Member Variables • Member Variables are Dynamic • Why declare members in classes? • Visibility control • Default values (initialization) • Better readability (documentation comments, …) • Reflection class Point { public $x = 1; public $y = 2; } $p = new Point(); $p = newstdClass(); $p->x = 1; $p->y = 2; vs. Base class without any members (used also for implicit object constructions) by Martin Kruliš (v1.3)
Member Functions (Methods) • 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 • Otherwise the Same as Regular Functions • No overloading, variadic, … by Martin Kruliš (v1.3)
Inheritance • 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 classMyFooextends Foo { public function Bar() { parent::Bar(); } } by Martin Kruliš (v1.3)
Constructor • 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.3)
Destructor • 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.3)
Member Constants • 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 { constBAR = 42; functionechoBar() { echo self::BAR; } } echo Foo::BAR; by Martin Kruliš (v1.3)
Static Members • Revision Static vs. Regular (Dynamic) Members Class static variable/constant static method new operator method Object Object member variable logically belongs to (is stored at) is used (called) on by Martin Kruliš (v1.3)
Static Members • Static (Class) Members • Declared by static keyword before the member • Accessed by :: operator (like constants) • E.g., MyClass::$statVaror 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 { publicstatic $x; } class B extends A { publicstatic $x; } class C extends A {} … C::$x = 42; new variable Example 1 same as A::$x by Martin Kruliš (v1.3)
Late Static Binding • 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(); static::who(); Prints ‘A’ Prints ‘B’ by Martin Kruliš (v1.3)
Small Mind Teaser class A { functionfoo() { echo (isset($this)) ? 'dynamic' : 'static'; } } classB { functionbar() { A::foo(); // static call } } A::foo(); // prints 'static' $obj = newB(); $obj->bar(); // prints 'dynamic' This is only a mentalexercise. Do not callregular methods statically! by Martin Kruliš (v1.3)
AbstractEntities • 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 abstractclassAbstractClass { abstractfunctionfoo(); } classConcreteClassextendsAbstractClass { functionfoo() { … foo body … } } $obj = newConcreteClass(); by Martin Kruliš (v1.3)
Interfaces • Interfaces • List of public methods a class must implement • Interfaces may be extended like classes • Using the extends operator interfaceIFoo { public function bar($goo); } class Foo implementsIFoo { public function bar($goo) { ... } } Unlike in case of inheritance, a class may implement multiple interfaces by Martin Kruliš (v1.3)
Object Iterators • Iterating Member Variables • By foreach construct (like arrays) • Keys are strings with the name of the member • Only visible (accessible) members are iterated classMyClass { public $var1 = 1; public $var2 = 2; private$var3 = 3; } $obj = newMyClass(); foreach($objas $key => $value) { ... } • Custom iteration can be implemented • Interface Iterator and IteratorAggregate Example 2 by Martin Kruliš (v1.3)
Generators PHP 5.5 • Detached Custom Iterators • The foreach construct is powerful • But it iterates over structures (arraysand 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 functionrange_gen($from, $to, $step) { for ($i = $from; $i < $to; $i += $step) yield $i; } foreach(range_gen(1,10,2) as $value) ... Returns next value Local context is preserved by Martin Kruliš (v1.3)
Object Cloning • Copying Reference vs. Copying Object • Assignment copies reference, not the object • Object copy must be invoked explicitly, by cloning $foo = new Foo(); $foo2 = $foo; $foo3 = clone $foo; Foo object #1 $foo $foo2 Foo object #2 $foo3 by Martin Kruliš (v1.3)
Object Cloning • Shallow vs. Full Copy • Cloning process creates shallow copy by default • Assignment operator is used on every member • Post-cloning operations may be implemented in method __clone(), which is invoked on the copy public function __clone() { $this->innerObj = clone $this->innerObj; } $this is newly copied object, which has all members already assigned Nested cloning od inner object (a deep copy) Example 3 by Martin Kruliš (v1.3)
Magic Methods • 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 access to member variables, which are not declared or not visible • Declared variables are accessed directly • Only for regular members, not for static • Handle with care • They may lead to less readable core or even errors by Martin Kruliš (v1.3)
Magic Methods • Method Invocation Override • __call() – intercepts calls to not visible methods • __callStatic() – the same for static methods • __invoke() – when object is called as function • Array Access Interface • Allows using the object as an array ($obj[…]) • booleanoffsetExists(mixed$offset) • mixedoffsetGet(mixed$offset) • voidoffsetSet(mixed$offset, mixed $value) • voidoffsetUnset(mixed$offset) PHP 5.4 Example 4 by Martin Kruliš (v1.3)
Serialization • Object (De)Serialization • Using magic methods • __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, logged, …) • Using Serializable interface • string serialize(void) • voidunserialize(string$serialized) by Martin Kruliš (v1.3)
Comparing Objects • 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.3)
Type Detection/Verification • Operator instanceof • Verifies whether object is an instance of given class or derived class, or implements given interface if ($foo instanceofFooClass) ... • 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.3)
OOP-Related Functions • 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.3)
Autoloading • Automatic Loading of Classes • Useful for libraries, reduces the number of includes • Global function __autoload() • Called automatically when undeclared class is accessed • spl_autoload_register() • Register (possibly multiple) callback handler(s) function__autoload($className) { if (file_exists("libs/$className.php")) include"libs/$className.php"; else log("Class $className is not defined!"); } by Martin Kruliš (v1.3)
Reflection • Reflection • A mechanism implemented in (dynamic) languages to inspect types, objects, classes, etc. at runtime • PHP holds a specific reflector class for each entity • ReflectionType • ReflectionFunction • ReflectionClass • ReflectionObject • ReflectionProperty • ReflectionParameter • … by Martin Kruliš (v1.3)
Reflection • Reflection API in PHP • An object of appropriate reflector is instantiated • E.g., To list information about a class, an object of ReflectionClass is created (by the name of the class) • Each reflector provides methods to access the data • Class/Object reflector allows listing properties, methods, constants, and inspect inheritance • Function/Method reflectors give information about arguments, modifiers, and creates dynamic closure • … • API also provides access to doc comments /** … */ • Can be used for custom annotations Example 5 by Martin Kruliš (v1.3)
Namespaces • Namespaces • Another way how to encapsulate spaceof identifiers • Affect classes, traits, interfaces, functions, constants • Similar to directories and files • Declaration: namespaceidentifier; • 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 – useidentifier [asidentifier]; by Martin Kruliš (v1.3)
Traits • 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 traitSayHello { public functionhelloWorld() { echo 'Hello World'; } } classmyClass { useSayHello; ... PHP 5.4 by Martin Kruliš (v1.3)
Anonymous Classes PHP 7 • Instant One-use Classes • Similar to anonymous functions interfaceLogger { public functionlog(string $msg); } ... $app->addLogger(newclassimplementsLogger { public functionlog(string $msg) { echo $msg; } }); by Martin Kruliš (v1.3)
Discussion by Martin Kruliš (v1.3)