ylsideas/forecaster

PHP中操作和转换关联数组的库

v1.2.0 2018-10-27 16:48 UTC

This package is auto-updated.

Last update: 2024-08-28 06:07:05 UTC


README

Forecaster是一个用于在PHP中操作和转换关联数组的库。

虽然该项目使用了在Laravel中找到的类和辅助工具,但它也可以用于非Laravel项目,因为它只依赖于Tighten Co的Collect包而不是Laravel支持包,这意味着它与任何框架或独立项目都兼容。

安装

Forecaster与PHP 7.1及更高版本兼容并经过测试。

应该使用以下命令通过composer安装此包

composer require ylsideas/forecaster

使用方法

您可以使用Forecaster处理具有类型转换和数组位置的数组。例如,以下所有基本类型都包括在内:intintegerfloatdoublerealstringbooleanbool。您还可以忽略数据类型参数,这样就不会进行类型转换,但键仍然会被包含。

$result = forecast([
    'a-string-int' => '10',
    'a-string-float' => '1.5',
    'an-int' => 10,
    'another-int' => 1,
    'do-not-touch' => '11'
])
    ->cast('a-string-int', 'anInt', 'int')
    ->cast('a-string-float', 'aFloat', 'float')
    ->cast('an-int', 'aString', 'string')
    ->cast('another-int', 'aBoolean', 'bool')
    ->cast('do-not-touch', 'doNotTouch')
    ->get();

// $results to

[
    'anInt' => 10,
    'aFloat' => 1.5,
    'aString' => '10',
    'aBoolean' => true,
    'doNotTouch' => '11',
]   

Forecaster还可以使用点符号处理更复杂的数组结构。

$result = forecast([
    'onions' => [
        'have' => [
            'layers' => true,
        ]
    ]
])
    ->cast('onions.have.layers', 'ogres.do.to')
    ->get();
    
// results to

[
    'orgres' => [
        'do' => [
            'to' => true,
        ]
    ]
]               

一个很好的功能是可以使用castAll方法转换数组中的所有值。甚至还有使用通配符进行此操作的选择。

$result = forecast([
    'anArrayOfStrings' => [
        '10', '100', '1000'
    ],
    'anArrayOfArrays' => [
        ['value' => '20'],
        ['value' => '200'],
        ['value' => '2000'],
    ]
])
    ->castAll('anArrayOfStrings', 'an-array-of-ints')
    ->castAll('anArrayOfArrays.*.value', 'an-array-of-all-values')
    ->get();
    
// results to

[
    'an-array-of-ints' => [
        10, 100, 1000
    ],
    'an-array-of-all-values' => [
        20, 200, 2000
    ],
]               

您不仅可以使用数组,还可以使用对象或对象和数组的组合,使用相同的点符号。

$object = new stdClass();
$object->objField = [
    'arrField' => '10',
];

$result = forecast($object)
    ->cast('objField.arrField', 'my_field', 'int')
    ->get();
    
// results to

[
    'my_field' => 10,
]               

使用castItems方法操作子数组相对简单

$result = forecast([
    'an-array' => [
        ['attr' => '10'],
        ['attr' => '100'],
        ['attr' => '1000'],
    ]
])
    ->castItems('an-array', 'anArray', function (Forecaster $forecaster) {
        $forecaster->cast('attr', 'Attribute', 'int');
    })
    ->get();
    
// results to

[
    'anArray' => [
        ['Attribute' => 10],
        ['Attribute' => 100],
        ['Attribute' => 1000],
    ]
]    

添加自己的固定转换器

您可以将自己的转换器应用于Forecaster类静态地,使其对所有创建的实例都可用。

Forecaster::transformer('csv', function ($value) {
    return str_getcsv($value);
});

$results = forecast([
    'test' => '1, 2, 3',
])
    ->cast('test', 'output', 'csv')
    ->get();
    
// results to

[
    'output' => ['1', '2', '3']
]

使用函数进行即时转换

$results = forecast([
    'test' => '1, 2, 3',
])
    ->cast('test', 'output', function ($value) {
        return str_getcsv($value);
    })
    ->get();
    
// results to

[
    'output' => ['1', '2', '3']
]

使用类进行更复杂的转换

如果您需要执行更复杂的逻辑并希望重用,可以定义转换器。

public class CsvTransformer implements CastingTransformer
{
    public function cast(string $in, string $out, array $item, array $processed)
    {
        return str_getcsv($item[$in]);
    }
}

然后在使用forecast时应用它们。

$results = forecast([
    'test' => '1, 2, 3',
])
    ->cast('test', 'output', new CsvTransformer())
    ->get();
    
// results to

[
    'output' => ['1', '2', '3']
]

条件转换

有时您可能只想在特定条件满足时执行某些转换。Forecaster为此提供了一个函数,该函数仅在条件为真时(例如,== true)执行。

$processed = Forecaster::make([
    'test' => '10',
])
    ->when(true, function (Forecaster $caster) {
        $caster->cast('test', 'output', 'int');
    })
    ->get();
    
// results to

[
    'output' => 10, 
]    

您还可以使用函数解决条件。

$processed = Forecaster::make([
    'test' => '10',
])
    ->when(
        function ($item) {
            return $item['test'] > 1;
        }, 
        function (Forecaster $caster) {
            $caster->cast('test', 'output', 'int');
        }
    )
    ->get();
    
// results to

[
    'output' => 10, 
]    

转换为对象

如果您希望将结果转换为所选的对象,可以在get方法中提供类字符串。

$results = forecast([
    'test' => '10',
])
    ->cast('test', 'output')
    ->get(SomeClass::class);

您还可以提供字符串object作为参数,这将指示forecaster实例将数组转换为stdObj对象。

$object = forecast([
    'test' => '10',
])
    ->cast('test', 'output')
    ->get('object');

还有选项使用函数解决。

$results = forecast([
    'test' => '10',
])
    ->cast('test', 'output')
    ->get(function ($processed) {
        return new SomeClass($processed['output']);
    });

与Laravel/Tighten Collections一起使用

如果您有一个想要转换的数组,它已经在Laravel/Tighten Collection类中,则有一个宏可用于无缝完成此操作。

$collection = collect([
    ['test' => '123.456'],
    ['test' => '789.101112']
])
    ->forecast(function (Forecaster $forecast) {
        $forecast->cast('test', 'output', 'float');
    })
    ->toArray();
    
// results to

[
    ['output' => 123.456],
    ['output' => 789.101112],
]

此宏还允许您指定预测结果,如果您希望将它们转换为特定类或stdObject。

$collection = collect([
    ['test' => '123.456'],
    ['test' => '789.101112']
])
    ->forecast(
        function (Forecaster $forecast) {
            $forecast->cast('test', 'output', 'float');
        }, 
        'object'
    );

常见问题解答

为什么没有日期时间转换器?

目前我们认为这应该由用户来实现,而不是库的一部分,因为一些开发者只使用datetime,而其他开发者会使用像Carbon或Chronos这样的附加包。我们对这个想法持开放态度,因为它是有意义的。我们只是不想在早期提出需要破坏性更改的东西。

测试

该包的测试使用PHPUnit进行。您可以从composer依赖中运行它。运行vendor/bin/phpunit将执行phpunit.xml.dist,但如果您想为自己测试进行修改,可以将其复制到phpunit.xml,但请勿将您版本的phpunit.xml作为PR的一部分提交。

贡献

如果您想为此项目做出贡献,请阅读包含的贡献指南

许可

该项目受MIT许可保护,您可以在包含的license.md中阅读有关内容。