Public SDK Reference
当前公开 PHP 合同的精确签名、参数、返回值、能力门禁与失败边界。
# 先读规则
只使用本页列出的公开类型。注册阶段只声明,不执行产品工作;运行时工作只能放在收到 RuntimeContext 的 handler/provider 中。不要导入 Kernel 的非公开命名空间,也不要自行实现第二套权限、依赖或生命周期控制面。
# PluginRegistrar
interface PluginRegistrar
{
public function register(RegistrationContext $context): void;
}
register() 返回 void,唯一职责是声明 handler、资源、配置和 presentation contribution。不要在这里读写数据、发网络请求或执行迁移。
# RegistrationContext
| 方法 | 要求与结果 |
|---|---|
onEvent(string $eventId, string $handlerId, callable $handler, int $priority = 0): void | handler 为 callable(RuntimeContext, mixed): mixed;需要 event.listen,且事件必须在 manifest 中声明并由主机定义。 |
onLifecycle(string $action, callable $handler): void | handler 为 callable(RuntimeContext): void;action 仅为 install、enable、disable、upgrade、uninstall。 |
template(string $name, string $relativePath): void | 路径必须已列入 manifest 的 templates。 |
asset(string $name, string $relativePath): void | 路径必须已列入 manifest 的 assets。 |
configSchema(callable $validator): void | validator 为 callable(string, mixed): bool;非法配置返回 false。 |
themeProvider(array $presentationScopes = ['site.default']): void | 仅 theme-presentation,需要 provider.register。 |
presentationContribution(string $target, PresentationContributionKind $kind, string $template, string $contributionId, int $priority = 0): void | target 必须由主机登记,template 必须先注册。OVERRIDE 需要 ui.theme.override,SLOT 需要 content.decorate。 |
presentationDataProvider(string $type, string $version, PresentationDataProvider $provider): void | 主题包禁止提供业务数据;需要 provider.register;type/version 必须与 provider 实现一致。 |
# RuntimeContext
final class RuntimeContext
{
public readonly PackageIdentity $identity;
public readonly GrantSet $grants;
public readonly DataStore $data;
public readonly ScopedConfigStore $config;
public readonly ScopedCacheStore $cache;
public readonly ScopedTemplateRegistry $templates;
public readonly ScopedAssetRegistry $assets;
public readonly ScopedLogger $logger;
public readonly array $request;
}
所有 handle 已绑定当前包身份。不要传入另一个 package id,也不要绕过 capability grant。配置提供 set(string, mixed): void、get(string, mixed = null): mixed、all(): array;缓存提供 get(string): mixed、put(string, mixed): void、delete(string): void;模板提供 resolve(string): string;资源提供 url(string): string;日志提供 log(string $severity, string $message, array $context = []): void,severity 仅 debug/info/warning/error。
# DataStore
public function get(string $namespace, string $key): mixed;
public function put(string $namespace, string $key, mixed $value): void;
public function delete(string $namespace, string $key): void;
get 需要 database.module.read;put/delete 需要 database.module.write。namespace 必须在 data_ownership 中。
当前公开 DataStore 没有 query、list、order、update 或 transaction 方法。需要列表时,把确定性列表建模为一个 value,由包代码读取、排序并整体写回;不要虚构查询接口。
# Migration
new Migration(
string $id,
int $order,
string $checksum,
callable(DataStore): void $apply,
bool $idempotentRetry = false,
);
id 不能为空,checksum 必须是小写 SHA-256 十六进制。Runner 按 [order, id] 排序;重复 id 被拒绝;已记录为 APPLIED 的迁移不会再次运行;历史 checksum 不可改变。FAILED 迁移仅在显式 idempotentRetry=true 时允许重试。
# PackageManifest
验证后的只读属性为:manifestVersion、identity、packageType、entrypoint、capabilities、requires、optionalRequires、migrations、dataOwnership、uninstallPolicy、events、templates、assets、raw。完整 JSON 字段规则见 Manifest Reference。
# Presentation contracts
enum PresentationContributionKind: string {
case OVERRIDE = 'OVERRIDE';
case SLOT = 'SLOT';
}
final class PresentationViewModel {
public function __construct(
public readonly string $type,
public readonly string $version,
public readonly array $data,
);
}
interface PresentationDataProvider {
public function type(): string;
public function version(): string;
public function provide(array $request): PresentationViewModel;
}
final class PresentationRenderContext {
public function __construct(
public readonly array $page,
public readonly array $viewer,
public readonly array $navigation,
public readonly array $theme,
public readonly array $models,
public readonly array $invocation,
);
}
ViewModel type 使用点分小写标识,version 为三段数字。模型与 render context 只允许结构化值和有限数字;models 的 key 必须是 type@version。Presentation 是数据与渲染合同,不授予存储权限。
# 失败方式
公开失败以 KernelException 的稳定 code 表达。常见门禁包括未声明或未授权 capability、数据 namespace 不属于当前包、事件未声明、模板/资源未声明、presentation target 不存在、provider 声明与实现不一致。界面可以本地化文案,但必须保留 code。