aplia/starter-bootstrap

为启动 eZ publish 项目提供的通用代码

v1.14 2021-01-26 09:51 UTC

README

此软件包包含启动 eZ publish 项目所需的通用代码。它设置必要的全局变量,加载 Composer 自动加载器,并安装错误处理器。

但是,它不会启动 eZ publish 内核,相反,此引导系统应包含在项目的一部分 config.php 文件中。

Latest Stable Version Minimum PHP Version

安装

通过运行以下命令将此软件包添加到项目中

composer require aplia/starter-bootstrap

然后,将以下行添加到 config.php

<?php
// Bootstrap the system based on our configuration
if (!file_exists(__DIR__ . '/vendor/aplia/starter-bootstrap/bootstrap.php')) {
    if (PHP_SAPI != 'cli') {
        echo '<html><body><p>';
    }
    $text =
        "aplia/starter-bootstrap is not installed, cannot continue.\n" .
        "Make sure the bootstrap system is installed by running:\n" .
        "composer require 'aplia/starter-bootstrap:^1.2'\n";
    if (PHP_SAPI == 'cli') {
        echo $text;
    } else {
        echo nl2br($text), '</p></body></html>';
    }
    exit(1);
}
require __DIR__ . '/vendor/aplia/starter-bootstrap/bootstrap.php';

require 调用还将返回当前的 App 实例以供进一步检查。

优化生产环境

为了减少在生产模式下引导过程中需要处理的文件数量,系统可以创建一个优化的引导文件和配置文件。这通过以下操作完成

vendor/bin/bootstrap_build

这将在 build 文件夹中创建文件,将用于动态设置引导过程。网站的部署系统应设置成始终运行此命令以获取更新的代码和配置。

可以通过运行以下命令删除构建文件

vendor/bin/bootstrap_clean

开发

向包中添加新功能时,必须考虑兼容性。任何 Starter 项目都应能够更新到最新版本,并且仍然可以正常工作。新的行为必须仅通过配置(全局变量等)激活,这些配置默认是关闭的。

配置本地安装

要覆盖配置条目,可以创建文件 extension/site/config/local.php。它必须是一个 PHP 文件,它返回一个包含配置条目的数组。

示例

<?php
return [
    'app' => [
        'errorLevel' => 'error',
    ],
    'sentry' => [
        'dsn' => 'https://....@sentry.aplia.no/..',
    ],
];

此文件将在最后加载,因此它将覆盖 vendor/aplia/starter-bootstrap/config 中其他配置文件中的任何值。

也可以定义配置文件来覆盖 basedevprod 的条目。例如,extension/site/config/base.php 将为所有环境定义站点的基配置,而 extension/site/config/prod.php 定义生产配置,extension/site/config/dev.php 定义开发配置。

添加功能助手

可以定义额外的全局可用函数,也称为助手。当前使用的助手列表由配置 app.helpers 确定(参见 base.php 中的示例)。这些助手的名称然后在配置条目 helpers 中定义,其中包含一个包含要包含的文件名的数组。

每个文件名都是一个仅定义函数的 PHP 文件,它不能执行任何其他代码。也很重要检查函数是否尚未定义,这可以避免 PHP 错误,并允许重新定义函数。示例

path/to/helper.php

<?php
if (!function_exists('my_helper')) {
    function my_helper()
    {
        // code here.
    }
}

然后通过以下方式定义助手条目

<?php
return [
    'helpers' => [
        'site' => ['path/to/helper.php'],
    ],
];

并通过以下方式激活它

<?php
return [
    'app' => [
        'helpers' => [
            'site' => 300,
        ],
    ],
];

优先级值很重要,因为它确定文件何时加载。例如,如果您想覆盖现有函数,则使用较低的值,但通常只需使用较高的值(300 或更高)以最后加载它。

弃用

PHP 报告的弃用错误将默认发送到错误日志。此行为受配置 app.deprecation 控制。对于开发,这更改为 error,这意味着在错误处停止并显示错误页面。

可以通过设置 ERROR_DEPRECATION 为有效值之一来在运行时更改弃用模式。

例如

ERROR_DEPRECATION=ignore php old_script.php

调试错误

在开发过程中,系统将在错误处停止并显示错误页面。PHP 的一个限制使得无法查看堆栈跟踪中的变量内容。为了解决这个问题,可以使用 dump 函数将变量存储在基本应用程序中,直到发生错误。一旦渲染了错误页面,它将在表中显示这些调试变量。dump 还会输出页面上的变量内容,就像 var_dump 一样,但具有更好的 HTML 和 CLI 运行输出。

示例用法

<?php
dump($data);

dump() 还支持来自 eZ publish 模板使用的属性系统或实现 __properties 的类的虚拟属性。有关更多详细信息,请参阅下文的 高级 dump 使用

如果您想将变量与名称关联起来,请使用 inspect 函数,因为它还会存储变量或表达式的名称。

示例用法

<?php
inspect($name, '$name');

日志记录

入门级引导程序集成了 Monolog 日志系统,有关更多详细信息,请参阅 LOGGING.md。

使用编辑器链接

通过设置配置 editor.name,错误处理程序将更改文件链接以使用编辑器链接。

以下编辑器受支持

  • 'sublime' 用于 SublimeText
  • 'textmate' 用于 TextMate
  • 'emacs' 用于 Emacs
  • 'macvim' 用于 MacVim
  • 'phpstorm' 用于 PHP Storm
  • 'idea' 用于 IDEA
  • 'vscode' 用于 VS Code

可以通过设置 editor.editors 使用其他编辑器。

默认情况下,它假定文件路径位于远程服务器上,并将它们映射到本地路径。但是,为了正确工作,需要在 editor.fileMappings 中设置映射。例如:

[
    'editor' => [
        'fileMappings' => [
            // Example 1: Map root of project to local path
            '' => '~/src/myproject',
        ],
    ],
];

要禁用远程文件映射,请将 editor.remoteFilesystem 设置为 false

extension/site/config/local.php 配置示例

<?php
return [
    'editor' => [
        'name' => 'sublime',
        'fileMappings' => [
            '' => '~/src/myproject',
        ],
    ],
];

配置

可以使用全局变量或 $_ENV 变量配置引导程序。

选择要停止的错误

默认行为是仅停止具有 error 级别的错误,这是为了避免现有扩展或 eZ publish 导致站点停止。但是在开发过程中,应该将级别更改为捕获所有级别。

extension/site/config/local.php 中创建文件并包含以下内容

<?php
return [
    'app' => [
        'errorLevel' => 'notice',
    ],
];

这告诉引导程序系统在通知、警告和错误处停止。

调试引导程序过程

可以通过设置全局变量 STARTER_BASE_DEBUG 为 true 来调试引导程序过程。如果 dev 模式是 STARTER_CONFIGS 的一部分,则它将自动启用。这将尽快安装错误处理程序。

<?php
$GLOBALS['STARTER_BASE_DEBUG'] = true;

此外,还可以通过设置全局变量 STARTER_BASE_DUMP_CONFIG 来输出最终应用程序配置。

<?php
$GLOBALS['STARTER_BASE_DUMP_CONFIG'] = true;

使用这将立即结束进程。

要查看引导过程中使用的所有功能调用,请将全局变量 STARTER_DEBUG_TRACE 设置为 true

<?php
$GLOBALS['STARTER_DEBUG_TRACE'] = true;

跟踪的文件名和选项由全局变量 STARTER_DEBUG_TRACE_FILESTARTER_DEBUG_TRACE_OPTIONS 控制。

使用自定义 BaseConfig 类

用于存储基本配置的配置类可以通过设置全局变量 STARTER_CONFIG_CLASS 来覆盖。该类将使用自动加载器加载。

<?php
$GLOBALS['STARTER_CONFIG_CLASS'] = '\\Custom\Config';

使用自定义 BaseApp 类

用于存储当前应用程序及其配置对象的类可以通过设置全局变量 STARTER_APP_CLASS 来覆盖。该类将使用自动加载器加载。

<?php
$GLOBALS['STARTER_APP_CLASS'] = '\\Custom\\App';

指定 www-root

www-root 是网站服务器提供所有文件的根目录,它自动被设定为安装 vendor 文件夹的根目录。要覆盖自动行为,请设置环境变量 WWW_ROOT

<?php
$_ENV['WWW_ROOT'] = 'www';

指定 eZ publish 根目录

eZ publish 将自动检测,位于 www-root 或 vendor 文件夹内。如果使用自定义文件夹用于 eZ publish,可以通过设置环境变量 EZP_ROOT 来覆盖。

<?php
$_ENV['EZP_ROOT'] = 'ezpublish';

指定 vendor 文件夹

composer 的 vendor 文件夹默认设置在 www-root 中的 vendor,但可以通过设置环境变量 VENDOR_ROOT 来覆盖。

<?php
$_ENV['VENDOR_ROOT'] = 'custom_vendor';

指定要使用的配置

对于指定基本配置,设置全局变量 STARTER_BASE_CONFIGS。注意:通常不推荐设置。

<?php
// Adding an additional base config
$GLOBALS['STARTER_BASE_CONFIGS'] = ['base', 'core'];

或者使用环境变量 BASE_CONFIGS 控制。它是一个以逗号分隔的配置名称列表,例如 base,core

对于指定当前框架,设置全局变量 STARTER_FRAMEWORK。默认为 ezp。它可以是一个字符串表示单个框架,也可以是一个数组用于激活多个框架。

<?php
// Enabling specific config for laravel
$GLOBALS['STARTER_FRAMEWORK'] = 'laravel';

或者使用环境变量 FRAMEWORK 控制。它是一个以逗号分隔的配置名称列表,例如 laravel,ezp

对于指定当前运行模式,设置全局变量 STARTER_CONFIGS。默认为 prod

<?php
// Enabling development config
$GLOBALS['STARTER_CONFIGS'] = ['dev'];

或者使用环境变量 APP_ENV 控制。它是一个以逗号分隔的配置名称列表,例如 dev,other

还可以使用全局变量 STARTER_EXTRA_CONFIGS 设置附加配置。

<?php
// Enabling development config
$GLOBALS['STARTER_EXTRA_CONFIGS'] = ['extra'];

或者使用环境变量 EXTRA_CONFIGS 控制。它是一个以逗号分隔的配置名称列表,例如 extra

指定引导类

对于每个配置设置,都可能设置一个用于引导系统的类。例如,base 配置设置了类 Aplia\Bootstrap\BaseApp,它有静态方法 bootstrapSubSystem

这可以在配置中的 app.bootstrap.classes 下设置,它是一个关联数组,键必须是具有 starter.app. 前缀的配置名称,值是具有完整命名空间的类名称。starter. 类将在 app. 类之前运行。主要用于应用程序的 app. 前缀。

<?php
// Example configuration
return [
    'app' => [
        'bootstrap' => [
            'classes' => [
                'starter.base' => 'Aplia\Bootstrap\BaseApp',
            ],
        ],
    ],
];

高级转储使用

可以通过配置额外的 Caster 函数来扩展 dump 函数。可以使用 cast 函数从对象中提取额外属性,例如作为虚拟属性。

Casters 通过将它们添加到 app.dump.casters 配置数组中进行配置,例如

return [
    'app' => [
        'dump' => [
            'casters' => [
                // Dump virtual attributes on all persistent objects
                'eZPersistentObject' => ['Aplia\Bootstrap\VirtualAttributeCaster', 'castAttributes'],
            ],
        ],
    ],
];

将其添加到您的本地配置文件 extension/site/config/local.php

当使用 eZ publish 引导模式时,默认启用对 eZPersistentObject 的支持。

有关 casters 的更多信息,请参阅 var_dumper 文档:https://symfony.com.cn/doc/current/components/var_dumper/advanced.html#casters

PHP 魔术属性

还支持 PHP 内置属性系统,这些由魔术方法 __get() 和(可选)__set() 处理。然而,PHP 没有魔术方法来报告类上存在哪些属性。为了帮助解决这个问题,VirtualAttributeCaster 支持自定义的 __properties() 方法,如果类上设置了此方法,它将使用此方法提取属性并将它们作为常规 PHP 属性检索,这将触发 __get()

由于系统不知道哪些类支持此系统,因此必须手动按项目配置。将 VirtualAttributeCaster 添加为特定或基类的 caster。

例如,如果我们有一个名为 BasedModel 的类

namespace CustomProject;

class BasedModel
{
    public function __properties()
    {
        return ['id'];
    }

    public function __get($name)
    {
        if ($name === 'id') {
            return $this->fetchId();
        }
    }

    public function fetchId()
    {
        // ...
    }
}

则可以将其配置为

return [
    'app' => [
        'dump' => [
            'casters' => [
                'CustomProject\BaseModel' => ['Aplia\Bootstrap\VirtualAttributeCaster', 'castAttributes'],
            ],
        ],
    ],
];

禁用默认 casters

如果您不想使用 var-dumper 提供的默认铸件,请将 app.dump.defaultCastersEnabled 设置为 false。

控制虚拟属性

虚拟属性分为四类:简单、经济、昂贵和阻塞属性。

简单属性是指映射到对象现有属性上的属性,并且始终会显示。

经济属性在调用它们以获取其值时被认为是低成本,通常会被显示。

昂贵属性被认为是高成本,例如从数据库中获取数据,默认情况下不会显示。

阻塞属性通常不打算被检索,因为它们可能存在问题,例如从数据库中检索大量数据的操作。

要控制要检索哪些虚拟属性,可以使用配置 app.dump.expandMode,它默认为 expanded,可以是以下之一:

  • 基本 - 总是检索简单和经济属性。
  • 展开 - 对于初始对象,检索简单、经济和昂贵属性;嵌套对象仅使用简单和经济。
  • 嵌套 - 对于所有对象,检索简单、经济和昂贵属性。
  • 全部 - 对于所有对象,检索简单、经济、昂贵和阻塞属性。
  • 无 - 不检索任何虚拟属性,仅列出它们。

系统为 eZ publish 的一些关键类定义了虚拟属性,但如果您需要访问其他类的属性,则使用 app.dump.virtualAttributesapp.dump.expensiveAttributes 配置条目。这些包含类及其应显示的属性的定义。

virtualAttributes 定义经济属性,而 expensiveAttributes 定义昂贵属性。

eZContentClassAttribute 的示例。

return [
    'app' => [
        'dump' => [
            'virtualAttributes' => [
                'eZContentClassAttribute' => [
                    'data_type',
                    'display_info',
                    'name',
                    'nameList',
                    'description',
                    'descriptionList',
                    'data_text_i18n',
                    'data_text_i18n_list',
                ],
            ],
            'expensiveAttributes' => [
                'eZContentClassAttribute' => ['content', 'temporary_object_attribute'],
            ],
        ],
    ],
];