420 likes | 446 Views
Общая архитектура Y ii 2. YiiSoft. Климов П.В. Область применения. Построение функциональности не имеющей аналогов Новая интерпретация уже существующих бизнес процессов Стык или объединение различных областей и процессов Системы с повышенными требованиями к качеству. PHP 5.4 ООП
E N D
Общая архитектураYii2 YiiSoft Климов П.В.
Область применения • Построение функциональности не имеющей аналогов • Новая интерпретация уже существующих бизнес процессов • Стык или объединение различных областей и процессов • Системы с повышенными требованиями к качеству
PHP 5.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 Управление зависимостями
Автозагрузка классов // 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’;
Магия в PHP classObject { public$publicProperty; private$_privateProperty; public function setPrivateProperty($value) { $this->_privateProperty = $value; } public function getPrivateProperty() { return$this->_privateProperty; } }
classObject { public function __get($propertyName) { $methodName = 'get‘.$propertyName; if (method_exists($this, $methodName)) { returncall_user_func([$this, $methodName]); } else { throw new Exception("Missing property {$propertyName}'!"); } } public function __set($propertyName, $value) { $methodName = 'set‘.$propertyName; if (method_exists($this, $methodName)) { returncall_user_func([$this, $methodName], $value); } else { throw new Exception("Missing property {$propertyName}'!"); } }
$object = newObject(); $object->publicProperty = 'Public value'; echo ($object->publicProperty); $object->privateProperty = 'Private value'; echo ($object->privateProperty);
Порождение объектов function createObject(array$config) { $className = $config['class']; if (empty($className)) { throw new Exception(‘Missing parameter "class"!'); } unset($config['class']); $object = new$className(); foreach ($configas$name=>$value) { $object->$name = $value;// Конфигурация } return$object; }
Задание любого объекта через массив: $config = [ 'class‘ => ‘yii\web\UrlManager', 'enablePrettyUrl‘ => true, 'showScriptName‘ => false, 'rules‘ => [ '/‘ => 'site/index', '<controller:\w+>/<id:\d+>*‘ => '<controller>/view', ], ]; $object = Yii::createObject($config);
“Request component by id” di\ServiceLocator Client “Create and store by id” $definitions $components 1 * base\Component get($id) “Get class instance” “instantiate” di\Container $definitions $dependencies $singletons ComponentA … set($class, $params) get($class) Dependency Injection (DI)
di\ServiceLocator base\Module base\Application
$config = [ 'name‘ => 'My Web Application', … 'components‘ => [ 'user‘ => [ ‘enableAutoLogin‘ => true, ], … ], ]; (new yii\web\Application($config))->run(); … $application = Yii::$app; $user = Yii::$app->get(‘user’);
1 1 * Component * Application “create” * 1 * C * Controller Module “render” “register” 1 V * AssetBundle Widget View * “render part” * M * Model MVC в Yii2
:Application web server ‘run’ :Request :UrlManager ‘handle’ ‘resolve’ ‘data’ ‘route’ :Controller ‘run action’ ‘response’ :Response ‘compose output’ ‘output’ ‘output’ Маршрутизация web запроса
Построение отображения class View extends Component { public function renderFile($viewFile, $data = null) { require($viewFile); } } <html> <body> <h1>Data<?phpecho$data; ?></h1> <hr/> <?php$this->render(‘main_menu.php’); ?> </body> </html>
“determine view path” 1 1 ViewContextInterface View “by file extension” render() 1 * ViewRenderer “Define specific renderer” smarty\ViewRenderer twig\ViewRenderer handles *.tpl handles *.twig Структура отображения
Виджет (Widget) <?phpecho GridView::widget([ 'dataProvider' => $dataProvider, 'options' => ['class' => 'detail-grid-view table-responsive'], 'filterModel' => $searchModel, 'columns' => [ 'time', 'level', 'category', 'message', ], ]); ?>
Client Shortcut static method "register()" View $assetBundles “Depends on” registerAssetBundle() * AssetBundle “Get Asset Bundle” “Create, override and register” $css $js $depends AssetManager 1 $bundles getBundle() “Compose actual files” AssetConverter JqueryAsset … convert() Asset Management
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', ]; }
Model “Create and run” setAttributes() getAttributes() validate() 1 * Validator “Define specific validator” EmailValidator RangeValidator … Модель
1 1 Client PDO PDO Driver PDO MySQL PDO PostgreSQL … MySQL PostgreSQL Доступ к базе данных через PDO
1 1 1 “Types, keys, etc.” PDO Connection 1 1 “Syntax” “Create” 1 1 * “Use” “Use” QueryBuilder Command Schema 1 * * 1 mysql\QueryBuilder … mysql\Schema … Абстракция базы данных
“Create and execute” 1 1 * Query Command * “Create” * “Build” 1 QueryBuilder BatchQueryResult 1 Iterator 1 DataReader Countable Select Query Shortcut
BaseActiveRecord ActiveRelationTrait save() delete() Shortcut static method "find()" * 1 ActiveRecord ActiveQuery “Instantiate by query result” 1 “Database access” * Command Query Active Record
// Выборка записей: $allUsers = User::find()->all(); // Вставка новой записи: $newUser = new User(); $newUser->name = ‘new user’; $newUser->save(); // Обновление существующей записи: $existingUser = User::find()->where([‘name’=>‘testuser’])->one(); $existingUser->email = ‘newemail@domain.com’; $existingUser->save(); // Отложенная загрузка отношения: $bio = $existingUser->profile->bio; // Жадная загрузка отношения: $allUsers = User::find()->with(‘profile’)->all();
:ActiveQuery Client ‘create from query result’ ‘find with "profile"’ :User ‘get "profile" info’ ‘relation info’ :ActiveQuery ‘find where userId in set’ ‘profile references’ :Profile ‘bind "profile"’ ‘result’ «Жадная» загрузка отношений
NOSQL Active Record • MongoDB • Redis • ElasticSearch • Sphinx
BaseActiveRecord db\ActiveRecord mongodb\ActiveRecord “Has relation” User Profile Cross-DBMS отношения
1 * “Raise” Event Component eventHandlers sender data trigger() 1 1 PHP Callback “Handle” * Handler “List of PHP callbacks” * События (Events)в Yii
Event Handler :ActiveRecord Client ‘save’ ‘raise “beforeInsert”’ :Event * ‘handle “beforeInsert”’ ‘get event info’ ‘sender’ ‘adjust event sender’ ‘saving result’ ‘actual data saving’ Обработка события
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’
ActiveRecord ArPosition ArFile Save custom records display order Bind physical file with the db record ArPositionFile Position + File Проблема множественного наследования
1 * Behavior Component owner behaviors getOwner() events() __call() attachBehavior() 1 1 * * Event “Handle” “Raise” data Поведение (Behavior)
Расширение интерфейса 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}”); } … }
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’
Обработка событий class ExampleBehavior extends Behavior { public function events() { return [ ‘beforeInsert’ => ‘handleBeforeInsert’, ‘afterInsert’ => ‘handleAfterInsert’ ]; } public function handleBeforeSave(Event $event) { // Обработка события «beforeInsert» } … }
yii\mail 1 * MailerInterface MessageInterface “Send” Shortcut method "send()" BaseMailer BaseMessage yii\swiftmailer Mailer Message Отправка электронной почты
1 * Collection ClientInterface “Configure and create” BaseClient OAuth1 OAuth2 OpenId BaseOAuth Twitter Yandex Facebook Расширение«AuthClient»
Дополнительные расширения • Gii • Debug • Boostrap • JUI • Codeception • Imagine • ApiDoc
ZFort приглашает на работу: Senior Magento Developer / TechLead Middle PHP CMS Developer Middle ASP.NET Developer Middle FrontEnd Developer Senior Project Manager Yii2 • NOSQL и Active Record • Cross-DBMS отношения • События • Поведения • Стандартные расширения • Composer + Bower • Компонентная структураи DI • MVC • Управление «assets» • PDO и Active Record