Рассмотрим сравнительно сложные, и в то же время, часто возникающие, задачи, для которых ядро Yii не дает готового решения. Посмотрим как из отдельных моделей ActiveRecord собирать единые сущности, и как разбивать большие модели на составляющие. Разберем как правильно сохранять файлы и как сэкономить на обработчиках событий и поведениях
- Интернационализация сущностей в базе данных;
- Обработка “ролей” в реляционных базах данных;
- Работа с файлами;
- Вложенные модели;
- Trait вместо Behavior.
Продвинутое использование ActiveRecord в Yii2Paul Klimov
Запись лекции "Продвинутое использование ActiveRecord в Yii2" от 24.09.2016, проходившей в Киеве в "Projector"
http://prjctr.com.ua/events/yii2-conference.html
Продвинутое использование ActiveRecord в Yii2Paul Klimov
Запись лекции "Продвинутое использование ActiveRecord в Yii2" от 24.09.2016, проходившей в Киеве в "Projector"
http://prjctr.com.ua/events/yii2-conference.html
Industrial Programming Java - Lection Pack 01 - Building an application - Lav...Fedor Lavrentyev
Курс "Промышленное программирование на Java". Набор лекций 1. "Сборка и компоновка приложения".
Сборка проекта. Apache Maven. Компоновка и верхнеуровневый дизайн приложения. Depencency Injection. Spring Framework. Spring Boot. Обзор популярных утилитарных библиотек. Логгинг, slf4j, log4j.
МФТИ, 2014 год. Лектор - Лаврентьев Федор Сергеевич
Организация работы с API на Vue.js, Виталий КопачёвMail.ru Group
В процессе работы из проекта в проект я тащу свой «велосипед», постоянного его подтачиваю или модифицирую под конкретные нужды. Хотел бы рассказать о нем, его плюсах и минусах. Кроме этого, поговорим о том, какие «велосипеды» для работы с API существуют.
Курс "Промышленное программирование на Java". Набор лекций 3. "Реляционные базы данных".
Модель предметной области. Подключение к РСУБД из Java.
Spring JDBC.
МФТИ, 2014 год. Лектор - Лаврентьев Федор Сергеевич
1. Контроллеры в Django
2. Объекты HttpRequest и HttpResponse
3. Получение GET и POST параметров
4. Работа с HTTP заголовками в Django
5. Декораторы
6. Шаблонизация в Django
7. Наследование шаблонов
8. Context processors
With application and team growth such questions as keeping documentation up to date, sharing of the knowledge, communication between stakeholder and development team became more and more actual. BDD as methodology is aimed to minimize negative impact of those issues. Spock and Geb frameworks will help us to illustrate BDD implementation on specific example.
Industrial Programming Java - Lection Pack 01 - Building an application - Lav...Fedor Lavrentyev
Курс "Промышленное программирование на Java". Набор лекций 1. "Сборка и компоновка приложения".
Сборка проекта. Apache Maven. Компоновка и верхнеуровневый дизайн приложения. Depencency Injection. Spring Framework. Spring Boot. Обзор популярных утилитарных библиотек. Логгинг, slf4j, log4j.
МФТИ, 2014 год. Лектор - Лаврентьев Федор Сергеевич
Организация работы с API на Vue.js, Виталий КопачёвMail.ru Group
В процессе работы из проекта в проект я тащу свой «велосипед», постоянного его подтачиваю или модифицирую под конкретные нужды. Хотел бы рассказать о нем, его плюсах и минусах. Кроме этого, поговорим о том, какие «велосипеды» для работы с API существуют.
Курс "Промышленное программирование на Java". Набор лекций 3. "Реляционные базы данных".
Модель предметной области. Подключение к РСУБД из Java.
Spring JDBC.
МФТИ, 2014 год. Лектор - Лаврентьев Федор Сергеевич
1. Контроллеры в Django
2. Объекты HttpRequest и HttpResponse
3. Получение GET и POST параметров
4. Работа с HTTP заголовками в Django
5. Декораторы
6. Шаблонизация в Django
7. Наследование шаблонов
8. Context processors
With application and team growth such questions as keeping documentation up to date, sharing of the knowledge, communication between stakeholder and development team became more and more actual. BDD as methodology is aimed to minimize negative impact of those issues. Spock and Geb frameworks will help us to illustrate BDD implementation on specific example.
Кортунов Никита. Как ускорить разработку приложений или есть ли жизнь после P...AvitoTech
икита расскажет о возможностях backend as a service, ответит на вопрос есть ли жизнь после Parse, поделится опытом разработки BaaS Scorocode, особенностями архитектуры и кейсами применения, как можно ускорить разработку с помощью BaaS.
Вадим Дробинин. Защищаем себя и пользователей: руководство по безопасностиAvitoTech
Докладчик поднимет важную тему защиты пользовательских данных и непосредственно ресурсов приложений от внешних угроз, расскажет об основных проблемах, с которыми сталкиваются разработчики, обеспокоенные безопасностью своих приложений и покажет наиболее успешные способы защиты от атак на Swift
Андрей Юткин. Media Picker — to infinity and beyondAvitoTech
Paparazzo - https://github.com/avito-tech/Paparazzo
В своём докладе Андрей поделится опытом разработки собственной камеры и галереи в приложении Avito и расскажет про проблемы, с которыми столкнулся в процессе. Из доклада вы узнаете:
- как реализовать вывод изображения с камеры в нескольких view одновременно
- как оптимизировать работу с памятью при работе с картинками
- как абстрагироваться от источника картинки
- как обработать изображения с помощью фрэймворка ImageIO
- как абстрагироваться от UIKit в слое Presenter архитектуры VIPER
- как работать с изображениями из iCloud и про другие скользкие моменты фрэймворка Photos.
Доклад о разработке (а главное - оптимизации) программы на Perl под Raspberry PI.
Наглядно показывает, что в Perl есть немало возможностей, а также инструментов, которые позволяют делать программы быстрее и эффективнее - используя как преимущества самого языка, так и оптимизацию алгоритма программы.
Алексей Плеханов: 25 причин попробовать LaravelOleg Poludnenko
Доклад с PUG#1 https://www.facebook.com/events/1505404039679797/
Мой доклад посвящен популярному фреймворку Laravel.
Я рассказываю про 25 причин, по которым, я считаю, стоит попробовать этот фреймворк, особенно, если раньше Вы не были с ним знакомы. Описаны ORM Eloquent, роутинг в Laravel, работа с основными компонентами, такими как контроллеры, шаблонизатор, авторизация, пагинация, а также более сложные вещи, как Inverse of Control, фасады в Laravel, работа с очередями и консольными командами. Также в докладе освещены другие интересные фичи фреймворка!
PHP User Group Ukraine в социальных сетях:
https://www.facebook.com/pug.ukraine
https://vk.com/pug.ukraine
https://www.linkedin.com/groups/PHP-User-Group-Ukraine-6703717
5. class Item extends yiidbActiveRecord
{
public function behaviors()
{
return [
‘translations’ => [
'class' => VariationBehavior::class,
'variationsRelation' => 'translations',
'variationOptionReferenceAttribute' => 'languageId',
'optionModelClass' => Language::class,
]
];
}
public function getTranslations()
{
return $this->hasMany(ItemTranslation::class, [‘itemId' => 'id']);
}
}
Конфигурация «VariationBehavior»
6. $model = new Item();
// `getVariationModels()` возвращает список моделей-вариаций
$variations = $model->getVariationModels();
// их количество всегда равно количеству доступных опций:
var_dump(count($variations) == Language::find()->count()); // `true`
// валидация и сохранение производятся автоматически:
$post = Yii::$app->request->post();
if ($model->load($post)
&& Model::loadMultiple($model->getVariationModels(), $post)
&& $model->save())
{
return $this->redirect(['index']);
}
Управление вариаторами
7. class Item extends yiidbActiveRecord
{
public function behaviors()
{
return [
‘translations’ => [
// …
'defaultVariationRelation' => 'defaultTranslation',
'defaultVariationOptionReference' => function () {
return Yii::$app->language; // ID опции по умолчанию
},
'variationAttributeDefaultValueMap' => [
‘name' => ‘canonicalName‘ // fallback для атрибутов вариатора
],
]
];
}
public function getDefaultTranslation()
{
return $this->hasDefaultVariationRelation(); // `has many` -> `has one`
}
}
Вариация «по умолчанию»
8. class VariationBehavior extends yiibaseBehavior
{
public function __get($name)
{
try {
return parent::__get($name);
} catch (yiibaseUnknownPropertyException $e) {
return $this->getDefaultVariationModel()->{$name};
}
}
public function __set($name, $value) {…}
public function canGetProperty($name, $checkVars = true) {…}
public function canSetProperty($name, $checkVars = true) {…}
}
Добавление виртуальных свойств
«хозяину» поведения
9. $model = Item::find()->one();
echo $model->name; // вернет `$model->defaultTranslation->name`
// а если `defaultTranslation` не найдено, то `$model->canonicalName`
// Задание нового значения:
$model->name = ‘New translation name’;
// «Жадная» загрузка:
$models = Item::find()->with(‘defaultTranslation’)->all();
foreach ($models as $model) {
echo $model->name;
}
Прямой доступ к атрибутам вариатора
10. Сущности с общими атрибутами
Преподаватель Студент
- Ученая
степень
- Зарплата
- ФИО
- Паспорт
- Адрес
- Телефон
- Учебная
группа
- Стипендия
11. Роли в реляционной базе данных
Person
id
name
address
phone Student
personId
studyGroupId
scolarship
Instructor
personId
rankId
salary
12. Роли в реляционной базе данных
Person
1
id
name
address
phone Student
personId
studyGroupId
scolarship
Can be
1
Instructor
personId
rankId
salary
Can be
1 1
21. $bucket = Yii::$app->fileStorage->getBucket('tempFiles');
// создать файл с заданным содержимым:
$bucket->saveFileContent('foo.txt', 'Foo content');
// удалить файл:
$bucket->deleteFile('foo.txt');
// скопировать файл в хранилище:
$bucket->copyFileIn('/path/to/source/file.txt', 'file.txt');
// скопировать файл из хранилища:
$bucket->copyFileOut('file.txt', '/path/to/destination/file.txt');
var_dump($bucket->fileExists('file.txt')); // выводит `true`
echo $bucket->getFileUrl('file.txt'); // выводит:
// http://domain.com/files/f/i/file.txt'
Операции с файлами
22. Файловые потоки
// Открыть локальный файл:
$resource = fopen(‘/path/to/file.txt’, ‘r’);
// Открыть удаленный файл по протоколу HTTP:
// файл загружается по протоколу HTTP и доступен как локальный:
$resource = fopen(‘http://example.com/file.txt’, ‘r’);
// Дескриптор потока в общем виде:
$resource = fopen(‘{PROTOCOL}://{PATH}[?{QUERY}]’, ‘r’);
23. Потоковая Обвертка
class StreamWrapper
{
public function stream_open($path, $mode, $options, &$openedPath) {}
public function stream_close() {}
public function stream_eof() {}
public function stream_read($count) {}
public function stream_write($data) {}
}
stream_wrapper_register(‘foo’, StreamWrapper::class, STREAM_IS_URL);
26. Максимальное количество файлов в
одном каталоге
• Для «старых» файловых систем (FAT) –
65 000
• Для современных (NTFS) теоретическое
– 4 294 967 295
• Практическое (без существенной потери
производительности) – 50 000..100 000
35. class User extends ActiveRecord implements ContainerInterface
{
use ContainerTrait;
public function embedAddressModel()
{
return $this->mapEmbedded(‘address', Address::class);
}
public function embedCommentModels()
{
return $this->mapEmbeddedList('comments', Comment::class);
}
}
Объявление вложенных объектов
38. class User extends yiidbActiveRecord
{
public function behaviors()
{
return [
‘timestamp’ => [
'class' => TimestampBehavior::class,
// обрабатывает только 2 собыития:
// - `beforeInsert`
// - `beforeUpdate`
]
];
}
}
Конфигурация «TimestampBehavior»
39. $user = new User(); // срабатывает событие `init`
// поведения проинициализированы!
$models = User::find()->all(); // срабатывает событие `afterFind`
// поведения проинициализированы!
unset($models); // объекты НЕ разрушены!
gc_collect_cycles(); // принудительная сборка мусора
// только теперь объекты разрушены
Инициализация и разрушение
поведений
40. class User extends yiidbActiveRecord
{
public function init()
{
// «прыжок» через родителя
// убираем событие «init»
yiibaseModel::init();
}
public function afterFind()
{
// нет вызова родительской реализации
// убираем событие «afterFind»
}
}
Устранение «лишних» событий
41. $user = new User(); // нет события `init`
// поведения НЕ проинициализированы!
$models = User::find()->all(); // нет события `afterFind`
// поведения НЕ проинициализированы!
unset($models); // объекты разрушены!
echo gc_collect_cycles(); // выводит `0`
$user->save(); // событие `beforeInsert`
// поведения проинициализированы!
Отложенная инициализация
поведений
43. class User extends yiidbActiveRecord
{
use BehaviorTrait;
use TimestampTrait;
}
trait TimestampTrait
{
// Имя обработчика: «{событие}Handler{суффикс}»
// Обработка события «beforeInsert»
public function beforeInsertHandlerTimestamp($event)
{
$this->createdAt = time();
}
}
Использование «BehaviorTrait»
44. Примеры решения типичных задач за
рамками ядра Yii2
• Интернационализация в БД
• Роли в реляционных БД
• Абстракция файлового хранилища
• Связывание файлов с записями в БД
• Вложенные модели
• Trait вместо Behavior
http://www.yiiframework.com/
https://github.com/yii2tech