Хроники Yii3
623 subscribers
43 photos
1.7K links
Описание процесса разработки фреймворка из первых рук 😎

Обсуждение:
https://yangx.top/yii3ru

Сводка по всем пакетам:
https://www.yiiframework.com/status/3.0

Поддержать разработчиков:
https://opencollective.com/yiisoft
加入频道
⚡️ #yiisoftWidget

В пакете Yii Widget улучшен пример использования в виджете Breadcrumbs + сделаны небольшие изменения в psalm-аннотациях (PR).
⚡️ #yiisoftView

В документации Yii View дополнен блок про использование методов hasCommonParameter() и getCommonParameter() + сделаны небольшие изменения в psalm-аннотациях (PR).
⚡️ #yiisoftDocs

Исправлены битые ссылки в документации в разделе "Running Applications" (PR).

Спасибо Andrew за пул-реквест 👍
⚡️ #yiisoftConfig

В пакете Yii Config увеличена минимальная требуемая версия Composer до 2.0 (PR).
⚡️ #yiisoftConfig

Подчистили служебные файлы в Yii Config (PR):

- улучшены конфигурации GitHub Workflow;
- улучшена конфигурация psalm;
- исключены все служебные файлы при создании архива репозитория;
- мелкие улучшения в других служебных файлах.
⚡️ #yiisoftMutex #yiisoftMutexFile #yiisoftMutexPdoMysql #yiisoftMutexPdoPgsql #yiisoftMutexPdoOracle

Полностью переосмыслен и переписан код пакета Yii Mutex (PR, PR, PR), обеспечивающий взаимное исключение исполнения критических участков кода в «состоянии гонки».

—————

Основные интерфейсы и классы

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

MutexInterface — интерфейс мьютекс-объекта с методами acquire() (включает блокировку) и release() (отключает блокировку).

MutexFactoryInterface — интерфейс фабрики, создающей экземпляр мьютекс-объекта с двумя методами:

- create() — создание мьютекс-объекта;

- createAndAcquire() — создание мьютекс-объекта и включение блокировки. При неудачном включении блокировки будет брошено исключение.

MutexFactory — абстрактный класс фабрики, реализующй интерфейс MutexFactoryInterface, с уже реализованным методом createAndAcquire().

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

В общем случае есть два варианта использования:

$mutexFactory = new MyMutexFactory();

$mutex = $mutexFactory->create('critical_logic');

if (!$mutex->acquire(1000)) {
throw new \RuntimeException('Unable to acquire "critical_logic" mutex.');
}

// business logic execution

$mutex->release();

и

$mutexFactory = new MyMutexFactory();

// При неудачной блокировке будет
// брошено исключение
$mutex = $mutexFactory->createAndAcquire('critical_logic', 1000);

// business logic execution

$mutex->release();

—————

Класс SimpleMutex

Предоставляет альтернативный вариант работы с мьютексами. Пример:

$mutex = new SimpleMutex(new MyMutexFactory());

if (!$mutex->acquire('critical_logic', 1000)) {
throw new \RuntimeException('Unable to acquire "critical_logic" mutex.');
}

// business logic execution

$mutex->release();

—————

Класс Synchronizer

Позволяет запускать callback-функции в синхронизированном режиме (в один момент времени выполняется только один экземпляр callback-функции). Пример:

$synchronizer = new Synchronizer(new MyMutexFactory());

$newCount = $synchronizer->execute('critical_logic', function () {
return $counter->increase();
}, 10);

—————

Соответствующие изменение внесены в мьютекс-драйверы:

- File Driver (PR),
- MySQL PDO Driver (PR),
- Postgres PDO Driver (PR),
- Oracle PDO Driver (PR).
⚡️ #yiisoftDocs

В документации исправлена ошибка в примере кода в разделе "Saying Hello" (PR).

Спасибо Igbanam Ogbuluijah за пул-реквест 👍
⚡️ #yiisoftFactory

В пакете Yii Factory исправлена ошибка в нормализаторе дефинишенов (PR).

В некоторых случаях нормализатор (класс Normalizer) возвращал некорректный дефинишен с классом null. Теперь в этих случаях бросается исключение InvalidConfigException.
⚡️ #yiisoftDi

Большое обновление сервис-провайдеров в контейнере зависимостей Yii Dependency Injection (PR).

По сути это абсолютно новые сервис-провайдеры. Разрабатывая их, мы ориентировались на container-interop/service-provider (но сделали всё-таки немного по-другому).

Вместо наследования от класса, теперь провайдеры должны реализовывать интерфейс Yiisoft\Di\Contracts\ServiceProviderInterface, содержащий два метода:

getDefinitions() определяет дефинишены для контейнера. Этот метод:

- должен только возвращать дефинишены и не иметь никаких сайд-эффектов;
- должен быть идемпотентным.

getExtensions() возвращает функции обратного вызова, модифицирующие сервисы после их создания. В функцию передаются два аргумента: контейнер и созданный сервис, Возвращает функция сам сервис. Пример:

static function (ContainerInterface $container, MyService $service) {
return $service->withAnotherOption(42);
}

Важно! Сервис-провайдер НЕ должен содержать какую-либо бизнес-логику или другую функциональность, отличную от определения дефинишенов, например внесение изменений в базу данных или определение переменных окружения.

Пример сервис-провайдера:

use Yiisoft\Di\Container;
use Yiisoft\Di\Support\ServiceProvider;

final class CarFactoryProvider extends ServiceProviderInterface
{
public function getDependencies(): array
{
return [
CarFactory::class => [
'class' => CarFactory::class,
'$color' => 'red',
],
EngineInterface::class => SolarEngine::class,
WheelInterface::class => [
'class' => Wheel::class,
'$color' => 'black',
],
CarInterface::class => [
'class' => BMW::class,
'$model' => 'X5',
],
];
}

public function getExtensions(): array
{
return [
// Класс Garage должен быть уже определён в контейнере
Garage::class => function(ContainerInterface $container, Garage $garage) {
$car = $container->get(CarFactory::class)->create();
$garage->setCar($car);
return $garage;
}
];
}
}

—————

В рамках этого PR были удалены классы и интерфейсы DeferredServiceProviderInterface, DeferredServiceProvider, ServiceProvider и AbstractContainerConfigurator.

—————

#yiisoftApp #yiisoftAppApi #yiisoftDemo #yiisoftDemoApi

В процессе адаптации пакетов, использующих сервис-провайдеры была реализована концепция начальной загрузки (bootstrap) в приложениях:

- шаблон веб-приложения (PR),
- шаблон API-приложения (PR),
- демо веб-приложения (PR, PR),
- демо API-приложения (PR).

Bootstrap представляет собой массив функций (точнее callable) вида function (ContainerInterface $container): void, которые последовательно будут вызваны при запуске приложения.

—————

#yiisoftWidget #yiisoftYiiCycle #yiisoftYiiFilesystem #yiisoftYiiDebug #yiisoftYiiDebugApi #yiisoftYiiSentry

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

- Yii Widget (PR),
- Yii Cycle (PR),
- Yii Filesystem (PR),
- Yii Debug (PR),
- Yii Debug Api (PR),
- Yii Sentry (PR).
⚡️ #yiisoftFactory #yiisoftDi

В фабрике и контейнере зависимостей инжектор зависимостей Yiisoft\Injector\Injector теперь используется напрямую, а не берётся из контейнера (PR в Yii Factory, PR в Yii Dependency Injection).

После этого изменения в контейнере исчезла возможность подмены инжектора.
⚡️ #yiisoftFactory #yiisoftDi

В интерфейсе Yiisoft\Factory\DependencyResolverInterface метод resolve() переименован в resolveReference(), так как он разрешает не все зависимости, а только ссылки (PR в Yii Factory, PR в Yii Dependency Injection).
⚡️ #yiisoftFactory #yiisoftDi

Несколько изменений, касающихся дефинишенов в Yii Factory (PR):

• В динамических ссылках DynamicReference запрещено использовать объекты. Попытка передать объект будет вызывать исключение (это работает и для контейнера).

• Объекты, указанные в дефинишене для передачи в качестве аргументов в конструктор, в фабрике теперь НЕ клонируются.

• В интерфейсе Yiisoft\Factory\DependencyResolverInterface удалён метод shouldCloneOnResolve().

• Удалён неиспользуемый код и некорректные тесты.

DependencyResolver в Yii Dependency Injection адаптирован к этим изменениям (PR).
⚡️ #yiisoftYiiAuthClient

В пакете Yii External Authentication Extension ранее удалённый интерфейс Yiisoft\Factory\FactoryInterface заменён на прямое использование фабрики Yiisoft\Factory\Factory (PR).
⚡️ #yiisoftApp #yiisoftViewTwig

В шаблоне веб-приложения удалена лишняя проверка при выводе заголовка страницы <title> (PR).

Аналогичная проблема исправлена в документации к пакету Yii View Twig Renderer (PR).

Спасибо Chabib Nurozak за обнаруженную ошибку 👍
⚡️ #yiisoftMutex

В пакете Yii Mutex добавлены тесты для Mutex и MutexFactory (PR).
⚡️ #yiisoftMutexFile #yiisoftMutexPdoMysql #yiisoftMutexPdoPgsql #yiisoftMutexPdoOracle

В мьютекс-драйверах удалена опция autoRelease (теперь она всегда включена), а автоматическое снятие блокировки выполняется с помощью деструктора класса (__desctruct()) вместо регистрации функции, которая будет выполнена при завершении скрипта (register_shutdown_function()):

- File Driver (PR),
- MySQL PDO Driver (PR),
- Postgres PDO Driver (PR),
- Oracle PDO Driver (PR).

Спасибо kafkiansky за идею 👍
⚡️ #yiisoftFactory #yiisoftDi

В конфигурациях контейнера и фабрики запрещено использование объектов, реализующих DefinitionInterface, за исключением ссылок, то есть объектов, реализующих ReferenceInterface (PR в Yii Factory, PR в Yii Dependency Injection).
⚡️ #yiisoftMutex

Реализована обработка ошибок в пользовательском коде при использовании класса Synchronizer из пакета Yii Mutex (PR).

• В мьютексе всегда будет снята блокировка, даже если во время выполнения callback-функции было брошено исключение.

• Если во время выполнения пользовательского кода произошла ошибка (не исключение, например E_WARNING), то такая ошибка будет преобразована в исключение ErrorException, что позволит перехватить её.

Спасибо Антону @faqphp за обнаруженную проблему 👍
⚡️ #yiisoftDi

В контейнере зависимостей Yii Dependency Injection немного изменён внутренний формат хранения дефинишенов для лучшей читаемости при дампе контейнера (PR).
⚡️ #yiisoftSession

Немного причесали пакет Yii Session (PR):

- включена проверка на обратную совместимость;
- улучшено оформление readme;
- обновлены dev-зависимости;
- исключены все служебные файлы при создании архива репозитория;
- улучшена конфигурация psalm.
- улучшена конфигурации GitHub Workflow и других служебных файлов.