定制 beecubu/php-foundation-core 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

beecubu/php-foundation-core

Composer 安装命令:

composer require beecubu/php-foundation-core

包简介

Main package of PHP Object Foundation Framework.

README 文档

README

Core package for PHP Object Foundation. This is the base used by the rest of the framework libraries. It provides:

  • A strict property system (Objectum) with typed properties and validation.
  • Serialization and JSON export/import (Serializable) with custom hooks.
  • Enum utilities (Enum), property definitions (Property), and serialization helpers.
  • Common tools: date/time utilities and formatters.

Requirements

  • PHP 7.1+
  • ext-openssl
  • ext-json

Installation

composer require beecubu/php-foundation-core

Key Concepts

Objectum (Typed Properties)

Define properties with types and access rules:

<?php

use Beecubu\Foundation\Core\Objectum;
use Beecubu\Foundation\Core\Property;

class User extends Objectum
{
    protected function properties(): void
    {
        $this->properties += [
            'name'   => [Property::READ_WRITE, Property::IS_STRING],
            'age'    => [Property::READ_WRITE, Property::IS_INTEGER],
            'active' => [Property::READ_WRITE, Property::IS_BOOLEAN],
        ];
    }
}

$u = new User();
$u->name = 'Ada';
$u->active = 'yes';

Enums

use Beecubu\Foundation\Core\Enum;

class Status extends Enum
{
    public const Draft = 'draft';
    public const Sent = 'sent';
}

Use enums in properties with validation:

use Beecubu\Foundation\Core\Property;

$this->properties += [
    'status' => [Property::READ_WRITE, Property::IS_ENUM, Status::class],
];

Serializable

Serializable extends Objectum and adds JSON/RawData serialization with custom hooks and property filtering.

<?php

use Beecubu\Foundation\Core\Serializable;
use Beecubu\Foundation\Core\Property;

class Article extends Serializable
{
    protected function properties(): void
    {
        parent::properties();
        $this->properties += [
            'title'   => [Property::READ_WRITE, Property::IS_STRING],
            'content' => [Property::READ_WRITE, Property::IS_STRING],
        ];
    }
}

$a = new Article();
$a->title = 'Hello';

$json = $a->json();        // stdClass
$raw = $a->rawData();      // stdClass

$copy = Article::instanceWithJson($json);

Encrypted Strings

If a property is Property::IS_STRING_ENCRYPTED, values are stored encrypted in raw data. In JSON, the framework exports them as an EncryptedStringProperty object with kind, encoding, and value.

$this->properties += [
    'secret' => [Property::READ_WRITE, Property::IS_STRING_ENCRYPTED],
];

Example JSON shape:

$json = $article->json();

$json->secret->kind;      // encrypted-string
$json->secret->encoding;  // base64
$json->secret->value;     // base64 payload

When importing from JSON:

  • If secret is a string, it is treated as plain text and encrypted.
  • If secret is an object, it is treated as an EncryptedStringProperty.

Object Auto-Initialization

By default, IS_OBJECT properties are auto-created when first accessed (if no value is set). You can disable this globally:

Beecubu\Foundation\Core\Objectum::$CreateObjectPropertiesOnGet = false;

IS_OBJECT and IS_OBJECT_NULLABLE can also accept more than one class by passing an array of class names as the third property definition value:

$this->properties += [
    'target' => [Property::READ_WRITE, Property::IS_OBJECT_NULLABLE, [User::class, Team::class]],
];

When importing serialized data for a property with multiple possible classes, include _class in the raw/json object so the framework can resolve which concrete class must be created.

On-Demand References

SerializableProperty::CREATE_ON_DEMAND_BY_ID allows lazy-loading related objects by id.
Important: the referenced class must implement protected static function instanceByRawDataId($id) or lazy loading will fail.
This method is called by the serialization layer when a property is accessed and only an id is available. The default implementation throws an exception, so each on-demand class must provide its own factory.

use Beecubu\Foundation\Core\SerializableProperty;

$this->properties += [
    'author' => [Property::READ_WRITE, Property::IS_OBJECT_NULLABLE, Author::class, SerializableProperty::CREATE_ON_DEMAND_BY_ID],
];

Example implementation:

class Author extends Serializable
{
    // properties()...

    protected static function instanceByRawDataId($id)
    {
        // Fetch from persistence layer by id and return an Author instance.
        // Example: return AuthorRepository::findById($id);
    }
}

Serializable Snapshots

SerializableProperty::IS_SNAPSHOT stores a read-only partial copy of a related Serializable object instead of storing the live object or only its id. This is useful for historical data where the owner must keep a small immutable picture of another entity.

The source class declares which fields are part of the snapshot:

class Status extends Serializable
{
    protected function properties(): void
    {
        parent::properties();
        $this->properties += [
            'title' => [Property::READ_WRITE, Property::IS_STRING],
            'color' => [Property::READ_WRITE, Property::IS_STRING],
            'description' => [Property::READ_WRITE, Property::IS_STRING],
        ];
    }

    protected function snapshotProperties(): void
    {
        $this->snapshotProperties = ['title', 'color'];
    }
}

The owner marks the property as a snapshot:

use Beecubu\Foundation\Core\SerializableProperty;

$this->properties += [
    'status' => [Property::READ_WRITE, Property::IS_OBJECT_NULLABLE, Status::class, SerializableProperty::IS_SNAPSHOT],
];

IS_SNAPSHOT is only supported for IS_OBJECT, IS_OBJECT_NULLABLE, and typed IS_ARRAY object properties. Using it with another property type throws SerializableUnsupportedSnapshotPropertyTypeException.

Assigning a Status creates a SerializableSnapshot. The snapshot only exposes the configured properties and all of them are read-only:

$notification->status = $status;

$notification->status->isSnapshot(); // true
$notification->status->isSnapshotOf(Status::class); // true
$notification->status->title;        // copied from $status

If an existing SerializableSnapshot is assigned directly, the framework validates that its source class is accepted by the property and that its scope matches the property scope when one is defined.

Snapshots can also be scoped when the same source class needs different partial views:

class Status extends Serializable
{
    protected function snapshotProperties(): void
    {
        $this->snapshotProperties = [
            'notification' => ['title', 'color'],
            'badge' => ['color'],
        ];
    }
}

$this->properties += [
    'status' => [Property::READ_WRITE, Property::IS_OBJECT_NULLABLE, Status::class, SerializableProperty::IS_SNAPSHOT, 'notification'],
];

For dynamic cases, override snapshotPropertiesForScope(?string $scope = null): array and return the property names for that scope.

In RawData mode, snapshots always include _class and include _scope when a scope is defined. These metadata fields are used to reconstruct the virtual snapshot and to validate consistency. If a property defines a scope and imported RawData contains a different _scope, the framework throws SerializableSnapshotScopeMismatchException.

IS_SNAPSHOT also supports IS_OBJECT / IS_OBJECT_NULLABLE properties with multiple accepted classes:

$this->properties += [
    'state' => [Property::READ_WRITE, Property::IS_OBJECT_NULLABLE, [OpenState::class, ClosedState::class], SerializableProperty::IS_SNAPSHOT],
];

It can also be used with typed arrays of objects:

$this->properties += [
    'states' => [Property::READ_WRITE, Property::IS_ARRAY, State::class, SerializableProperty::IS_SNAPSHOT],
];

SerializableProperty::CREATE_SNAPSHOT_BY_ID behaves like IS_SNAPSHOT, but also accepts reference data as input. When an id or reference payload is assigned or imported, the framework normalizes it through TargetClass::parseDataBeforeInsertInIvarsOnDemand($data), calls TargetClass::instanceByRawDataId($id) immediately, and stores the resulting snapshot.

$this->properties += [
    'status' => [Property::READ_WRITE, Property::IS_OBJECT_NULLABLE, Status::class, SerializableProperty::CREATE_SNAPSHOT_BY_ID],
    'states' => [Property::READ_WRITE, Property::IS_ARRAY, State::class, SerializableProperty::CREATE_SNAPSHOT_BY_ID],
];

Important: the target class must implement protected static function instanceByRawDataId($id). If the incoming data is not a primitive id, use parseDataBeforeInsertInIvarsOnDemand() in the target class to extract the id exactly as with CREATE_ON_DEMAND_BY_ID. The property value is still a SerializableSnapshot (or an array of snapshots), never a lazy reference.

Tools

Helpers

use Beecubu\Foundation\Core\Tools\Helpers;

Helpers::empty($value); // Better empty() for framework objects

Formatters

use Beecubu\Foundation\Core\Tools\Formatters\NumberFormatter;
use Beecubu\Foundation\Core\Tools\Formatters\DateFormatter;
use Beecubu\Foundation\Core\Tools\Formatters\StringFormatter;
use Beecubu\Foundation\Core\Tools\Formatters\PluralsFormatter;

NumberFormatter::numberToString(1234.56, 'en'); // "1,234.56"
DateFormatter::dateToString(new DateTime(), 'en');
StringFormatter::utf82iso('àéí');
PluralsFormatter::plural('day', 2, 'en'); // "days"

DateTime Helper

use Beecubu\Foundation\Core\Tools\DateTime;

$dt = new DateTime('@1717352123'); // respects php.ini timezone

Custom Properties (Serialization Hooks)

Serializable lets you override how specific properties are imported/exported by defining custom flags in customProperties().
The flags are defined in Beecubu\Foundation\Core\CustomProperty and control:

  • When the hook runs: import, export, or both
  • Which mode: JSON, RawData, or both

Typical pattern:

use Beecubu\Foundation\Core\CustomProperty;

class Report extends Serializable
{
    protected function properties(): void
    {
        parent::properties();
        $this->properties += [
            'status' => [Property::READ_WRITE, Property::IS_STRING],
            'secret' => [Property::READ_WRITE, Property::IS_STRING],
        ];
    }

    protected function customProperties(): void
    {
        $this->customProperties += [
            // Only transform when exporting to JSON
            'status' => CustomProperty::ON_EXPORT | CustomProperty::ON_JSON_MODE,
            // Only transform when importing from RawData
            'secret' => CustomProperty::ON_IMPORT | CustomProperty::ON_RAW_MODE,
        ];
    }

    protected function exportCustomProperty(string $property, $value, bool $rawDataMode, ?array $fields = null, bool $excluding = true, bool $ignoreEmptyValues = true)
    {
        if ($property === 'status') return strtoupper($value);
        return $value;
    }

    protected function importCustomProperty(string $property, $value, bool $replace = true, bool $rawDataMode = false, bool $writableOnly = false)
    {
        if ($property === 'secret') return trim($value);
        return $value;
    }
}

Useful flag presets:

  • CustomProperty::ON_IMPORT_AND_EXPORT_IN_ALL_MODES
  • CustomProperty::ON_IMPORT | CustomProperty::ON_JSON_MODE
  • CustomProperty::ON_EXPORT | CustomProperty::ON_RAW_MODE

Property Types Reference

Common property types:

  • Property::IS_STRING
  • Property::IS_STRING_ENCRYPTED
  • Property::IS_INTEGER
  • Property::IS_FLOAT
  • Property::IS_BOOLEAN
  • Property::IS_DATE
  • Property::IS_ENUM
  • Property::IS_ENUM_NULLABLE
  • Property::IS_ARRAY
  • Property::IS_ARRAY_ENUM
  • Property::IS_OBJECT
  • Property::IS_OBJECT_NULLABLE
  • Property::IS_DICTIONARY
  • Property::IS_BINARY

Access types:

  • Property::READ_ONLY
  • Property::READ_WRITE
  • Property::WRITE_ONLY

beecubu/php-foundation-core 适用场景与选型建议

beecubu/php-foundation-core 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 270 次下载、GitHub Stars 达 0, 最近一次更新时间为 2019 年 10 月 10 日, 在 PHP 生态内属于活跃度较高的组件。

我们在过去多个企业项目中使用过 beecubu/php-foundation-core 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 beecubu/php-foundation-core 我们能提供哪些服务?
定制开发 / 二次开发

基于 beecubu/php-foundation-core 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 270
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 3
  • 依赖项目数: 7
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2019-10-10