surgiie / 转换器
一个用于PHP的数据转换/格式化包。
Requires
- php: ^8.2.0
- illuminate/http: ^9.0|^10.0|^11.0
- illuminate/support: ^9.0|^10.0|^11.0
- illuminate/validation: ^9.0|^10.0|^11.0
Requires (Dev)
- laravel/pint: ^1.16
- pestphp/pest: ^2.34
- symfony/var-dumper: ^7.0
This package is auto-updated.
Last update: 2024-09-27 18:01:54 UTC
README
转换器是一个PHP包,用于转换值或输入,由Laravel框架的验证组件提供支持。
安装
composer require surgiie/transformer
使用
要使用此包,请传递您的数据和应通过的数据的可调用函数数组
<?php use Closure; use Illuminate\Support\Stringable; // Example functions available at runtime: function to_carbon($value) { return new Carbon\Carbon($value); } function only_numbers($value) { return preg_replace("/[^0-9]/",'',$value); } $input = [ 'first_name'=>' jim ', 'last_name'=>' thompson', 'address' => '123 some street', 'phone_number'=>'123-456-7890', 'date_of_birth'=>"1991-05-01", ]; $transformers = [ 'first_name'=>'trim|ucfirst', 'last_name'=>'trim|ucfirst', 'phone_number'=>'only_numbers', // more on object values and method delegation below 'address' => [Stringable::class, '->after:123 ', '->toString'], 'date_of_birth'=>'to_carbon|->format:m/d/y', ]; $transformer = new DataTransformer($input, $transformers); $newData = $transformer->transform(); // Returns: // [ // "first_name" => "Jim", // "last_name" => "Thompson", // "phone_number" => "1234567890", // "address"=> "some street", // "date_of_birth" => "05/01/91", // ]
注意,语法类似于Laravel验证语法,因为此包由相同的组件提供支持。
传递参数
您可以使用 <function>:<comma-delimited-list>
语法为您的函数指定参数
<?php $transformers = [ 'example'=>'your_function:arg1,arg2', ];
指定值参数顺序
默认情况下,传递给您的函数的第一个参数将是正在格式化的值,然后是按提供的顺序指定的参数。如果您的函数不接受值作为第一个参数,您可以使用 :value:
占位符来指定顺序。例如
<?php $input = ['phone_number'=>'123-456-3235']; $transformers = [ 'example'=>'preg_replace:/[^0-9]/,,:value:', ]; $transformer = new DataTransformer($input, $transformers); $transformer->transform();
转换参数
您可能会发现,在将参数传递给转换函数时,由于基本类型参数的类型提示,可能会遇到运行时错误。由于此处参数被指定为字符串,您可能会遇到以下情况
<?php function example_function(int $value){ return $value + 1; } $input = ['example'=>"1"]; $transformers = [ 'example'=>'example_function:1', ];
上述代码会抛出错误,因为传递的 1
参数是一个字符串,而函数期望一个整数。在这些情况下,您可以使用以下约定将参数转换为目标原生类型,通过在值后附加 @<type>
来完成。例如,将 1
转换为整数
<?php function example_function(int $value){ return $value + 1; } $input = ['example'=>"1"]; $transformers = [ 'example'=>'example_function:1@int', // "1" will be casted to an int. ];
可用的转换类型
以下是一些基本转换类型:
- int
- str
- float
- bool
- array
- object
注意 对于更复杂类型或转换需求,请使用以下文档中所述的闭包或 Surgiie\Transformer\Contracts\Transformable
类。
可选转换
如果您只想在值不为null或"空"时进行转换,您可以在函数链中使用 ?
字符来指定何时退出处理。这通常放在链的开始处
<?php $input = ['first_name'=>null]; $transformers = [ 'example'=>'?|function_one|function_two', ]; $transformer = new DataTransformer($input, $transformers); $transformer->transform();
注意:此包使用Laravel的 blank
助手确定空白/空值。如果您有更复杂的退出规则逻辑,可以使用闭包或 \Surgiie\Transformer\Contracts\Transformable
类,并调用第二个参数的退出回调。
闭包和Transformable类
您可以使用闭包来转换您的值
<?php $input = ['first_name'=>' Bob']; $transformers = [ 'first_name'=>['trim', function ($value) { // modify the value return $value; }], ]; $transformer = new DataTransformer($input, $transformers); $transformer->transform();
或者,您可以实现 Surgiie\Transformer\Contracts\Transformable
协议,并使用类实例
<?php use Surgiie\Transformer\DataTransformer; use Surgiie\Transformer\Contracts\Transformable; class TransformValue implements Transformable { public function transform($value, Closure $exit) { // quit transforming value(s) if($someCondition){ $exit(); } // or modify the value $value = "Changed"; return $value; } } $input = ['first_name' => ' Bob']; $transformers = [ 'first_name' => ['trim', new TransformValue], ]; $transformer = new DataTransformer($input, $transformers); $transformer->transform();
数组输入
您还可以使用点表示法格式化嵌套数组数据
<?php $input = [ 'contact_info'=>[ 'first_name'=>' jim ', 'last_name'=>' thompson', 'phone_number'=>'123-456-7890', 'address'=>'123 some lane.' ] ]; $transformers = [ 'contact_info.first_name'=>'trim|ucwords', 'contact_info.last_name'=>'trim|ucwords', 'contact_info.phone_number'=>'preg_replace:/[^0-9]/,,:value:', 'contact_info.address'=>[function ($address) { return 'Address Is: '.$address; }], ]; $transformer = new DataTransformer($input, $transformers); $transformer->transform();
通配符
您还可以在键上使用通配符来应用匹配通配符模式的转换器
<?php $input = [ 'first_name'=>' jim ', 'last_name'=>' thompson', 'ignored'=>' i-will-be-the-same' ]; $transformers = [ // apply to all keys that contain "name" '*name*'=>'trim|ucwords', ]; $transformer = new DataTransformer($input, $transformers); $transformer->transform();
对象值/方法委派
如果值已转换为实例,则可以将函数调用委派给对象。使用 -><methodName>:args
语法,您可以在该实例上指定方法链
<?php use Closure; class Example { protected $value; public function __construct($value) { $this->value = $value; } public function concat($string) { return $this->value . $string; } } function example($value) { return new Example($value); } $input = [ 'string'=>"Foo", ]; $transformers = [ 'string'=>'example|->concat:Bar', ];
您还可以使用接受单个值作为构造函数参数的类常量,例如
<?php $input = [ 'string'=>"Foo", ]; $transformers = [ 'string'=>[Example::class, '->concat:Bar'], ];
执行前保护层
默认情况下,所有在运行时可以调用的函数都将被执行。但是,如果您想添加一个保护或安全层,以阻止某些方法被调用,您可以通过返回 true 来添加一个守卫回调,检查方法是否应该被调用。
<?php use Surgiie\Transformer\DataTransformer; use Surgiie\Transformer\Transformer; // accepts the function name being executed and the key/name of the input being processed: Transformer::guard(function($method, $key){ // only "trim" is allowed to be executed return in_array($method, ['trim']); }); $input = [ 'first_name'=>' jim ', ]; $transformers = [ 'first_name'=>'trim|ucwords', ]; $transformer = new DataTransformer($input, $transformers); // throws a Surgiie\Transformer\Exceptions\ExecutionNotAllowedException once it gets to ucwords due to the guard method. $transformer->transform();
手动转换值/单个值
要格式化单个值,请使用 Transformer 类。
<?php use Surgiie\Transformer\Transformer; $transformer = new Transformer(" uncle bob ", ['trim', 'ucwords']); $transformer->transform(); // returns "Uncle Bob"
使用特性
要在类中即时转换数据和值,请使用 \Surgiie\Transformer\Concerns\UsesTransformer
特性。
<?php use App\Http\Controllers\Controller; use Illuminate\Http\Request; use Surgiie\Transformer\Concerns\UsesTransformer; class ExampleController extends Controller { use UsesTransfomer; public function store(Request $request) { //... // transform a single value $newValue = $this->transform(" example ", ['trim|ucwords']); // or transform an array of data $newData = $this->transformData(['example'=> 'data '], ["example"=>'trim|ucwords']); } }
使用请求宏
要在 Illuminate\Http\Request
对象实例上使用宏转换数据,请在请求上调用 transform()
方法,该方法返回转换后的数据。
public function store(Request $request) { // Using data from the request object (i.e. `$request->all()`) $transformedData = $request->transform([ 'first_name' => ['strtoupper'], ]); // $transformedData['first_name'] will be all uppercase // all other data will be included from the request // You can also customize the input that is transformed, // in this case $transformedData will only have the `first_name` key. $transformedData = $request->transform($request->only(['first_name']), [ 'first_name' => ['strtoupper'], ]); }
在调用 FormRequest
对象时,它使用 validated()
函数来检索输入数据。请注意,这要求您要针对的数据在表单请求的规则函数中定义为验证规则,否则数据将不会进行转换。
包发现/不发现
Laravel 会自动注册包服务提供者,但如果您不希望这样做,您可以通过在 composer.json
中包含以下内容来忽略服务提供者的包发现:
"extra": { "laravel": { "dont-discover": [ "surgiie/transformer" ] } }
贡献
以下方式始终欢迎贡献:
- 讨论
- 问题跟踪器
- 拉取请求