henzeb/var-export-wrapper

包装对象和闭包以供 var_export 使用

v1.2.0 2024-03-10 13:11 UTC

This package is auto-updated.

Last update: 2024-09-10 14:07:11 UTC


README

Latest Version on Packagist Total Downloads

当缓存配置时,var_export 是一个好选择。例如,在 Laravel 中就是这样做的。但并非所有对象都可以自动导出。

想象一下,你想要创建一个 ImageManipulationService 来调整你的图片。你希望它可配置,所以你得到如下内容

return [
    [
        'suffix' => 'thumb',
        'width' => 300,
        'height' => 200,
        'ratio' => true,
        'pixelate' => 3,
    ]
    // ...
]

你需要为每个可能的功能提供一个选项,或者每次请求时实现新的所需功能。你可以使用可调用的类,但这不会使其可读。

如果可以这样呢

return [
     'constraints' => [
        'aspectRatio' => fn(Constraint $constraint) => $constraint->aspectRatio()
    ],
    'images' => [
        'suffix' => 'thumb',
        'manipulate' => function (Image $image) {
                $image->resize(
                    300,
                    20,
                    config('constraints.aspectRatio')
                )->pixelate(3);
            }
        }
    ]
    // ...
]

使用此包,您可以导出未实现 __set_state 的闭包和对象。您不需要 laravel 来使用它,但使用它时,它将自动解析您的配置以供 artisan config:cache 使用。

安装

只需使用以下命令进行安装。

composer require henzeb/var-export-wrapper

用法

exportify

exportify 是包装对象或对象数组的工具

use function Henzeb\VarExportWrapper\Support\Functions\exportify;

exportify(fn()=>true); // returns instance of VarExportable
exportify(new ExportableClass()); // returns instance of ExportableClass
exportify(new RegularClass()); // returns instance of VarExportable

exportify(['recursive' => [new RegularClass(), fn()=>true]]); // returns nested array with 2 VarExportable instances

注意:exportify 也会遍历实现 TraversableArrayAccess 的对象。

__get_state

exportify 不会自动包装对象内部属性,这在大多数情况下是可行的。但有时你希望导出对象,如对象内部的闭包,或指定要导出什么。为了做到这一点,你可以在你的对象上实现 __get_state。此方法应返回一个数组,其中包含你想要使用 __get_state 恢复的属性。

class User {
    private $name;
    private $email;
    
    public function __construct($name, $email) {
        $this->name = $name;
        $this->email = $email;
    }
    
    public function __get_state(): array {
        return [
            'name' => $this->name,
            'email' => $this->email,
        ];
    }
    
    public static function __set_state($state): self {
        return new self($state['name'], $state['email']);
    }
}

注意:你不需要在这里自己使用 exportify,这是自动完成的。

is_exportable

验证给定的对象或数组。如果不能导出,它将返回 false。

use function Henzeb\VarExportWrapper\Support\Functions\is_exportable;

is_exportable(fn()=>true); // returns false
is_exportable(new RegularClass()); // returns false
is_exportable(new ExportableClass()); // returns true
is_exportable(STDIN); // returns true
is_exportable([[fn()=>true]]); // returns false
is_exportable([[new ExportableClass()]]); // returns true
is_exportable([[new ExportableClass(), fn()=>true]]); // returns false

var_export

var_export 是原生函数的超级版本,但在底层,它将自动将默认无法导出的所有内容包装在 VarExportable 实例中,然后再实际导出值。

use function Henzeb\VarExportWrapper\Support\Functions\var_export;

var_export(fn()=>true); // dumps the var_export string after wrapping the closure.
var_export(new RegularClass()); // dumps the var_export string after wrapping the object
var_export(new ExportableClass()); // dumps the var_export string without wrapping
var_export([[fn()=>>true]]); // dumps the var_export string after wrapping closure

var_export(fn()=>true, true); // returns the var_export string after wrapping the closure.
var_export(new RegularClass(), true); // returns the var_export string after wrapping the object
var_export(new ExportableClass(), true); // returns the var_export string without wrapping
var_export([[fn()=>true]], true); // returns the var_export string after wrapping closure
 

var_export_file

var_export_filevar_export 相同,但它将导出到文件而不是返回。

use function Henzeb\VarExportWrapper\Support\Functions\var_export_file;

var_export_file('/tmp/config.php',[[fn()=>>true]]); // writes the var_export string to /tmp/config.php after wrapping closure

var_import

var_import 在你想要导入 var_exported 字符串或文件时很有用。此函数将自动展开 VarExportable 实例。你也可以传递一个数组,它以另一种方式导入,但仍然包含 VarExportable 实例。

use function Henzeb\VarExportWrapper\Support\Functions\var_import;
use function Henzeb\VarExportWrapper\Support\Functions\var_export;
 
var_import(var_export(fn()=>true)); // returns the closure
var_import('path/to/var_export.php'); // returns the object which is exported in the specified file
var_import([new \Henzeb\VarExportWrapper\VarExportable(fn()=>'hello')]); // returns the array with closure

Laravel 配置

当在 Laravel 安装中安装时,你可以在配置中开始使用闭包和对象。当调用 artisan config:cache 时,var_export wrapper 会自动将它们包装在包装器中。

底层的闭包

为了能够导出闭包,必须序列化它们。它使用 laravel/serializable 来实现这一点。这意味着如果你设置了一个密钥,闭包将被签名,否则它将原生序列化,因此未签名。

你不需要在将闭包传递给 exportify 之前将其包装。

测试

composer test

贡献

请参阅 CONTRIBUTING 以获取详细信息。

安全

如果你发现任何与安全相关的问题,请通过电子邮件 henzeberkheij@gmail.com 而不是使用问题跟踪器。

致谢

许可证

GNU AGPLv。请参阅 许可证文件 以获取更多信息。