Общая архитектура Yii2
Управление зависимостями
Автозагрузка классов
Магия в PHP
Порождение объектов
Задание любого объекта через массив:
Dependency Injection (DI)
MVC в Yii2
Маршрутизация web запроса
Построение отображения
Структура отображения
Виджет (Widget)
Asset Management
Модель
Доступ к базе данных через PDO
Абстракция базы данных
Select Query Shortcut
Active Record
«Жадная» загрузка отношений
NOSQL Active Record
Cross-DBMS отношения
События (Events) в Yii
Обработка события
Проблема множественного наследования
Поведение (Behavior)
Расширение интерфейса
Обработка событий
Отправка электронной почты
Расширение «AuthClient»
Дополнительные расширения
Yii2
1.01M
Categories: programmingprogramming softwaresoftware

Общая архитектура Yii2

1. Общая архитектура Yii2

Климов П.В.
YiiSoft

2.

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

3.

Основные характеристики
PHP 5.4
ООП
Модульность
Простота
Высокое быстродействие

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

Composer
Manages PHP packages
"request non-PHP package"
composer-asset-plugin
Substitute Bower client,
compatible with composer
"use Bower protocol as client"
Bower
Manages CSS and
JavaScript packages

5. Автозагрузка классов

// Autoload via Composer by PSR-4 :
$model = new yii\base\Model();
// Yii built-in autoload by PSR via alias:
Yii::setAlias(‘@app’, ‘/var/www/myproject’);
$someObj = new app\models\Customer();
// include ‘/var/www/myproject/models/Customer.php’;

6. Магия в PHP

class Object
{
public $publicProperty;
private $_privateProperty;
public function setPrivateProperty($value)
{
$this->_privateProperty = $value;
}
public function getPrivateProperty()
{
return $this->_privateProperty;
}
}

7.

class Object
{
public function __get($propertyName)
{
$methodName = 'get‘ . $propertyName;
if (method_exists($this, $methodName)) {
return call_user_func([$this, $methodName]);
} else {
throw new Exception("Missing property {$propertyName}'!");
}
}
public function __set($propertyName, $value)
{
$methodName = 'set‘ . $propertyName;
if (method_exists($this, $methodName)) {
return call_user_func([$this, $methodName], $value);
} else {
throw new Exception("Missing property {$propertyName}'!");
}
}

8.

$object = new Object();
$object ->publicProperty = 'Public value';
echo ($object->publicProperty);
$object->privateProperty = 'Private value';
echo ($object->privateProperty);

9. Порождение объектов

function createObject(array $config)
{
$className = $config['class'];
if (empty($className)) {
throw new Exception(‘Missing parameter "class"!');
}
unset($config['class']);
$object = new $className();
foreach ($config as $name=>$value) {
$object->$name = $value; // Конфигурация
}
return $object;
}

10. Задание любого объекта через массив:

$config = [
'class‘ => ‘yii\web\UrlManager',
'enablePrettyUrl‘ => true,
'showScriptName‘ => false,
'rules‘ => [
'/‘ => 'site/index',
'<controller:\w+>/<id:\d+>*‘ => '<controller>/view',
],
];
$object = Yii::createObject($config);

11. Dependency Injection (DI)

di\ServiceLocator
$definitions
$components
get($id)
“Get class
instance”
“Request component
by id”
1
Client
“Create and
store by id”
*
base\Component
“instantiate”
di\Container
$definitions
$dependencies
$singletons
set($class, $params)
get($class)
ComponentA

12.

di\ServiceLocator
base\Module
base\Application

13.

$config = [
'name‘ => 'My Web Application',

'components‘ => [
'user‘ => [
‘enableAutoLogin‘ => true,
],

],
];
(new yii\web\Application($config))->run();

$application = Yii::$app;
$user = Yii::$app->get(‘user’);

14. MVC в Yii2

1
1
Application
*
1
Module
Widget
*
*
Component
*
“create”
View
*
Model
C
*
Controller
“render” 1
“render
part”
*
“register”
*
*
AssetBundle
V
M

15. Маршрутизация web запроса

:Application
web server
‘run’
:Request
:UrlManager
‘handle’
‘resolve’
‘data’
‘route’
:Controller
‘run action’
‘response’
‘compose output’
‘output’
‘output’
:Response

16. Построение отображения

class View extends Component
{
public function renderFile($viewFile, $data = null)
{
require($viewFile);
}
}
<html>
<body>
<h1>Data <?php echo $data; ?></h1>
<hr />
<?php $this->render(‘main_menu.php’); ?>
</body>
</html>

17. Структура отображения

“determine view path”
View
render()
1
1
ViewContextInterface
“by file extension”
1
*
ViewRenderer
“Define specific renderer”
smarty\ViewRenderer
handles *.tpl
twig\ViewRenderer
handles *.twig

18. Виджет (Widget)

<?php echo GridView::widget([
'dataProvider' => $dataProvider,
'options' => ['class' => 'detail-grid-view table-responsive'],
'filterModel' => $searchModel,
'columns' => [
'time',
'level',
'category',
'message',
],
]); ?>

19. Asset Management

Client
Shortcut static
method
"register()"
View
“Depends on”
$assetBundles
registerAssetBundle()
“Get Asset
Bundle”
AssetManager
$bundles
1
“Create,
override
and
register”
*
AssetBundle
$css
$js
$depends
getBundle()
“Compose
actual files”
AssetConverter
convert()
JqueryAsset

20.

class YiiAsset extends AssetBundle
{
public $sourcePath = '@yii/assets';
public $js = [
'yii.js',
];
public $depends = [
'yii\web\JqueryAsset',
];
}
class JqueryAsset extends AssetBundle
{
public $sourcePath = '@bower/jquery/dist';
public $js = [
'jquery.js',
];
}

21. Модель

Model
“Create and run”
setAttributes()
getAttributes()
validate()
1
*
Validator
“Define specific validator”
EmailValidator
RangeValidator

22. Доступ к базе данных через PDO

Client
PDO
1
1
PDO Driver
PDO MySQL
PDO PostgreSQL
MySQL
PostgreSQL

23. Абстракция базы данных

PDO
1
1
“Syntax”
1
1
QueryBuilder
“Use”
1
*
mysql\QueryBuilder
Connection
1
*
“Types, keys, etc.”
“Create”
Command

1
1
“Use”
*
1
Schema
mysql\Schema

24. Select Query Shortcut

1
Query
“Create”
*
BatchQueryResult
“Create and
execute”
1
*
*
“Build”
Command
1 QueryBuilder
1
Iterator
1
DataReader
Countable

25. Active Record

BaseActiveRecord
save()
delete()
Shortcut static
method "find()"
ActiveRecord
1
*
ActiveRelationTrait
*
1
“Instantiate by
query result”
ActiveQuery
“Database
access”
Command
Query

26.

// Выборка записей:
$allUsers = User::find()->all();
// Вставка новой записи:
$newUser = new User();
$newUser->name = ‘new user’;
$newUser->save();
// Обновление существующей записи:
$existingUser = User::find()->where([‘name’=>‘testuser’])->one();
$existingUser->email = ‘[email protected]’;
$existingUser->save();
// Отложенная загрузка отношения:
$bio = $existingUser->profile->bio;
// Жадная загрузка отношения:
$allUsers = User::find()->with(‘profile’)->all();

27. «Жадная» загрузка отношений

:ActiveQuery
Client
‘find with
"profile"’
‘create from
query result’
:User
‘get "profile"
info’
‘relation info’
:ActiveQuery
‘find where userId in set’
‘profile references’
‘bind "profile"’
‘result’
:Profile

28. NOSQL Active Record


MongoDB
Redis
ElasticSearch
Sphinx

29. Cross-DBMS отношения

BaseActiveRecord
db\ActiveRecord
mongodb\ActiveRecord
“Has relation”
User
Profile

30. События (Events) в Yii

Component
1
“Raise”
eventHandlers
Event
sender
data
trigger()
1
*
1
PHP
Callback
“Handle”
*
Handler
“List of PHP callbacks”
*

31. Обработка события

Event Handler
:ActiveRecord
Client
‘save’
‘raise
“beforeInsert”’
:Event
*
‘handle “beforeInsert”’
‘get event
info’
‘sender’
‘adjust event sender’
‘saving
result’
‘actual data
saving’

32.

function handleBeforeInsert(Event $event)
{
$sender = $event->sender;
// Изменяем состояние отправителя события:
$sender->create_date = date('Y-m-d', strtotime('NOW'));
}
$user = new User();
// Назначаем обработчик события:
$user->on(‘beforeInsert’, ‘handleBeforeInsert’);
$user->name = ‘test name’;
$user->save();
echo $user->create_date; // Вывод: ‘2015-03-21’

33. Проблема множественного наследования

ActiveRecord
ArPosition
ArFile
Save custom records
display order
Bind physical file with
the db record
ArPositionFile
Position + File

34. Поведение (Behavior)

1
*
Component
Behavior
behaviors
owner
__call()
attachBehavior()
getOwner()
events()
1
1
“Raise”
*
Event
data
*
“Handle”

35. Расширение интерфейса

class Component
{
private $_behaviors = [ ];
public function __call($method, $arguments)
{
// Ищем недостающий метод среди поведений:
foreach ($this->_behaviors as $behavior) {
if (method_exists($behavior, $method)) {
return $behavior->$method($arguments);
}
}
throw new Exception(“Missing method {$method}”);
}

}

36.

class ArBehaviorExample extends Behavior
{
public function behaviorMethod()
{
$this->owner->create_date = date('Y-m-d', strtotime('NOW'));
}
}
$user = new User();
// Добавляем поведение:
$behavior = new ArBehaviorExample();
$user->attachBehavior($behavior);
// Вызываем метод поведения:
$user->behaviorMethod();
echo $user->create_date; // Вывод: ‘2015-03-21’

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

class ExampleBehavior extends Behavior
{
public function events()
{
return [
‘beforeInsert’ => ‘handleBeforeInsert’,
‘afterInsert’ => ‘handleAfterInsert’
];
}
public function handleBeforeSave(Event $event)
{
// Обработка события «beforeInsert»
}

}

38. Отправка электронной почты

yii\mail
MailerInterface
1
“Send”
*
MessageInterface
Shortcut method "send()"
BaseMailer
BaseMessage
yii\swiftmailer
Mailer
Message

39. Расширение «AuthClient»

Collection
1
*
ClientInterface
“Configure and
create”
BaseClient
OAuth1
Twitter
BaseOAuth
OAuth2
Facebook
OpenId
Yandex

40. Дополнительные расширения


Gii
Debug
Boostrap
JUI
Codeception
Imagine
ApiDoc

41. Yii2


Composer + Bower
Компонентная структура и DI
MVC
Управление «assets»
PDO и Active Record
NOSQL и Active Record
Cross-DBMS отношения
События
Поведения
Стандартные расширения
ZFort приглашает на работу:
Senior Magento
Developer /
TechLead
Middle
ASP.NET
Developer
Senior
Project
Manager
Middle PHP
CMS
Developer
Middle
FrontEnd
Developer
English     Русский Rules