承接 amsify42/php-typestruct 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

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

amsify42/php-typestruct

Composer 安装命令:

composer require amsify42/php-typestruct

包简介

PHP package for validating data against the structure defined

README 文档

README

PHP package for validating data against the structure defined.

Installation

$ composer require amsify42/php-typestruct

Table of Contents

  1. Introduction
  2. Validation
  3. Data
  4. Class Validation
  5. Rules
  6. Custom Rules
  7. Complex Example

1. Introduction

The purpose of this php package is to make validation easy and the structure defined for validation should be readable. The data passed can be validated against the structure defined.

2. Validation

Let's say we have data in array format.

$data = [
    'id' => 42,
    'name' => 'amsify',
    'price' => 4.2
];

and we want this to be strictly validated. Now we can define the structure against which this data to be validated.

namespace App\TypeStruct;

export typestruct Simple {
    id: int,
    name: string,
    price: float
}

Notice that the structure we defined does not completely look like a PHP syntax but it will work as a structure against data.

$data = [
    'id' => 42,
    'name' => 'amsify',
    'price' => 4.2
];
$typeStruct = new Amsify42\TypeStruct\TypeStruct();
$typeStruct->setClass(App\TypeStruct\Simple::class);
$result = $typeStruct->validate($data);

Note we are creating new instance of Amsify42\TypeStruct\TypeStruct, passing the full class name of typestruct App\TypeStruct\Simple and pasing data to validate() method.

The validate method will return with the info whether the data passed is validated against the structure and it will return

array(2) {
  ["is_validated"]=>
  bool(true)
  ["messages"]=>
  array(0) {
  }
}

The is_validated will have true or false based on whether data is validated or not and messages will have error messages in hierarchy based on elements which are not validated.

Helper method

We can also use helper method to get the Amsify42\TypeStruct\TypeStruct new instance.

/**
 * If we have direct of the typestruct file
 */
$typeStruct = get_typestruct('/path/to/Simple.php');
$result = $typeStruct->validate($data);
/**
 * For class, we need to pass full class name and 2nd param as 'class'
 */
$typeStruct = get_typestruct(App\TypeStruct\Simple::class, 'class');
$result = $typeStruct->validate($data);

Autoloading

Autoloading of the typestruct file will be done automatically if its name and path is based on psr-4 standards else you need to use setPath() method with typestruct instance which expects direct path of the typestruct file.

Options

With Typestruct instance we can set these options before calling validate() method

/**
 * To tell the typestruct that data we are passing is of type object(stdClass)
 * default is false
 */
$typeStruct->isDataObject(true);
/**
 * If true, it will validate and collect all error messages else it will get the first error and exit
 * Default is true
 */
$typeStruct->validateFull(false);
/**
 * Default is empty string, you can either pass 'json' or 'xml' based on the type of data you are passing for validation.
 */
$typeStruct->contentType('json');
/**
 * Absolute path to the typestruct file
 */
$typeStruct->setPath('/path/to/Sample.php');
/**
 * Full class name of typestruct file
 */
$typeStruct->setClass(App\TypeStruct\Simple::class);

3. Data

The data you can pass for validation are

Array
Object(stdClass)
Json
XML

As we have already seen the array example, lets see the examples for the rest

Object(stdClass)

$data        = new \stdClass();
$data->id    = 42;
$data->name  = 'amsify';
$data->price = 4.2;    

$typeStruct = new Amsify42\TypeStruct\TypeStruct();
$typeStruct->isDataObject(true)->setClass(App\TypeStruct\Simple::class);
$result = $typeStruct->validate($data);

Note: We are passing true to method isDataObject() to tell TypeStruct that the data we are passing is of type Object(stdClass).

Json

$jsonData = '{"id":42,"name":"amsify","price":4.2}';
$typeStruct = new TypeStruct();
$typeStruct->contentType('json')->setClass(App\TypeStruct\Simple::class);
$result = $typeStruct->validate($jsonData);

XML

$xmlData = '<?xml version="1.0" encoding="UTF-8" ?> <root> <id>42</id> <name>amsify</name> <price>4.2</price> </root>';
$typeStruct = new TypeStruct();
$typeStruct->contentType('xml')->setClass(App\TypeStruct\Simple::class);
$result = $typeStruct->validate($xmlData);

Note: We are calling contentType() method to set its type for both Json and XML.

4. Class Validation

We can do the validation by creating class and extending it to the Amsify42\TypeStruct\Validator

<?php

namespace App\Validators;

use Amsify42\TypeStruct\Validator;

class Sample extends Validator
{
    protected $tsClass = \App\TypeStruct\Simple::class;

    protected $data = [
                        'id'    => 42,
                        'name'  => 'amsify',
                        'price' => 4.2
                    ];                 
}

Since we already set TypeStruct class name and data in protected properties. We can create instance of this class directly and validate

$sample = new \Amsify42\Validators\Sample();
$result = $sample->validate();

You can also set the data before validating against the typestruct like this

$sample = new \Amsify42\Validators\Sample();
$sample->setData(['id' => 42, 'name' => 'amsify']);
$result = $sample->validate();

and we can also use these protected properties which extends Amsify42\TypeStruct\Validator

/**
 * Instead of setting typestruct class name, we can also set direct path of that typestruct file
 */
protected $tsPath;
/**
 * This will decide whether validation will stop at first error itself or when completing all validation errors. Default is true
 */
protected $validateFull;
/**
 * You can set to json or xml, default is empty string
 */
protected $contentType;
/**
 * Tells the typestruct whether the data we setting/passing is of type Object(stdClass)
 */
protected $isDataObject;

5. Rules

Basic

These are the basic types we can use for elements. It will check whether key exist and its type.

export typestruct Sample {
    id: int,
    name: string,
    price: float,
    points: numeric,
    is_active: boolean,
    is_public: tinyInt,
    items: array
    some: any
}

numeric work just like php is_numeric() method which allows numbers even in quotes. tinyInt expects the value to be either 0 or 1 and type any means that element value could be of any type.

Optional

To make the element optional, we simply prefix it with question mark ?

export typestruct Sample {
    id: int,
    name: string,
    email: ?string
}

Optional can also be applied to child dictionary

export typestruct Sample {
    id: int,
    name: string,
    email: ?string,
    details : ?{
        address: string,
        pincode: ?int
    }
}

Length

We can also set the limits to the length of these types like this

export typestruct Sample {
    id: int(5),
    name: string(20),
    price: float(5.2),
    is_active: boolean,
    items: [5]
}

Array

These are the array types we can use

items: int[] 
items: string[]
items: float[]
items: numeric[]
items: boolean[]
items: tinyInt[]

External as Child

We can also use the other external TypeStruct file as a element

namespace App\TypeStruct;
export typestruct Category {
    id: int,
    name: string
}

Now we can use Category as type like this

namespace App\TypeStruct;
use App\TypeStruct\Category;
export typestruct Product {
    id: int,
    name: string,
    price: float,
    active: boolean,
    category: Category
}

or as array of this type

namespace App\TypeStruct;
use App\TypeStruct\Category;
export typestruct Product {
    id: int,
    name: string,
    price: float,
    active: boolean,
    categories: Category[]
}

More Rules

You can also attach more rules to the input like this

namespace App\TypeStruct;
export typestruct User {
    id: int,
    name: string,
    email: string<email>
}

As you can see, we have added rule email to the email element which will check for valid email address. You can add more rules to the element separated by dot . like this

namespace App\TypeStruct;
export typestruct User {
    id: int,
    url: string<url.checkHost>
}

These are the pre defined rules you can use

nonEmpty - Check for non empty value just like php method empty() checks
email - Check for valid email
url - Check if string is a valid url
date - Check if string is a valid date

6. Custom Rules

We can also write method to perform cutom validation but this can only be achieved when we create class and extends it to Amsify42\TypeStruct\Validator

namespace App\TypeStruct;

export typestruct Simple {
    id: int,
    name: string<checkName>,
    price: float
}

Now we can write method checkName in our validator class like this

<?php

namespace App\Validators;

use Amsify42\TypeStruct\Validator;
use App\TypeStruct\Simple;

class Sample extends Validator
{
    protected $tsClass = Simple::class;

    protected $data = [
                        'id'    => 42,
                        'name'  => 'amsify',
                        'price' => 4.2
                    ];

    public function checkName()
    {
        if($this->value() !== 'amsify')
        {
            return 'Name should be amsify';
        }
        return true;
    }                                 
}

We can use $this->name() to get the name of current element and $this->value() to get the value of the current element which is applicable to the rule. To get the other element value, we already have $this->data accessible from these custom rule methods.
If you want to access data from custom method more easily, you can also use the method $this->path() which will directly get the element from multi level path.

class Sample extends Validator
{
    ...
    protected $data = [
                        'id'    => 42,
                        'detail' => [
                            'more' => [
                                'location' => 'City'
                            ]
                        ]
                    ];

    public function checkCustom()
    {
        echo $this->path('detail.more.location'); /* It will print `City` */
    }                                 
} 

Note: $this->path expects parameters to be key name separated by dot(if multiple keys) and will either return NULL(if key does not exist) or the target key value.

7. Complex Example

namespace App\TypeStruct;

use App\TypeStruct\User;

export typestruct Sample {
    name: string,
    email: string,
    is_test: tinyInt,
    id: int,
    address: {
        door: string,
        zip: int
    },
    items: [],
    user : User,
    someEl: {
        key1: string,
        key2: int,
        key12: array,
        records: \App\TypeStruct\Record[],
        someChild: {
            key3: boolean,
            key4: float,
            someAgainChild: {
                key5: string,
                key6: float,
                key56: boolean[]
            }
        }
    }
}
<?php

namespace App\TypeStruct;

export typestruct User {
    id: int,
    name: string,
    email: string<email>
}
<?php

namespace App\TypeStruct;

export typestruct Record {
    id: int,
    name: string
}

The above complex and multi level typestruct example file will be validated with the data:

[
    'name' => 'amsify',
    'is_test' => '1',
    'user' => [
        'id' => 1,
        'name' => 'some',
        'email' => 'some@site.com'
    ],
    'address' => [
        'door' => '12-3-534',
        'zip' => 600035
    ],
    'url' => 'https://www.site.com/page.html',
    'items' => [1,2,3,4,5,6,7],
    'someEl' => [
        'key1' => 'val1',
        'key2' => 2,
        'key12' => [1,2,12],
        'records' => [
            [
                'id' => 1,
                'name' => 'r1'
            ],
            [
                'id' => 2,
                'name' => 'r2'
            ]
        ],
        'someChild' => [
            'key3' => true,
            'key4' => 4.01,
            'someAgainChild' => [
                'key5' => 'val5',
                'key6' => 6.4,
                'key56' => [true,false,true]
            ]
        ]
    ]
]

amsify42/php-typestruct 适用场景与选型建议

amsify42/php-typestruct 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 34 次下载、GitHub Stars 达 1, 最近一次更新时间为 2020 年 03 月 30 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「validation」 「php validation」 「typestruct」 「php typestruct」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

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

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

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

BUG 修复 & 性能优化

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

项目外包 & 长期维护

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

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

统计信息

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

GitHub 信息

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

其他信息

  • 授权协议: MIT
  • 更新时间: 2020-03-30