如何将变量转换为数组

60

我有一个变量$v$,它可以是单个字符串或者字符串数组
现在我有如下代码:

$a = array();
if (is_array($v)) {
    $a = $v;
} else {
    $a[] = $v;
}

有没有更加优雅的方法实现这个功能?(换句话说,如何将一个变量强制转换为数组)

8个回答

110

您可以通过以下方式将变量转换为数组:

    $var = (array)$arr;

1
这会导致 PHP 出现意外行为。正确的方式是 array($arr)。 - Ulterior
40
答案是正确的。@Ulterior的评论不正确。例如:$arr = null; var_dump((array) $arr, array($arr));返回:array(0) {}(正确),然后array(1) { [0] => NULL }(不正确)此外,关于cbroughton的正确答案,当变量必须在foreach()中使用时,需要进行这样的转换:如果变量不是数组(或可迭代的),将会出现PHP警告。 - FGM
2
顺便说一句:我认为进行类型转换非常重要。如果你有一个变量,它可能会被改变,然后再跟着一个接受数组的函数,例如 foreachimplode,否则你将遇到不必要的错误和警告。 - GFargo
1
假设 $z=[1,2],请注意 (array)$z[$z] 之间的区别,因为它们的 类型 已经是 _array_,所以不会影响 $z,而 [$z] 则会在 $z 周围显式添加一个数组包装层。 - St3an

22
$a = (array) $v;

答案就是它。


15

我会像这样编写您的代码片段(简短且易于阅读,您可以立即知道正在发生什么):

$a = is_array($v) ? $v : array($v);

7

或者您可以使用 settype 方法:

settype($a, "array");

为了明确变量类型。这与幕后发生的类型转换完全相同。(在循环中更有用,例如对于组内类型转换)


5

如果$v是一个标量(布尔值、字符串、数字),你可以使用:

a) $v = (array)$v;

如果$v是一个对象,你需要使用:

b) $v = is_array($v) ? $v : array($v);

方法(b)在所有情况下都适用(包括标量的情况)。


1
这个问题的范围明确限制为从字符串或字符串数组中形成一个数组。这个答案不必要地扩大了问题的范围。这是对错误问题的正确答案。这个答案中适当的一半早在多年前就已经被提出了。 - mickmackusa

4
正如其他人所说,将标量值转换为数组将产生一个单例数组(即一个只包含该标量的数组元素)。然而,正如其他人指出的那样,请注意仅在您知道该值将是标量而不是类实例时才执行此操作。
PHP文档中可以得到以下信息:
对于类型为整数、浮点数、字符串、布尔和资源的任何值,将其转换为数组将会得到一个只有一个元素的数组,索引为零,该元素的值为被转换的标量。换句话说,`(array)$scalarValue` 与 `array($scalarValue)` 完全相同。
如果对象被转换为数组,则结果是一个元素为对象属性的数组。键是成员变量名,有一些显著的例外:整数属性无法访问;私有变量在变量名前面加上类名;受保护的变量在变量名前加上“*”。这些前置值两侧有空字节。

2
如果您想将一个对象转换为单个计数数组,可以使用以下代码:
$list = array([0] => $obj);

当尝试转换一个对象时,其他提供的答案不起作用,它只会将该对象的字段转换为关联数组(除非这正是您想要做的)。

$var = (array)$arr;

提问者说:“我有一个变量 $v,它可以是单个字符串或字符串数组。” 看起来你不公平地创造了一个不同的情景,并声称其他答案行不通。从相反的角度来看,似乎你在错误的页面上发布了正确的答案。 - mickmackusa

-4

实际上,如果你想将其转换为数组并且不必担心放入其中的内容,答案就是

$var = (is_object($var)) ? array($var) : (array) $var;

你可以使用以下代码进行测试。
function toArray($var) {
    return (is_object($var)) ? array($var) : (array) $var;
}

$object = new stdClass;
$resource = fopen('php://stdout', 'w');
$closure = function () {};

$tests = array(
    array(toArray(true),      array(true),      'boolean true'),
    array(toArray(false),     array(false),     'boolean false'),
    array(toArray(null),      array(),          'null'),
    array(toArray(1),         array(1),         'positive integer'),
    array(toArray(0),         array(0),         'zero integer'),
    array(toArray(-1),        array(-1),        'negative integer'),
    array(toArray(1.5),       array(1.5),       'positive float'),
    array(toArray(0.0),       array(0.0),       'zero float'),
    array(toArray(-1.5),      array(-1.5),      'negative float'),
    array(toArray(''),        array(''),        'empty string'),
    array(toArray('foo'),     array('foo'),     'string'),
    array(toArray(array()),   array(),          'array'),
    array(toArray($object),   array($object),   'object'),
    array(toArray($resource), array($resource), 'resource'),
    array(toArray($closure),  array($closure),  'closure'),
);

foreach ($tests as $test) {
    ob_start();
    var_dump($test[0]);
    $a = ob_get_clean();
    ob_start();
    var_dump($test[1]);
    $b = ob_get_clean();
    assert($a === $b, "{$test[2]} is not the same");
}

1
实际上,这并不是真的。你可以像 $var = (array) $obj; 这样将对象强制转换为数组 -> $object = new stdClass; 应该被强制转换为空数组 array() - Philipp

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接