proklung / wp-core-symfony
Wordpress 的核心 Symfony 功能
Requires
- php: >=7.3 | ~8
- proklung/base-exception: ^1.0
- symfony/config: ~4|~5
- symfony/console: ^4.0 || ^5.0
- symfony/dependency-injection: ^4.0 || ^5.0
- symfony/dotenv: ^4.0 || ^5.0
- symfony/event-dispatcher: ^4.0 || ^5.0
- symfony/expression-language: 4.0 || ^5.0
- symfony/filesystem: ^4.0 || ^5.0
- symfony/framework-bundle: ^4.0 || ^5.0
- symfony/http-foundation: ^4.0 || ^5.0
- symfony/http-kernel: ^4.0 || ^5.0
- symfony/property-access: ^4.0 || ^5.0
- symfony/proxy-manager-bridge: ^4.0 || ^5.0
- symfony/routing: ^4.0 || ^5.0
- symfony/serializer: ^4.0 || ^5.0
- symfony/validator: ^4.0 || ^5.0
Requires (Dev)
This package is auto-updated.
Last update: 2024-09-22 10:08:02 UTC
README
安装
composer.json
"repositories": [ { "type": "git", "url": "https://github.com/proklung/wp.core.symfony" } ]
composer require proklung/wp-core-symfony
初始化
在 wp-config.php
use Prokl\ServiceProvider\LoadEnvironment; /** Загрузить окружение. Параметр конструктора - путь к .env файлам */ $environment = new LoadEnvironment($_SERVER['DOCUMENT_ROOT']); $environment->load(); $environment->process();
在主题的 functions.php
use Prokl\ServiceProvider\ServiceProvider; $serviceProvider = new ServiceProvider( 'app/symfony/services.yaml', $_ENV['APP_ENV'], (bool)$_ENV['APP_DEBUG'], '/config/bundles.php' );
为了实现与原始版本的“兼容性”(相似性),可以通过构造函数的第四个(非必需)参数指定配置文件(例如,bundles.php
)的路径。
重要的环境变量
APP_ENV
- 环境代码(dev、prod、test 等)APP_DEBUG
- 调试模式
配置
- 在拉取的配置中,
compile.container
选项 - 是否编译容器到文件。如果没有设置,则为“不编译”。对于不等于“dev”的环境有意义。即选项控制容器在 prod 上的导出。
容器导出的存储位置:<容器变量 kernel.cache_dir>/symfony-app/containers
缓存和日志的路径
由 AppKernel
类定义。默认情况下
- 缓存路径(
kernel.cache_dir
) -/wp-content/cache
- 日志路径(
kernel.logs_dir
) -'/../../logs'
(比 DOCUMENT_ROOT 高两级 - 使用 Bitrix 所用构建的特点)
要更改这些,需要从 AppKernel
类继承并重写几个变量
use Prokl\ServiceProvider\Services\AppKernel; class MyKernel extends AppKernel { protected $cacheDir = '/bitrix/cache/mycache'; protected $logDir = '/logs-saver'; }
(第二种方案 - 从 AppKernel
继承并重写 getCacheDir
和 getLogDir
方法)。
通过继承核心类进行更改
class MyServiceProvider extends ServiceProvider { protected $kernelServiceClass = MyKernel::class; protected $cacheDir = '/wp-content/my-cache'; }
第二种方案 - 从 ServiceProvider
继承并用自己的逻辑替换 getPathCacheDirectory
方法。
对包的支持
配置文件 - /config/standalone_bundles.php
。此路径可以通过构造函数更改。
存储配置的文件夹 - /config
。包配置 - /config/packages
。
私有服务的问题
根据 Symfony 的概念,所有服务(理想情况下)都应该是私有的,并且应该进行注入。但在自定义情况下,通常需要通过助手服务定位器来获取它们。为了将所需的服务转换为公共服务,提出了以下解决方案。在容器参数的通用部分出现了 publicable_services
选项。
parameters: publicable_services: - 'snc_redis.default'
容器编译后,私有服务 snc_redis.default
将变为公共服务。
独立的微型容器
独立的容器 - 配置独立,完全隔离(用于模块、插件等)。
use Symfony\Component\DependencyInjection\ContainerBuilder; use Prokl\ServiceProvider\Micro\AbstractStandaloneServiceProvider; use Prokl\ServiceProvider\Micro\ExampleAppKernel; class ExampleMicroServiceProvider extends AbstractStandaloneServiceProvider { /** * @var ContainerBuilder $containerBuilder Контейнер. */ protected static $containerBuilder; /** * @var string $pathBundlesConfig Путь к конфигурации бандлов. */ protected $pathBundlesConfig = '/src/Micro/example.config/standalone_bundles.php'; /** * @var string $configDir Папка, где лежат конфиги. */ protected $configDir = '/src/Micro/example.config/example.config/example.yaml'; /** * @var string $kernelServiceClass Класс, реализующий сервис kernel. * Нужен для того, чтобы экземпляры контейнеров в kernel сервисе не перемешивались. */ protected $kernelServiceClass = ExampleAppKernel::class; }
示例类 ExampleAppKernel
/** * Class ExampleAppKernel * @package Prokl\ServiceProvider\Micro */ use Prokl\ServiceProvider\Micro\AbstractKernel; class ExampleAppKernel extends AbstractKernel { protected static $kernelContainer; }
在哪里需要 - 初始化
$micro = new ExampleMicroServiceProvider( 'src/SymfonyDI/Micro/example.config/example.yaml', $_ENV['APP_ENV'], (bool)$_ENV['APP_DEBUG'] );
助手 container
针对微型服务提供者进行优化
var_dump(container($micro)->getParameter('example'));
自动启动服务
为了在容器初始化后自动启动服务,它必须被标记为 service.bootstrap
标签。
app.options: class: Local\Services\AppOptions arguments: ['%kernel.environment%', '@parameter_bag'] tags: ['service.bootstrap']
支持启动优先级。那么就要这样
app.options: class: Local\Services\AppOptions arguments: ['%kernel.environment%', '@parameter_bag'] tags: - { name: 'service.bootstrap', priority: 100 }
优先级为 100 的服务将比优先级为 200 的服务先启动。
自动绑定到 WordPress 插件
标签: custom.events.init
。
type
- add_action、add_filter 等 默认:add_action
。event
- 插件名称。method
- 服务中的处理方法priority
- 优先级
Local\Events\CometCacheClearMemcachedEvent: tags: - { name: 'custom.events.init', event: 'post_class', method: 'handler', type: 'add_filter', priority: 100 }
自动注册帖子类型
标签: post.type
。
实现 PostTypeDataInterface
接口,具有两个方法
getNameTypePost
- 帖子类型名称getRegistrationData
- 带有传统帖子类型声明数据的数组。例如:
return [ 'labels' => [ 'name' => __('Instagram'), 'singular_name' => __('Instagram'), ], 'public' => true, 'publicly_queryable' => true, 'show_ui' => true, 'show_in_menu' => true, 'query_var' => true, 'rewrite' => 'instagram', 'capability_type' => 'post', 'has_archive' => 'instagram', 'hierarchical' => false, 'menu_position' => null, 'supports' => ['title', 'editor', 'author', 'thumbnail', 'excerpt', 'comments'], ];
Local\PostTypes\InstagramPostType: tags: - { name: 'post.type' }
默认服务
自动注册几个服务
service_container
(和别名)- 服务容器本身app.request
- 全局变量到 Request 的转换器custom.post.type.registrator
- 在 WordPress 中注册自定义帖子类型- 服务的同义词
kernel
。 delegated_container_manipulator
- 委派容器操作器。
助手
container()
- 返回容器实例(充当服务定位器)
$kernel = container()->get('kernel');
delegatedContainer()
- 返回一个管理器实例(实现接口Symfony\Component\DependencyInjection\ContainerInterface
),用于处理委托容器。
$moduleService = delegatedContainer()->get('my_module_id.service');
委托容器 - 一个独立容器,通常在模块、插件等地方形成。
在容器中,它使用标签 delegated.container
进行标记(可以有多个)。
module_notifier_container: class: Symfony\Component\DependencyInjection\ContainerInterface factory: ['Proklung\Notifier\DI\Services', 'getInstance'] tags: - { name: 'delegated.container' }