yeast/loafpan 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

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

yeast/loafpan

Composer 安装命令:

composer require yeast/loafpan

包简介

Object and config hydration from associative arrays

README 文档

README

QA

A simple PHP 8 native object expansion (or hydration as some call it) framework

Features

  • Only focused on deserialization of data, thus perfect for configs
  • JSON Schema generation (also works for yaml!)
  • PHP 8 Attribute guided
  • Simple templating/generics support
  • Simple alternative format expanders
  • Custom expander support allows for expanding out-of-branch objects
  • Readable code generation, for ease of debugging and speed

Installation

composer require yeast/loafpan

Very quick use

$config      = json_decode($json, true);

$loafpan     = new Loafpan($loafpanCacheDirectory);
// Don't forget to annotate your class.
$configClass = $loafpan->expand(MyConfig::class, $config);

Usage

To start using Loafpan, you first need to annotate your objects, in the next few examples we will create to fake classes to explain the details

An expandable object is called a "Unit", Units either need to be either annotated with Unit or have a custom expander registered. However for now we'll cover annotated Units

In the first example, Sandwich is a purely setter based unit, and will use the default constructor to instantiate the object and then set the properties manually.

Loafpan is here guided by the Field attributes, which signal which properties can be applied from an object.

// The first argument of `Unit` is the description of the object
// This is used in the JSON Schema generation
#[Unit("This is a very nice sandwich")]
class Sandwich {
    // A custom field name can be given with the `name` parameter
    #[Field(name: "title")]
    public string $name = "";
    // since PHP has no native support for generics or typed arrays (yet)
    // one can override the type, and use list<T> to define the actual type
    #[Field("The toppings of this sandwich", type: 'list<Yeast\Demo\Topping>')]
    public array $toppings = [];
}

Topping however is a purely expander based, and will take only a string, as this is the only instantiation method available

Expander functions are public static functions with either 1 or 2 arguments (the optional second one being a Loafpan instance), the first argument defines the input type that can be used to expand the object from, e.g. Topping can be made from a string alone

#[Unit("What goes on the bread stays on the bread")]
class Topping {
    private function __construct(private bool $wet = false) {}
    
    #[Expander]
    public static function fromName(string $name) {
        return new static($name === 'water' ? true : false);
    }
}

While Topping only defines 1 Expander, you can add multiple, be aware that the results can be unpredictable when the types overlap.

With the 2 classes we just defined, a valid json object for Sandwich would be

{
  // because the "name" property has set it's name to "title",
  // the json object must use title
  "title": "Soggy sandwich",
  "toppings": [
    "water",
    "2 pounds of lead"
  ]
}

which will roughly translate into

$sandwich = new Sandwich();
$sandwich->name = "Soggy sandwich";
$sandwich->toppings = [
   Topping::fromString("water"),
   Topping::fromString("2 pounds of lead")
];

Finally, applying all this, create a Loafpan instance with a directory in which it can scribble php files and call expand with the class you want to expand into, in our case Sandwich and the user input.

The following example shows this usage

$loafpan = new Loafpan($yourLoafpanCacheDirectory);
/** @var Sandwich $sandwich */
$sandwich = $loafpan->expand(Sandwich::class, [
    "title" => "Soggy sandwich",
    "toppings" => [
        "water",
        "2 pounds of lead"
    ]
]);

echo "I have a sandwich called " . $sandwich->name . " the topping:\n";
foreach ($sandwich->toppping as $topping) {
    echo " - " . ($topping->wet ? 'wet' : 'not wet') . "\n";
}

If the options given here doesn't give you enough flexibility, you can always implement your own expander by implementing UnitExpander (\Yeast\Loafpan\UnitExpander) on a class and either registering it to loafpan by using the registerExpander function on a Loafpan instance or setting the expander parameter on the Unit attribute

See src/Expander for some examples of custom UnitExpanders

Default expanders

  • list<T> - only accepts an array list with items of type T
  • map<T> - only accepts an associative array with items of type T
  • DateTime/DateTimeImmutable - only accepts a string with an ISO-8601 formatted date
  • Ramsey\Uuid\Uuid/Ramsey\Uuid\UuidInterface - only accepts a string with a properly formatted UUID

Todo

  • Generate in-depth errors about invalid input

统计信息

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

GitHub 信息

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

其他信息

  • 授权协议: MIT
  • 更新时间: 2022-02-02

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固