{"id":18062834,"url":"https://github.com/chaz6chez/structure","last_synced_at":"2025-04-11T15:13:02.098Z","repository":{"id":47240284,"uuid":"147640182","full_name":"chaz6chez/structure","owner":"chaz6chez","description":"A simple validator","archived":false,"fork":false,"pushed_at":"2023-08-23T02:24:13.000Z","size":138,"stargazers_count":17,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"2.x","last_synced_at":"2025-03-25T11:21:36.547Z","etag":null,"topics":["php","slight","structure","validator"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/chaz6chez.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-09-06T08:12:43.000Z","updated_at":"2025-03-05T14:12:22.000Z","dependencies_parsed_at":"2022-08-24T08:31:13.224Z","dependency_job_id":null,"html_url":"https://github.com/chaz6chez/structure","commit_stats":null,"previous_names":[],"tags_count":18,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chaz6chez%2Fstructure","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chaz6chez%2Fstructure/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chaz6chez%2Fstructure/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chaz6chez%2Fstructure/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chaz6chez","download_url":"https://codeload.github.com/chaz6chez/structure/tar.gz/refs/heads/2.x","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248429119,"owners_count":21101785,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["php","slight","structure","validator"],"created_at":"2024-10-31T05:08:36.994Z","updated_at":"2025-04-11T15:13:02.072Z","avatar_url":"https://github.com/chaz6chez.png","language":"PHP","readme":"# Structure - 2.0.0\n\n**A useless validator**\n****\nIf you have any good suggestions and \ncomments, please contact **chaz6chez1993@outlook.com**\n***\n\n## 应用场景\n\n - 出入参的判断及过滤\n - 数据转化及映射\n\n## 示例\n\n### 验证场景\n\n- 创建一个Structure\n\n````php\nnamespace YoursNamespace;\nuse Structure\\Struct;\nclass User extends Struct {\n\n    // 当id为非null值时，必须满足int 10 \u003c id \u003c 20\n    /**\n     * @rule int,min:10,max:20|id format error:1001\n     */\n    public $id; \n    \n    // name为必填，必须满足string 1 \u003c name长度 \u003c 20\n    /**\n     * @rule string,min:1,max:20|name format error:2001\n     * @required true|name cannot be empty:2002 \n     */\n    public $name;\n    \n    // 当sex为null时默认 string female\n    // 满足string 0 \u003c sex长度 \u003c 10\n    /**\n     * @rule string,min:0,max:10|sex format error:1001\n     * @default string:female\n     */\n    public $sex;\n}\n````\n\n- 使用\n\n````php\n    $struct = \\YoursNamespace\\User::factory();\n    $struct-\u003ecreate([\n        'id' =\u003e 12,\n        'name' =\u003e 'John Smith'\n    ]);\n    \n    // or\n    \n    $struct = \\YoursNamespace\\User::factory([\n        'id' =\u003e 12,\n        'name' =\u003e 'John Smith'\n    ]);\n    \n    // or\n    \n    $struct = new \\YoursNamespace\\User();\n    $struct = \\YoursNamespace\\User::factory();\n    \n    $struct-\u003eid = 12;\n    $struct-\u003ename = 'John Smith';\n    \n    // or\n    \n    $struct = new \\YoursNamespace\\User([\n        'id' =\u003e 12,\n        'name' =\u003e 'John Smith'\n    ]);\n    \n\n    if($struct-\u003ehasError()) {\n        throw new \\RuntimeException(\n            $struct-\u003egetError()-\u003egetMessage() . '-\u003e' . $struct-\u003egetError()-\u003egetPosition(),\n            $struct-\u003egetError()-\u003egetCode()\n        );\n    }\n    return $struct-\u003eoutput(); // array\n````\n\n \n## 使用说明\n\n- 继承 Structure\\Struct 及实现结构体\n- public属性接参\n\n````php\nnamespace Example;\n\nuse Structure\\Struct;\n\nclass User extends Struct{\n    public $id;\n    public $name;\n    public $sex;\n}\n````\n\n- 对要操作和转化的public属性进行注释\n\n````php\n\n    /**\n     * @rule string,min:10,max:20|name format error:1001 \n     */\n    public $name;\n````\n\n- 标签分为四个区域\n   - \u003ca href=\"#标签区\"\u003ea区：标签区\u003c/a\u003e\n   - b区：场景区\n   - c区：验证区\n   - d区：内容信息\n```php\n/**\n *  a区   b区        c区              d区\n * @标签 [场景]   验证方式   | 错误信息     : 错误码\n *      ↓           ↓           ↓             ↓\n * @rule[check] string,min:1|error message:error code  \n */                       \n````\n\n***\n## \u003ca id=\"标签区\"\u003e标签区\u003c/a\u003e：\n\n- **转换类的标签配合 filter()在output() 方法内生效，\n  会对包含该标签的属性执行转换或者过滤操作**\n  \n\n- **验证类的标签在 validate() 中生效返回布尔值，\n  通过getError() 可以获得错误信息**\n\n|标签名|方式|类型|说明|\n| :---: | :---:|:-----:| :--- |\n| \u003ca href=\"#@default\"\u003e@default\u003c/a\u003e | Structure\\Handler、func、method | 转换 | func与method是将返回值默认赋予该标签 |\n| \u003ca href=\"#@required\"\u003e@required\u003c/a\u003e| true |验证| 判断是否为必要值 |\n| \u003ca href=\"#@rule\"\u003e@rule\u003c/a\u003e | Structure\\Handler、func、method |验证| 以func与method的bool返回类型判断验证 |\n| \u003ca href=\"#@skip\"\u003e@skip\u003c/a\u003e | 无 |验证| 跳过验证 |\n| \u003ca href=\"#@ghost\"\u003e@ghost\u003c/a\u003e| 无 |转换| 跳过输出 |\n| \u003ca href=\"#@key\"\u003e@key\u003c/a\u003e| 无 |转换| 标记钥匙属性|\n| \u003ca href=\"#@mapping\"\u003e@mapping\u003c/a\u003e| 映射键名 |转换| 映射键转换 |\n| \u003ca href=\"#@operator\"\u003e@operator\u003c/a\u003e| true、func、method |转换| 键值特殊转换 |\n\n### \u003ca id=\"@default\"\u003e@default\u003c/a\u003e\n- 将该属性标记默认模式\n- 当该属性值为null且具备@default标签时生效\n\n````php\n    /**\n     * @default string:abc\n     * @default int:123\n     * @default float:1.1\n     * @default object:Handler\\Help\n     * @default map:{\"a\":\"1\"}\n     * @default array:[\"1\"]\n     * @default bool:true\n     */\n    public $name;\n````\n\n- 验证区可使用func、method进行方法赋值\n  - **method:className,methodName 必须是静态方法**\n  - **方法执行过程中抛出的任何异常都会被忽略，并以默认Null赋值**\n\n````php\n    /**\n     * @default func:is_array              会找到is_array函数\n     * @default method:_set                会定位当前类的_set方法\n     * @default method:Handler\\Help,get   会定位Handler\\Help类的get方法 \n     */\n    public $name;\n    public static function _set(){\n        return 'abc';\n    }\n````\n\n- **@default仅在output()输出时生效，若要直接使用类属性获取@default赋值，请使用以下方法：**\n- **但不建议频繁使用，会多执行一次object clone操作**\n\n```php\n    // 以name的@default标签为string:John举例\n    /**\n     * @default string:John\n     */\n    public $name;\n ```\n\n```php \n    $struct = new Struct();\n    // @default无法生效，值为null\n    $struct-\u003ename;\n    \n    // @default可以生效，值为字符串John\n    $struct()-\u003ename;\n```\n\n### \u003ca id=\"@required\"\u003e@required\u003c/a\u003e\n\n````php\n    /**\n     * @required true|name cannot empty\n     */\n    public $name;\n````\n\n### \u003ca id=\"@rule\"\u003e@rule\u003c/a\u003e\n\n- 通过预置Handler进行验证\n\n````php\n    /**\n     * @rule string,min:10,max:20|name format error\n     * @rule int,min:10,max:20|name format error\n     * @rule float,min:1.0,max:2.1,scale:3|name format error\n     * @rule bool,true|name format error\n     * @rule object,class:|name format error\n     * @rule array,min:10,max:20,values:string|name format error\n     * @rule map,min:1,max:5,keys:string,values:int|name format error\n     * @rule url,path:true,query:true|name format error\n     * @rule ip,ipv4:false,ipv6:false,private:false,reserved:false|name format error\n     * @rule regex,min:10,max:20,regex:/.?/|name format error\n     */\n    public $name;\n````\n\n- 验证区可使用func、method进行方法判断\n  - **method:className,methodName 必须是静态方法**\n  - **方法执行过程中任何异常会转化成StructureException抛出**\n\n````php\n    /**\n     * @rule func:_set                  会找到_set函数\n     * @rule method:_set                会定位当前类的_set方法\n     * @rule method:Handler\\Help,get   会定位Handler\\Help类的get方法\n     */\n    public $name;\n    \n    public static function _set($value) : bool\n    {\n        return $value === '_method';\n    }\n}\n\n\nfunction _set($value) : bool\n{\n    return $value === '_func';\n}\n````\n### \u003ca id=\"@ghost\"\u003e@ghost\u003c/a\u003e\n- \u003ca href=\"#输出\"\u003eoutput()\u003c/a\u003e 不会输出该标签\n\n````php\n    // @ghost true\n    $user-\u003eid = 'id';\n\n    $user-\u003ename = 'name';\n    $user-\u003eoutput();\n    // 以上会输出\n    [\n        'name' =\u003e 'name'\n    ];\n\n    $user-\u003eoutput(true);\n    // 以上会输出\n    [\n        'id' =\u003e 'id',\n        'name' =\u003e 'name'\n    ];\n````\n\n### \u003ca id=\"@key\"\u003e@key\u003c/a\u003e\n- 将该属性标记钥匙字段\n- 通过 \u003ca href=\"#过滤\"\u003efilter()\u003c/a\u003e-\u003e\u003ca href=\"#输出\"\u003eoutput()\u003c/a\u003e 可以做到仅输出钥匙字段\n\n````php\n    // @key true\n    $user-\u003eid = 'id';\n\n    $user-\u003ename = 'name';\n    $user-\u003efilter(STRUCT_FILTER_KEY)-\u003eoutput();\n    // 以上会输出\n    [\n        'name' =\u003e 'name'\n    ];\n    \n    $user-\u003etransfer(STRUCT_FILTER_KEY_REVERSE)-\u003eoutput();\n    // 以上会输出\n    [\n        'id' =\u003e 'id',\n    ];\n````\n\n### \u003ca id=\"@skip\"\u003e@skip\u003c/a\u003e\n- 跳过验证，但不影响输出\n\n### \u003ca id=\"@operator\"\u003e@operator\u003c/a\u003e\n\n#### 1. 识别[medoo语法-where](https://medoo.in/api/where) 并转换 \n````php\n    /**\n     * @operator true \n     */ \n    public $name;\n````\n\n通过 \u003ca href=\"#转换\"\u003etransfer()\u003c/a\u003e-\u003e\u003ca href=\"#输出\"\u003eoutput()\u003c/a\u003e 可以做到转换输出\n\n````php\n    // @operator true\n    $user-\u003eid = 'abc[\u003e]';\n    $user-\u003etransfer(STRUCT_TRANSFER_OPERATOR)-\u003eoutput();\n    // 以上会输出\n    [\n        'id[\u003e]' =\u003e 'abc'\n    ];\n\n    $user-\u003eid = '123,456[\u003c\u003e]';\n    $user-\u003etransfer(STRUCT_TRANSFER_OPERATOR)-\u003eoutput();\n    // 以上会输出\n    [\n        'id[\u003c\u003e]' =\u003e ['123','456'],\n    ];\n````\n\n    2.2以上版本完善了该标签下的类型转换\n    2.2以下版本中不会对类型转换\n##### 2.2以下版本：\n````php\n    // @operator true\n    $user-\u003eid = '123[\u003e]';\n    $user-\u003etransfer(STRUCT_TRANSFER_OPERATOR)-\u003eoutput();\n    // 以上会输出\n    [\n        'id[\u003e]' =\u003e '123'\n    ];\n    // 并非期待的\n    [\n       'id[\u003e]' =\u003e 123\n    ];\n    // 此种状况会影响数据库查询的索引\n````\n##### 2.2以上版本：\n\n- 不仅可以配合medoo语法做处理转换，也可以直接做类型转换\n- 字符串类型的数字默认会根据值类型转换\n  - 整型内容字符串转换成整型\n  - 小数字符串转换成浮点型\n\n````php\n    // @operator true\n    $user-\u003eid = '123[\u003e]';\n    $user-\u003etransfer(STRUCT_TRANSFER_OPERATOR)-\u003eoutput();\n    // 以上会输出 int\n    [\n        'id[\u003e]' =\u003e 123\n    ];\n    \n    // @operator true\n    $user-\u003eid = '123';\n    $user-\u003etransfer(STRUCT_TRANSFER_OPERATOR)-\u003eoutput();\n    // 以上会输出 int\n    [\n        'id' =\u003e 123\n    ];\n    \n    $user-\u003eid = '1.23[\u003e]';\n    $user-\u003etransfer(STRUCT_TRANSFER_OPERATOR)-\u003eoutput();\n    // 以上会输出 float\n    [\n        'id[\u003e]' =\u003e 1.23\n    ];\n\n    $user-\u003eid = '1.23';\n    $user-\u003etransfer(STRUCT_TRANSFER_OPERATOR)-\u003eoutput();\n    // 以上会输出\n    [\n        'id' =\u003e 1.23\n    ];\n````\n\n- 可以使用强制转换标签\n\n\n````php\n\n# String :\n\n    // @operator true\n    $user-\u003eid = '123[String][\u003e]';\n    $user-\u003etransfer(STRUCT_TRANSFER_OPERATOR)-\u003eoutput();\n    // 以上会输出 int\n    [\n        'id[\u003e]' =\u003e '123'\n    ];\n    \n    // @operator true\n    $user-\u003eid = '123[String]';\n    $user-\u003etransfer(STRUCT_TRANSFER_OPERATOR)-\u003eoutput();\n    // 以上会输出 int\n    [\n        'id' =\u003e '123'\n    ];\n\n# Int ：\n\n    // @operator true\n    $user-\u003eid = '1[Int][\u003e]';\n    $user-\u003etransfer(STRUCT_TRANSFER_OPERATOR)-\u003eoutput();\n    // 以上会输出 int\n    [\n        'id[\u003e]' =\u003e 1\n    ];\n    \n    // @operator true\n    $user-\u003eid = '1[Int]';\n    $user-\u003etransfer(STRUCT_TRANSFER_OPERATOR)-\u003eoutput();\n    // 以上会输出 int\n    [\n        'id' =\u003e 1\n    ];\n\n\n# Float ：\n\n    // @operator true\n    $user-\u003eid = '123[Float][\u003e]';\n    $user-\u003etransfer(STRUCT_TRANSFER_OPERATOR)-\u003eoutput();\n    // 以上会输出 int\n    [\n        'id[\u003e]' =\u003e 123.0\n    ];\n    \n    // @operator true\n    $user-\u003eid = '123[Float]';\n    $user-\u003etransfer(STRUCT_TRANSFER_OPERATOR)-\u003eoutput();\n    // 以上会输出 int\n    [\n        'id' =\u003e 123.0\n    ];\n\n# Bool ：\n\n    // @operator true\n    $user-\u003eid = '1[Bool][\u003e]'; // 0 false\n    $user-\u003etransfer(STRUCT_TRANSFER_OPERATOR)-\u003eoutput();\n    // 以上会输出 int\n    [\n        'id[\u003e]' =\u003e true\n    ];\n    \n    // @operator true\n    $user-\u003eid = '1[Bool]'; // 0 false\n    $user-\u003etransfer(STRUCT_TRANSFER_OPERATOR)-\u003eoutput();\n    // 以上会输出 int\n    [\n        'id' =\u003e true\n    ];\n````  \n\n\n\n\n\n#### 2.使用func、method进行转换\n  - **method:className,methodName 必须是静态方法**\n  - **方法执行过程中任何异常会转化成StructureException抛出**\n\n````php\n\n    /**\n     * @operator func:_add                  相当于_add($name)\n     * @operator method:_add                相当于$this-\u003e_add($name)\n     * @operator method:Handler\\Help,_add  相当于Handler\\Help::_add($name)\n     */\n    public $name;\n````\n\n\n### \u003ca id=\"@mapping\"\u003e@mapping\u003c/a\u003e\n- 将该属性标记映射处理\n- 通过 \u003ca href=\"#转换\"\u003etransfer()\u003c/a\u003e-\u003e\u003ca href=\"#输出\"\u003eoutput()\u003c/a\u003e 可以做到转换输出\n\n````php\n    // @mapping key\n    $user-\u003eid = 123;\n\n    $user-\u003ename = 'john';\n    $user-\u003eoutput();\n    // 输出\n    [\n        'id' =\u003e 123,\n        'name' =\u003e 'john'\n    ];\n\n    $user-\u003etransfer(STRUCT_TRANSFER_MAPPING)-\u003eoutput();\n    // 输出\n    [\n        'key' =\u003e 123,\n        'name' =\u003e 'john'\n    ];\n````\n\n***\n## 方法\n\n- 实例化\n\n````php\n    $user = User::factory([\n        'id' =\u003e 1,\n        'name' =\u003e 'john'\n    ],'check');\n````\n\n- 输入\n\n  - 使用create方法输入数据\n  - 使用属性赋值输入数据\n  - **使用create可以保存\u003ca href=\"#获取原始数据\"\u003e原始数据\u003c/a\u003e，使用属性赋值则不会保留原始数据**\n  \n````php\n    // 1.使用create输入数据\n    $user-\u003ecreate([\n        'id' =\u003e 1,\n        'name' =\u003e 'john'\n    ]); // return $this\n````\n\n````php\n    // 2.使用属性赋值输入数据\n    $user-\u003eid = 1;\n    $user-\u003ename = 'john';\n\n    // 使用create可以保存原始数据，建议使用create输入数据\n````\n\n- \u003ca id=\"获取原始数据\"\u003e获取原始数据\u003c/a\u003e\n\n````php\n    $user-\u003egetRaw(); // return array\n````\n\n- 设置场景\n\n````php\n    $user-\u003escene('check'); // return $this\n````\n\n- \u003ca id=\"转换\"\u003e转换\u003c/a\u003e\n\n  - STRUCT_TRANSFER_MAPPING\n  - STRUCT_TRANSFER_OPERATOR\n\n````php\n    $user-\u003etransfer(STRUCT_TRANSFER_MAPPING); // return $this\n\n    // STRUCT_TRANSFER_MAPPING\n    // STRUCT_TRANSFER_OPERATOR\n\n    // 接受可变长参数\n    $user-\u003etransfer(\n        STRUCT_TRANSFER_MAPPING,\n        STRUCT_TRANSFER_OPERATOR\n    ); // return $this\n````\n\n- \u003ca id=\"过滤\"\u003e过滤\u003c/a\u003e\n  - STRUCT_FILTER_NULL\n  - STRUCT_FILTER_EMPTY\n  - STRUCT_FILTER_ZERO\n  - STRUCT_FILTER_KEY\n  - STRUCT_FILTER_KEY_REVERSE\n  - STRUCT_FILTER_OPERATOR\n  - STRUCT_FILTER_OPERATOR_REVERSE\n\n````php\n    $user-\u003efilter(STRUCT_FILTER_NULL); // return $this\n\n    // STRUCT_FILTER_NULL\n    // STRUCT_FILTER_EMPTY\n    // STRUCT_FILTER_ZERO\n    // STRUCT_FILTER_KEY\n    // STRUCT_FILTER_KEY_REVERSE\n    // STRUCT_FILTER_OPERATOR\n    // STRUCT_FILTER_OPERATOR_REVERSE\n\n    // 接受可变长参数\n    $user-\u003efilter(\n        STRUCT_FILTER_NULL,\n        STRUCT_FILTER_EMPTY\n    ); // return $this\n````\n\n- \u003ca id=\"验证\"\u003e验证\u003c/a\u003e\n\n````php\n    $user-\u003evalidate(); // return bool\n    $user-\u003ehasError(); // return bool\n\n    // true 有错误，验证未通过\n    // false 无错误，验证通过\n````\n\n- 获取错误\n\n  - 需要在\u003ca href=\"#验证\"\u003e验证\u003c/a\u003e执行后才能获取错误信息\n\n````php\n    $user-\u003egetError(); // return Structure\\Error\n\n    $user-\u003egetError()-\u003egetMessage();  // 错误信息 string\n    $user-\u003egetError()-\u003egetCode();     // 错误码 string\n    $user-\u003egetError()-\u003egetField();    // 字段名 string\n    $user-\u003egetError()-\u003egetPosition(); // 错误定位 对应Handler对应的options字段\n\n    $user-\u003egetErrors(); // return Structure\\Error[]\n\n````\n\n- \u003ca id=\"输出\"\u003e输出\u003c/a\u003e\n  \n  - 全量输出会进行\u003ca href=\"#转换\"\u003e转换\u003c/a\u003e和default赋值\n  - 全量输出不进行\u003ca href=\"#过滤\"\u003e过滤\u003c/a\u003e\n\n````php\n    $user-\u003eoutput(); // return array\n\n    $user-\u003eoutput(true); // 全量输出\n````\n\n- 清洗\n\n````php\n    $user-\u003eclean(); // 默认不装载raw数据\n\n    $user-\u003eclean(true); // 装载raw数据\n````\n\n## 补充\n\n- Handler 接受自定义注册\n\n````php\n    \\Structure\\Handler::register();\n````\n\n- StructureException\n\n````php\n    try {\n        // ...                          \n    }catch (\\Structure\\Exceptions\\StructureException $exception){\n        $exception-\u003egetPosition(); // 错误定位信息\n        $exception-\u003egetMessage(); // Structure Exception [{position info}]\n        $exception-\u003egetCode(); // 始终以-666返回\n    }\n````\n\n\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchaz6chez%2Fstructure","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchaz6chez%2Fstructure","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchaz6chez%2Fstructure/lists"}