27
Модульная структура PHP-приложений Interlabs 25 февраля 2013 1 / 27

Модульная структура PHP-приложений

  • View
    1.885

  • Download
    5

Embed Size (px)

DESCRIPTION

Общее введение в пространства именв PHP.

Citation preview

Page 1: Модульная структура PHP-приложений

Модульная структураPHP-приложений

Interlabs

25 февраля 2013

1 / 27

Page 2: Модульная структура PHP-приложений

В чем проблема

PHP < 5.3: NIH-синдром

Каждый фреймворк — вещь в себе, малая доля использованиястороннего кода.

Необходимо стандартное решение:

• отсутствие конфликтов имен;• удобная установка и загрузка;• автоматическое управление зависимостями.

2 / 27

Page 3: Модульная структура PHP-приложений

История вопроса, до 5.3

Практически полное отсутствие стандартов

• каждая библиотека использует собственную структуруимен;

• единственный стандарт — PEAR, там все плохо.• нет поддержки пространств имен на уровне языка;

Каждый выкручивается как может.

3 / 27

Page 4: Модульная структура PHP-приложений

Пространства имен до 5.3

• сделать вид что проблемы нет — неизбежные конфликты.• или использовать префиксы в именах классов:

Zend_Db_TableZend_Controller_RequestZend_Controller_Plugin_PluginInterface

Zend — vendor, DB, Controller, Plugin — вложенные модули.

Конфликты минимизированы, но неудобно.

4 / 27

Page 5: Модульная структура PHP-приложений

Структура файлов до 5.3

Стандарты отсутствуют.

Два основных варианта:

• стиль Java: каждый класс в отдельном файле, процедурныйкод — как придется

• стиль Perl/Python/Ruby: файл — модуль, состоящий изнабора классов и процедурного кода.

Как правило собственный загрузчик кода, явная подгрузкамодулей.

5 / 27

Page 6: Модульная структура PHP-приложений

История вопроса, после 5.3

• поддержка пространств имен на уровне языка;• начало процесса стандартизации;• PEAR не нужен;• появление нормально реализованных средств управлениямодулями;

• постепенный переход ключевых библиотек и приложенийна новую систему.

6 / 27

Page 7: Модульная структура PHP-приложений

Пространства имен в PHP

namespace Interlabs\DBI;

use Interlabs\Common\Exception;use Interlabs\Common\Object as BaseObject;

class Connection extends BaseObject;{

...

throw new Exception\BadPropertyException(’...’);}

namespace устанавливает текущее, use — импортирует илиопределяет псевдоним.

7 / 27

Page 8: Модульная структура PHP-приложений

Пространства имен: особенности

• namespace — первое PHP-выражение в файле;• один файл может содержать несколько пространств имен(но так не принято);

• класс относится к пространству имен, в котором онопределен;

• при определении класса указывать пространство в именинельзя;

• функции тоже можно включать в пространства имен, но вмеру бесполезно (см. нижe);

8 / 27

Page 9: Модульная структура PHP-приложений

Разрешение имен

Foo Unqualified Name просто имяFoo\Bar Qualified Name относительное имя\Foo\Bar Fully Qualified Name абсолютное имя

1 абсолютные имена сразу разрешаются2 внутри namespace пытаемся разрешить относительноимпортированных пространств имен (use)

3 если не получилось — разрешаем относительно текущегопространства

4 простые имена функций разрешаются относительноготекущего пространства, если не получается —относительно глобального.

9 / 27

Page 10: Модульная структура PHP-приложений

СтандартизацияДля того, чтобы пространства имен реально работали, нужнастандартизация.

Framework Interop Group http://php-fig.org

На данный момент — целых 4 стандарта1

• PSR-0 — автозагрузка и модульная структура;• PSR-1 — стандарт именования;• PSR-2 — стиль кодирования;• PSR-3 — стандартный интерфейс логирования.

1Для сравнения — в Python сотни стандартов, используемых иразвиваемых

10 / 27

Page 11: Модульная структура PHP-приложений

PSR–0• каждый класс — в отдельном файле c именем класса;• подгрузка — автоматически;

• стандартная структура пространства имен:\<Vendor Name\(<Namespace>\)*<Class Name>

• структура файлов соответствует имени, \ — подкаталоги:\Interlabs\DBI\Platform\MySQLsrc/Interlabs/DBI/Platform/MySQL.php

• режим совместимости со старым кодом:Framework_Module_Somethingsrc/Framework/Module/Something.php

• эталонный код загрузчика классов.

https://github.com/php-fig/fig-standards/blob/master/accepted/PSR–0.md 11 / 27

Page 12: Модульная структура PHP-приложений

PSR–0: выводы и слабые места

1 лучше безобразно, но единообразно;2 отсутствует концепция модуля как таковая, базоваяединица — класс;

3 функции внутри пространств имени малополезны, так какавтозагрузка только для классов;

4 отсутствует стандартный API для обработки событий,например, события загрузки класса.

5 отсутствует стандарт на Vendor prefix.

Стандарт принят, нужно ему следовать.

12 / 27

Page 13: Модульная структура PHP-приложений

Autoloader• автоматическая подгрузка классов и интерфейсов;• реализовано в версии 5, в 5.3 доведено до ума;• реализуется путем определения специальной глобальнойфункции __autoload();

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

function autoload($className){

$className = ltrim($className, ’\\’);$fileName = ’’;$namespace = ’’;if ($lastNsPos = strrpos($className, ’\\’)) {

$namespace = substr($className, 0, $lastNsPos);$className = substr($className, $lastNsPos + 1);$fileName = str_replace(’\\’, DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR;

}$fileName .= str_replace(’_’, DIRECTORY_SEPARATOR, $className) . ’.php’;

require $fileName;}

13 / 27

Page 14: Модульная структура PHP-приложений

Рекомендуемая структураприложения

• основная единица кода — класс;• каждый класс определен в некотором пространстве имен;• каждый класс в отдельном файле, путь к файлусоответствует пространству имен;

• пространства имен образуют иерархию;• корень иерархии — vendor prefix;• все подгружается автоматически, явные include и requireдля загрузки кода не используются;

• если нужен процедурный интерфейс — класс состатическими методами;

• константы — тоже в классах.

14 / 27

Page 15: Модульная структура PHP-приложений

Кеширование кода классов

• большое количество небольших файлов с кодом классов• большое количество обращений к файловой системе закодом класса;

• существенные накладные расходы на интерпретацию.

Кеширование кода обязательно!

APC, eAccelerator, Zend Accelerator, . . .

15 / 27

Page 16: Модульная структура PHP-приложений

Использование внешнего кода иуправление зависимостями

Нужно управлять сторонним кодом, PEAR не предлагать.

Composer

http://getcomposer.org/

• простая установка внешних библиотек;• отслеживание версий;• отслеживание зависимостей;• простое обновление до свежих версий;• встроенный autoloader.

16 / 27

Page 17: Модульная структура PHP-приложений

composer: установка$ curl -sS https://getcomposer.org/installer | php$ vim /path/to/project/composer.json--------------- composer.json --------------------{

"require": {"php": ">=5.3.0","monolog/monolog": "1.0.*"

},"autoload": {

"psr-0": {"Interlabs": "src/"

}}

}--------------------------------------------------$ php composer.phar install

17 / 27

Page 18: Модульная структура PHP-приложений

composer: результат

src/ — создаем каталог для нашего кода;vendor/ — стандартный каталог для внешних библиотек;

autoload.php — код первоначальной загрузки.composer/ — код загрузчика классов... — файлы внешних библиотек

В файле запуска приложения остается сказать:

require ’vendor/autoload.php’;

18 / 27

Page 19: Модульная структура PHP-приложений

Добавление и обновлениеДобавление: прописываем в composer.json и вызываем

$ php composer.phar install

Для обновления библиотек до последних версий вызываем

$ php composer phar update

Версии пакетов: точная версия 1.0.2, диапазон >=1.0,<2.0,маска 1.0.*, значимый релиз ∼1.2.

Используемые версии фиксируются в файле composer.lock.19 / 27

Page 20: Модульная структура PHP-приложений

Откуда берутся пакеты

Пакеты берутся из репозиториев, центральный репозиторий:

Packagist

http://packagist.org

• собственные репозитории (Satis);• репозитории систем контроля версий (git, hg, SVN);• PEAR.

20 / 27

Page 21: Модульная структура PHP-приложений

Установка из git-репозитория

Для установки пакета можно использовать любойgit-репозиторий:

"repositories": [{

"type": "git","url": "http://git.example.com/my/project","reference": "master"

}]

21 / 27

Page 22: Модульная структура PHP-приложений

Legacy-кодДля старых библиотек описание пакета можно включатьнепосредственно в composer.json проекта:

"repositories": [{

"type": "package","package": {

"name": "my/project","source": {

"type": "git","url": "[email protected]:repo.git"

}]

}

22 / 27

Page 23: Модульная структура PHP-приложений

Метаданные проектаcomposer.json — описывает не только зависимости, но и сампроект.

{ "name": "company/component","description": "some component","type": "library","homepage": "http://www.example.com","version": "0.7.1","authors": [

...]

}

Знакомство с проектом начинаем с composer.json.

23 / 27

Page 24: Модульная структура PHP-приложений

Пример: silex{ "name": "silex/silex",

"description": "The PHP micro-framework based on the Symfony2 Components","keywords": ["microframework"],"homepage": "http://silex.sensiolabs.org","license": "MIT","authors": [

{ "name": "Fabien Potencier", "email": "[email protected]" },{ "name": "Igor Wiedler", "email": "[email protected]" }

],"require": {

"php": ">=5.3.3","pimple/pimple": "1.*","symfony/event-dispatcher": ">=2.1,<2.3-dev","symfony/http-foundation": ">=2.1,<2.3-dev","symfony/http-kernel": ">=2.1,<2.3-dev","symfony/routing": ">=2.1,<2.3-dev" },

"require-dev": {"symfony/security": ">=2.1,<2.3-dev",

"symfony/config": ">=2.1,<2.3-dev","symfony/validator": ">=2.1,<2.3-dev","twig/twig": ">=1.8.0,<2.0-dev","doctrine/dbal": ">=2.2.0,<2.4.0-dev","swiftmailer/swiftmailer": "4.2.*" },

"suggest": {"symfony/browser-kit": ">=2.1,<2.3-dev","symfony/css-selector": ">=2.1,<2.3-dev","symfony/dom-crawler": ">=2.1,<2.3-dev" },

"autoload": {"psr-0": { "Silex": "src/" }

},}

24 / 27

Page 25: Модульная структура PHP-приложений

Обработка событий

В процессе установки (обновления) пакета можно запускатьобработчики событий:

pre-install-cmd post-install-cmd pre-update-cmdpost-update-cmd pre-package-install post-package-installpre-package-update post-package-update pre-package-uninstallpost-package-uninstall post-autoload-dump

• вызовы методов классов, Composer\Script\Event вкачестве параметра;

• запуск внешних программ;

25 / 27

Page 26: Модульная структура PHP-приложений

Описание обработчиков{ "scripts": {

"post-install-cmd": ["Vendor\Class::updateCache","phpunit -c app/"

]}

use Composer\Script\Event;class Handler{

public static function updateCache(Event $event) {{//...}

}

26 / 27

Page 27: Модульная структура PHP-приложений

Что читать

• http://php.net/manual/ru/language.namespaces.php —пространства имен;

• http://php.net/manual/ru/language.oop5.autoload.php - автозагрузка;

• http://getcomposer.org/doc/ — работа с Composer;• http://packagist.org — центральный репозиторийпакетов Composer;

• http://getcomposer.org/doc/articles/handling-private-packages-with-satis.md —организация собственных репозиториев.

27 / 27