57

I have a variable $v that can be either single string or array of strings
and I have a code:

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

How it can be done in more elegant way? (in other words, how to cast a variable to array)

tsds
  • 8,700
  • 12
  • 62
  • 83

8 Answers8

106

You can cast a variable to an array by using:

    $var = (array)$arr;
Alexander Trauzzi
  • 7,277
  • 13
  • 68
  • 112
cbroughton
  • 1,726
  • 1
  • 12
  • 19
  • 1
    this results in php unexpected behaviour. correct way is array($arr) – Ulterior Jun 23 '14 at 21:53
  • 38
    The answer is correct. The comment by @Ulterior is not. Example: $arr = null; var_dump((array) $arr, array($arr)); Returns: array(0) {} (correct), then array(1) { [0] => NULL } (incorrect) Also, with regard to cbroughton's correct answer, such casts are needed when the variable has to be used in a foreach(): if the variable is not an array (or iterable), there will be a PHP warning. – FGM Aug 12 '14 at 14:22
  • 2
    FWIW: I think it's important to typecast If you ever have a variable it is subject to mutation followed by a function that takes an array e.g. `foreach` or `implode` otherwise you'll run into unwanted errors and warnings. – GFargo Nov 14 '16 at 16:51
  • let's assume `$z=[1,2]`, please note the difference between `(array)$z`, which won't affect $z (because its _type_ already is _array_), and `[$z]` wich will explicitly add an array wrapping layer around $z – St3an Jan 04 '22 at 13:54
22
$a = (array) $v;

is the answer.

Kelly
  • 40,173
  • 4
  • 42
  • 51
15

I would write your could snippet like this (short and you read it and know exactly what is happening):

$a = is_array($v) ? $v : array($v);
kapa
  • 77,694
  • 21
  • 158
  • 175
6

Alternatively you could use settype:

settype($a, "array");

For expliciting the variable type. It's exactly the same as what happens with a typecast behind the scenes. (More useful for group-wise typecasting e.g. in loops.)

mario
  • 144,265
  • 20
  • 237
  • 291
4

As others have said, casting a scalar value to an array will produce a singleton array (i.e. an array with the scalar as its only element). However, as still others have pointed out, take care to only do this if you know the value is going to be a scalar and not a class instance.

From the PHP docs:

For any of the types integer, float, string, boolean and resource, converting a value to an array results in an array with a single element with index zero and the value of the scalar which was converted. In other words, (array)$scalarValue is exactly the same as array($scalarValue).

If an object is converted to an array, the result is an array whose elements are the object's properties. The keys are the member variable names, with a few notable exceptions: integer properties are unaccessible; private variables have the class name prepended to the variable name; protected variables have a '*' prepended to the variable name. These prepended values have null bytes on either side.

GuyPaddock
  • 2,233
  • 2
  • 23
  • 27
4

If $v is a scalar (Boolean, String, Number) you can use:

a) $v = (array)$v;

If $v is an object, you have to use:

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

Method (b) works in every case (with scalars too).

Liakos
  • 512
  • 5
  • 10
  • The scope of this question is explicitly limited to forming an array from a string or an array of strings. This answer is unnecessarily stretching the scope of the question. This is the right answer to the wrong question. The half of this answer that is appropriate has already been said many years earlier. – mickmackusa May 15 '22 at 22:05
2

If you are looking to convert an object to a single count array you can use the follow code:

$list = array([0] => $obj);

The other provided answers won't work when trying to convert an object, it will simply convert the fields of that object into an associative array (unless that is what you are trying to do).

$var = (array)$arr;
TroySteven
  • 4,885
  • 4
  • 32
  • 50
  • The asker says: "_I have a variable $v that can be either single string or array of strings_". It seems that you are unfairly creating a different scenario and claiming that other answers won't work. Seen from the opposite perspective, it seems that you have posted the right answer on the wrong page. – mickmackusa May 15 '22 at 07:47
-4

Actually if you want to cast to an array and not have to worry about what you put into it, the answer is

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

You can test this with the following code

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");
}
opex
  • 234
  • 2
  • 6
  • 1
    Actually... this is not true. You can cast objects to array like `$var = (array) $obj;` -> `$object = new stdClass;` should be cast into `array()` (empty array) – Philipp Feb 02 '16 at 16:53