首页 > 解决方案 > 如何在 PHP 中将 stdClass 的属性转换为某种类型?

问题描述

想象一下有StdClass这样的:

$foo = new stdClass();

$foo->bar = "baz";
$foo->baz = "1";

现在我怎么能$foo->baz转换成int?我知道我可以做到以下几点:

$foo->baz = (int) $foo->baz;

然而,这似乎是一个太长的声明。有没有更短的方法来做到这一点?

标签: php

解决方案


标准的“使操作更短”发生在用户功能上。尽可能短:

function as_int(&$var) {
    $var = (int) $var;
}

as_int($foo->baz);

使用这个函数,我们只通过引用传入对象的属性。如果您可能需要访问函数内的对象,则可以使用稍长的形式:

function prop_as_int(object $obj, string $prop) {
    $obj->$prop = (int) $obj->$prop;
}

prop_as_int($foo, 'baz');

任一函数都会导致:

var_dump($foo);

/* 
object(stdClass)#2 (2) {
  ["bar"]=>  string(3) "baz"
  ["baz"]=>  int(1)
}
 */

这里没有return声明或引用参数 ( &$obj),因为在 PHP 中默认情况下对象是通过引用传递的。您可以在您的函数中添加一些完整性检查,例如该值是数字/数字、该属性是否存在(在第二个示例中)等。

您还可以使用自定义类和 int 类型的属性,而不是stdClass; 假设您使用严格类型,则使用处理类型一致性的设置器。如果您不使用严格类型,则将您添加的属性强制转换为正确的数据类型非常简单:

class Foo {
    public int $baz;
}

$foo = new Foo();
$foo->baz = "1";

var_dump($foo);

/* 
object(Foo)#2 (1) {
  ["baz"]=> int(1)
}
*/

如您所见,该值已自动转换为属性的声明类型。如果您declare(strict_types = 1);在使用中,它会导致TypeError: Typed property Foo::$baz must be int, string used,并且解决方案将是类型确认/强制设置器。然而,有效地实现这一点超出了这个答案的范围。

这种方法的缺点是会产生函数调用的开销,如果不调用数千次,这是无关紧要的。如果您发现自己经常在不同的上下文中重复操作并希望减少输入,您会想要这样做。但是,如果您在循环中迭代大量对象时这样做,请将其拼写出来。性能提升是值得的。

最后,如果您的属性名称不可预测并且您想继续使用stdClass,但您知道由所有数字/整数组成的任何变量都应该是数据类型 int... 然后,一旦对象被数据饱和,使用检查!is_int($prop) && ctype_digit($prop),它将匹配所有仅由数字组成的非 int 属性,并将它们转换为 int 数据类型。你也想把它变成一个函数:那是为了家庭作业。


推荐阅读