Slide 1

Slide 1 text

Epic PHP #5 Рома Лапин, Evercode Lab

Slide 2

Slide 2 text

Основы ООП

Slide 3

Slide 3 text

Объекты? Стратегию ООП лучше всего описать как смещение приоритетов в процессе программирования от функциональности приложения к структурам данных. Это позволяет программисту моделировать в создаваемых приложениях реальные объекты и ситуации.

Slide 4

Slide 4 text

ООП • Инкапсуляция • Полиморфизм • Наследование

Slide 5

Slide 5 text

ООП

Slide 6

Slide 6 text

Class class ComplicatedClass { ! public $someVar = 'a default value'; ! public function displayVar() { echo $this->someVar; } }

Slide 7

Slide 7 text

Class • Может содержать свои константы, переменные (свойства) и функции (методы) • Название класса не может быть зарезервированным словом PHP • Название может начинаться с буквы или символа подчеркивания и состоять из букв, цифр и _.

Slide 8

Slide 8 text

$this Псевдопеременная, доступная, когда метод вызывается в контексте объекта. Является ссылкой на вызывающий объект.

Slide 9

Slide 9 text

$this

Slide 10

Slide 10 text

new $instance = new ComplicatedClass(); ! $className = 'Foo'; $instance = new $className(); // Foo()

Slide 11

Slide 11 text

new • Создает экземпляр класса • В контексте класса можно создать объект, используя new self или new parent

Slide 12

Slide 12 text

Class vs Object?

Slide 13

Slide 13 text

Class vs Object?

Slide 14

Slide 14 text

Свойства // invalid property declarations: public $var1 = 'hello ' . 'world'; public $var3 = 1+2; public $var4 = self::myStaticMethod(); public $var5 = $myVar; ! // valid property declarations: public $var6 = myConstant; public $var7 = array(true, false);

Slide 15

Slide 15 text

Задание

Slide 16

Slide 16 text

Задание Создайте класс SuperHero. Придумайте, какие у него могут быть свойства.

Slide 17

Slide 17 text

extends class ExtendClass extends ComplicatedClass { function displayVar() { echo "Extending class\n"; parent::displayVar(); } } ! $extended = new ExtendClass(); $extended->displayVar();

Slide 18

Slide 18 text

extends • Наследоваться можно только от одного класса • Свойства и методы могут быть переопределены (если не заданы как final в родителе) • Сигнатура параметров переопределямых методов должна совпадать (кроме конструктора), иначе — E_STRICT

Slide 19

Slide 19 text

extends

Slide 20

Slide 20 text

Задание Создайте базовый класс Сharacter. Унаследуйте от него наш SuperHero и новый класс SuperVillain. Вынесите в Character общие свойства для героев и злодеев, а в них оставьте только уникальные поля.

Slide 21

Slide 21 text

Задание

Slide 22

Slide 22 text

Константы class MyClass { const constant = 'constant value'; ! function showConstant() { echo self::constant . "\n"; } } ! echo MyClass::constant . "\n"; ! $classname = "MyClass"; echo $classname::constant . "\n"; // As of PHP 5.3.0 ! $class = new MyClass(); $class->showConstant(); ! echo $class::constant."\n"; // As of PHP 5.3.0

Slide 23

Slide 23 text

Константы • доступны как часть класса • доступны во всех областях видимости • могут содержать только скалярные значения • способствуют более чистому коду • работают быстрее констант, определенных через define()

Slide 24

Slide 24 text

Constructor

Slide 25

Slide 25 text

Constructor class BaseClass { function __construct() { print "In BaseClass constructor\n"; } } ! class SubClass extends BaseClass { function __construct() { parent::__construct(); print "In SubClass constructor\n"; } } ! class OtherSubClass extends BaseClass { // inherits BaseClass's constructor }

Slide 26

Slide 26 text

Constructor // In BaseClass constructor $obj = new BaseClass(); ! // In BaseClass constructor // In SubClass constructor $obj = new SubClass(); ! // In BaseClass constructor $obj = new OtherSubClass();

Slide 27

Slide 27 text

Constructor • вызывается при создании объекта • родительский конструктор надо вызывать явно: parent::__construct() • если не переопределен, наследуется от класса родителя (если там он не private) • при переопределении параметры могут меняться

Slide 28

Slide 28 text

Задание Добавьте нашим героям и злодеям конструкторы, чтобы при создании объекта задавались основные свойства. Общие параметры должны задаваться только в конструкторе родительского класса.

Slide 29

Slide 29 text

Destructor class MyDestructableClass { function __construct() { print "In constructor\n"; $this->name = "MyDestructableClass"; } ! function __destruct() { print "Destroying " . $this->name . "\n"; } } ! $obj = new MyDestructableClass();

Slide 30

Slide 30 text

Destructor • будет вызван, как только на объект не останется ссылок • либо при завершении работы скрипта • родительский destructor надо вызывать явно: parent::__destruct() • будет вызван даже при остановке скрипта с помощью exit()

Slide 31

Slide 31 text

Destructor

Slide 32

Slide 32 text

PPP & F • Public • Private • Protected • Final — может применять к методам и классу целиком

Slide 33

Slide 33 text

PPP class MyClass { public $public = 'Public'; protected $protected = 'Protected'; private $private = 'Private'; ! function printHello() { echo $this->public; echo $this->protected; echo $this->private; } }

Slide 34

Slide 34 text

PPP $obj = new MyClass(); echo $obj->public; // Works echo $obj->protected; // Fatal Error echo $obj->private; // Fatal Error $obj->printHello(); // Shows Public, Protected and Private

Slide 35

Slide 35 text

PPP class MyClass2 extends MyClass { // We can redeclare the public and protected method, but not private protected $protected = 'Protected2'; ! function printHello() { echo $this->public; echo $this->protected; echo $this->private; } }

Slide 36

Slide 36 text

PPP $obj2 = new MyClass2(); echo $obj2->public; // Works echo $obj2->private; // Undefined echo $obj2->protected; // Fatal Error $obj2->printHello(); // Shows Public, Protected2, Undefined

Slide 37

Slide 37 text

Задание. Проверьте, правильно ли у вас расставлены уровни доступа у свойств и методов в созданных ранее классах. Добавьте свойств с недостающими уровнями видимости.

Slide 38

Slide 38 text

Задание. На удивление в PHP можно получить доступ к private и protected свойствам и методам объкта из объекта такого же класса. ! Попробуйте сами написать код, подтверждающий это. Если не получится, то найдите в документации и напишите подобный.

Slide 39

Slide 39 text

Paamayim Nekudotayim ::

Slide 40

Slide 40 text

static

Slide 41

Slide 41 text

static

Slide 42

Slide 42 text

static print Foo::$my_static . "\n"; ! $foo = new Foo(); print $foo->staticValue() . "\n"; print $foo->my_static . "\n"; // Undefined "Property" my_static ! print $foo::$my_static . "\n"; $classname = 'Foo'; print $classname::$my_static . "\n"; // As of PHP 5.3.0 ! print Bar::$my_static . "\n"; $bar = new Bar(); print $bar->fooStatic() . "\n";

Slide 43

Slide 43 text

static • доступны именно как часть класса • вызываются без создания объекта • вызов статичного свойства с помощью объектной нотации — Notice • по умолчанию public • использовать $this внутри статичных методов нельзя

Slide 44

Slide 44 text

abstract

Slide 45

Slide 45 text

abstract abstract class AbstractClass { // Force Extending class to define this method abstract protected function getValue(); abstract protected function prefixValue($prefix); ! // Common method public function printOut() { print $this->getValue() . "\n"; } }

Slide 46

Slide 46 text

abstract class ConcreteClass1 extends AbstractClass { protected function getValue() { return "ConcreteClass1"; } ! public function prefixValue($prefix) { return "{$prefix}ConcreteClass1"; } }

Slide 47

Slide 47 text

abstract • Класс должен быть объявлен абстрактным, если содержит или наследует хотя бы один абстрактный метод без имплементации • класс может иметь только одного предка • реализует ограничения для дизайна группы классов

Slide 48

Slide 48 text

Задание. Сделайте класс Character абстрактным и объявите в нем несколько абстрактных методов методов и один-два уже реализованных (общих для героев и злодеев). Абстрактные методы реализуйте в классах- наследниках. Например: saveWorld(), fight(), makeSomethingBad(), muahahahaha(), think(), putOnMask(), useSuperPower(), sayCatchPhrase() и т.д.

Slide 49

Slide 49 text

interface Интерфейсы позволяют создавать код, который определяет, какие методы должны реализовывать классы без необходимости определять саму реализацию методов.

Slide 50

Slide 50 text

interface

Slide 51

Slide 51 text

interface interface iTemplate { public function setVariable($name, $var); public function getHtml($template); }

Slide 52

Slide 52 text

interface class Template implements iTemplate { private $vars = array(); public function setVariable($name, $var) { $this->vars[$name] = $var; } public function getHtml($template) { foreach($this->vars as $name => $value) { $template = str_replace('{' . $name . '}', $value, $template); } return $template; } }

Slide 53

Slide 53 text

interface • все метода интерфейса — public, иначе просто бессмысленно :) • класс может имплементить больше одного интерфейса • но у этих интерфейсов не должно быть методов с одинаковыми именами

Slide 54

Slide 54 text

interface • интерфейсы могут наследоваться • интерфейсы могут содержать константы • сигнатуры методов интерфейса и класса должны совпадать

Slide 55

Slide 55 text

Задание. Создайте два интерфейса: один супергеройский, другой суперзлодейский. Объявите в них обязательные методы. Пусть наши классы будут реализовывать каждый свой интерфейс. ! Варианты методов: doEvil(), muahaha(), scaryFace(), saveTheWorldAgainBeforeBreakfast()

Slide 56

Slide 56 text

Instanceof Позволяет определить является ли объект экземпляром класса или интерфейса с учетом наследования.

Slide 57

Slide 57 text

Instanceof

Slide 58

Slide 58 text

Instanceof class ParentClass { } ! class MyClass extends ParentClass { } ! $a = new MyClass(); ! var_dump($a instanceof MyClass); var_dump($a instanceof ParentClass);

Slide 59

Slide 59 text

Instanceof interface MyInterface { } ! class MyClass implements MyInterface { } ! $a = new MyClass(); ! var_dump($a instanceof MyClass); var_dump($a instanceof MyInterface);

Slide 60

Slide 60 text

Задание. У нас уже есть три класса и два интерфейса. Создайте несколько объектов и проверьте являются ли они инстансами каждого класса и интерфейса.

Slide 61

Slide 61 text

Object Iteration class MyClass { public $var1 = 'value 1'; public $var2 = 'value 2'; public $var3 = 'value 3'; ! protected $protected = 'protected var'; private $private = 'private var'; ! function iterateVisible() { echo "MyClass::iterateVisible:\n"; foreach($this as $key => $value) { print "$key => $value\n"; } } }

Slide 62

Slide 62 text

Object Iteration $class = new MyClass(); ! foreach($class as $key => $value) { print "$key => $value\n"; } echo "\n"; ! ! $class->iterateVisible();

Slide 63

Slide 63 text

Magic methods

Slide 64

Slide 64 text

Magic methods • __toString() • __call() • __get() • __set()

Slide 65

Slide 65 text

Задание. Задайте классам героев и злодеев магические методы. Пусть в них просто выводится что-нибудь жизнеутверждающее и нетленное.

Slide 66

Slide 66 text

Клонирование

Slide 67

Slide 67 text

Клонирование $class = new MyClass(); ! $copy = $class; ! do_some_stuff($copy); ! /* $class и $copy остались ссылками на один и тот же объект и будут изменены оба */

Slide 68

Slide 68 text

Клонирование $class = new MyClass(); ! $copy = clone $class; ! do_some_stuff($copy); ! /* $class и $copy будут разными объектами. Изменения в $copy не будут влиять на изменения в $class */

Slide 69

Slide 69 text

Клонирование public function __clone() { /* если при клонировании нужны особые условия */ }

Slide 70

Slide 70 text

Сравнение объектов • == — одинаковые атрибуты, значения и реализуют один и тот же класс • === — ссылки на один и тот же инстанс класса

Slide 71

Slide 71 text

Namespaces

Slide 72

Slide 72 text

Проблемы • Коллизии имен между пользовательским кодом и классами/функциями/ константами самого PHP или стороннего используемого кода. • Слишком длинные имена, которыми решалась предыдущия проблема

Slide 73

Slide 73 text

Namespaces

Slide 74

Slide 74 text

Namespaces $a = strlen('hi'); ! $d = namespace\MYCONST; ! $d = __NAMESPACE__ . '\MYCONST'; echo constant($d);

Slide 75

Slide 75 text

Namespaces • namespace — первое, что есть в php файле после открывающего тэга • Один и тот же namespace может быть объявлен в нескольких файлах • Пространства имен могут формировать иерархию

Slide 76

Slide 76 text

Namespaces • к глобальному пространству имен всегда можно обратиться добавив перед вызовом \ • __NAMESPACE__ — константа содержащая имя текущего пространства имен

Slide 77

Slide 77 text

Импортируем use My\Full\Classname as Another, My\Full\NSname; ! $obj = new Another; // создает объект класса My\Full\Classname ! NSname\subns\func(); // вызывает функцию My\Full\NSname\subns\func

Slide 78

Slide 78 text

Интерпретируем • имя указано без\ в начале — класс будет искаться в текущем namespace • при его отсутствии — Fatal error • Для функций и констант без полного имени ненайденных в текущем namespace будет попытка найти их в глобальном пространстве имен (fallback).

Slide 79

Slide 79 text

PSR-0 • \Zend\Acl => /vendor/Zend/Acl.php • \Doctrine\Common\IsolatedClassLoader => /vendor/Doctrine/Common/ IsolatedClassLoader.php • https://github.com/php-fig/fig-standards/ blob/master/accepted/PSR-0.md

Slide 80

Slide 80 text

Интерпретируем

Slide 81

Slide 81 text

Задание. Организуем наш код как взрослые. Для приложения — отдельный каталог epicoop Весь код классов — в epicoop/src. Главный namespace — Epicphp Расположение классов соответствует PSR-0 index.php — epicoop/web В index.php подключаем все нужные классы

Slide 82

Slide 82 text

Exceptions

Slide 83

Slide 83 text

Exceptions function inverse($x) { if (!$x) { throw new Exception('Division by zero.'); } else return 1/$x; } ! try { echo inverse(5) . "\n"; echo inverse(0) . "\n"; } catch (Exception $e) { echo 'Caught exception: ', $e->getMessage(), "\n"; }

Slide 84

Slide 84 text

Exceptions

Slide 85

Slide 85 text

Exceptions • Унифицированный метод обработки ошибок • По сути являются объектами, создаваемыми (“выбрасываемыми”) в случае ошибки • Все исключения в throw должны быть инстансами класса Exception или его наследников

Slide 86

Slide 86 text

Exceptions • Каждый try должен иметь хотя бы один catch • блоков catch может быть несколько (для разных классов исключений) • После “выкинутого” код не выполняется до первого найденного catch • Исключение не поймано — Fatal error

Slide 87

Slide 87 text

Exceptions • Внутренние функции PHP используют error reporting и только новые ООП расширения исользуют exceptions, но это можно переопределить • http://www.php.net/manual/en/ spl.exceptions.php

Slide 88

Slide 88 text

Autoloading

Slide 89

Slide 89 text

Проблемы • Много классов в ООП приложениях • Как правило, один класс — один файл • До использования каждый класс надо подключить • Получались частоколы require и include • Много ошибок из-за забытых файлов

Slide 90

Slide 90 text

Проблемы

Slide 91

Slide 91 text

__autoload() function __autoload($class_name) { require_once "/www/library/{$class_name}.php"; } ! $a = new friend();

Slide 92

Slide 92 text

__autoload() function __autoload($name) { echo "Want to load $name.\n"; throw new Exception("Unable to load $name."); } ! try { $obj = new NonLoadableClass(); } catch (Exception $e) { echo $e->getMessage(), "\n"; }

Slide 93

Slide 93 text

spl_autoload_register Позволяет сделать несколько автолоадеров на случай разных концепций загрузки файлов. ! function my_autoloader($class) { include 'classes/' . $class . '.class.php'; } ! spl_autoload_register('my_autoloader');

Slide 94

Slide 94 text

Задание. Убираем из index.php все require и создаем функцию автолоадинга. Проверяем, что при создании объектов классов ошибок нет.

Slide 95

Slide 95 text

Standard PHP Library (SPL)

Slide 96

Slide 96 text

SPL Входит в состав PHP и содержит коллекцию полезных классов и интерфейсов.

Slide 97

Slide 97 text

SPL • Iterators • Datastructures • Interfaces • Exceptions • “и кое-что еще...” © • http://php.net/spl

Slide 98

Slide 98 text

Управление зависимостями

Slide 99

Slide 99 text

Проблемы • На PHP написано много кода • На самом деле много • Вам столько даже представить сложно • И я не шучу • С чего бы мне шутить

Slide 100

Slide 100 text

Проблемы • Посреди тон кода есть куча полезностей • Фреймворки • Библиотеки • Компоненты • Да, большинство простых проблем уже решены за вас

Slide 101

Slide 101 text

Проблемы • И вы будете использовать чужие фреймворки, библиотеки, компоненты... • Много, это точно • Но их же надо как-то искать? • Устанавливать? • Обновлять?

Slide 102

Slide 102 text

PEAR?

Slide 103

Slide 103 text

Fuck PEAR!

Slide 104

Slide 104 text

No content

Slide 105

Slide 105 text

Composer Composer является блестящим менеджером зависимостей для PHP. Укажите список зависимостей вашего проекта, в файле composer.json и с несколькими простыми командами, Composer автоматически скачает зависимости вашего проекта и установит автозагрузку для вас.

Slide 106

Slide 106 text

Composer • Множество совместимых библиотек • Их можно искать: https://packagist.org/ • Взрывное развитие и популярность у разработчиков • Если вашей библиотеки нет в packagist и ее не поставить через composer, то вашей библиотеки просто нет

Slide 107

Slide 107 text

Composer curl -s https://getcomposer.org/installer | php ! php composer.phar require twig/twig:~1.8 ! php composer.phar install

Slide 108

Slide 108 text

Composer

Slide 109

Slide 109 text

composer.json { "require": { "silex/silex": "1.0.*", "swiftmailer/swiftmailer": ">=4.1.2,<4.2-dev", "twig/twig": ">=1.8,<2.0-dev", "symfony/twig-bridge": "2.1.*", "symfony/form": "2.1.*", "symfony/validator": "2.1.*", "symfony/config": "2.1.*", "symfony/translation": "2.1.*", "rmzamora/google-api-php": "dev-master", "zendframework/zendgdata": "2.0.*", "symfony/security": "2.1.*" }, "minimum-stability": "dev", ! "autoload": { "psr-0": { "App": "src/" } } }

Slide 110

Slide 110 text

Composer • composer.json • composer.lock • php composer.phar update • http://getcomposer.org/doc/00-intro.md • Composer умеет ставить либы из PEAR

Slide 111

Slide 111 text

Задание. Установите композер в наш epicoop. Найдите в packagist symfony/finder, symfony/config, symfony/http-foundation. Установите их через composer.

Slide 112

Slide 112 text

Дизайн и паттерны

Slide 113

Slide 113 text

Дизайн и паттерны

Slide 114

Slide 114 text

Code Reuse • Мы решаем одни и те же проблемы каждый день • Мы решаем те же пробемы, что и наши “соседи” каждый день • Мы решаем одинаковые проблемы на разных проектах • И мы ленивые, но хотим делать хорошо!

Slide 115

Slide 115 text

Дизайн и паттерны • Правильные и конкретные решения для общих проблем • Общий язык для общения между разработчиками

Slide 116

Slide 116 text

Singleton public static function getInstance() { static $instance = null; if (null === $instance) { $instance = new static; } ! return $instance; } ! protected function __construct() { }

Slide 117

Slide 117 text

Singleton $obj = Singleton::getInstance(); \var_dump($obj === Singleton::getInstance()); // bool(true)

Slide 118

Slide 118 text

Singleton • убедиться, что в системе только один инстанс определенного класса • применения: обертки соединений (база данных, файлы, внешние источники данных) • Не рекомендуется к использованию в последнее время

Slide 119

Slide 119 text

Registry • Расширение Singleton • По сути явлется хранилищем для данных и инстансов других объектов • И обеспечивает, что это хранилище в системе одно • Zend_Registry

Slide 120

Slide 120 text

Factory • Предоставляет собой общий интерфейс к набору классов со схожей функциональностью, но разной начинкой • Создает инстанс нужного класса • например, фабрика для выбора хранилища данных, службы доставки, платежной системы

Slide 121

Slide 121 text

Factory

Slide 122

Slide 122 text

Front controller • Одна (!) точка входа для всех запрсов приложения • Совсем одна • Одна-одинешенька • Как Уилл Смит в «Я Легенда» • Пока не встретил женщину, из-за которой умер

Slide 123

Slide 123 text

Front controller

Slide 124

Slide 124 text

Front controller • index.php • + настройка сервера (например, .htaccess) • код, ответственный за загрузку зависимостей, обработку запроса, отправку ответа, весь он в одном месте • способствует модульности

Slide 125

Slide 125 text

MVC • во всех фреймворках страны • т.е. во всех современных фреймворках на самом деле

Slide 126

Slide 126 text

MVC • Model • View • Controller

Slide 127

Slide 127 text

MVC • Model — данные и обработка • View — шаблоны (html, xml, markup...) и никакой логики • Controller — обработка запроса, отправка данных из модели во вьюшку

Slide 128

Slide 128 text

MVC

Slide 129

Slide 129 text

MVC

Slide 130

Slide 130 text

Задание. Переделайте ваше CRUD приложение с использованием объектов и паттернов. ! Код вне объектов может быть только в index.php. Html должен быть в отдельных файлах. Логики там содержаться не должно, максимум вывод переменных, циклы для списков и if необходимые для определения логики вывода. ! Не бойтесь ошибиться. Не попробовав, вы никогда не поймете, как оно работает на самом деле.

Slide 131

Slide 131 text

Задание. Переделайте ваше CRUD приложение с использованием объектов и паттернов. ! Код вне объектов может быть только в index.php. Html должен быть в отдельных файлах. Логики там содержаться не должно. ! Не бойтесь ошибиться. Не попробовав, вы никогда не поймете, как оно.