Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert (cast) Object to Array without Class Name prefix in PHP?

Tags:

arrays

object

php

How to convert (cast) Object to Array without Class Name prefix in PHP?

class Teste{

    private $a;
    private $b;

    function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

}

var_dump((array)(new Teste('foo','bar')));

Result:

array
  '�Teste�a' => string 'foo' (length=3)
  '�Teste�b' => string 'bar' (length=3)

Expected:

array (
a => 'foo'
b => 'bar' )
like image 847
celsowm Avatar asked Aug 07 '12 14:08

celsowm


People also ask

How do you change an object to an array?

To convert an object to an array you use one of three methods: Object. keys() , Object. values() , and Object. entries() .

What array will you get if you convert an object to an array in PHP?

If an object is converted to an array, the result is an array whose elements are the object's properties.

How do you cast an array to an object?

Use the spread syntax (...) to convert an array to an object, e.g. const obj = {... arr} . The spread syntax will unpack the values of the array into a new object, where the indexes of the array are the object's keys and the elements in the array - the object's values. Copied!


2 Answers

From the manual:

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. This can result in some unexpected behaviour:

You can therefore work around the issue like this:

$temp = (array)(new Teste('foo','bar'));
$array = array();
foreach ($temp as $k => $v) {
  $k = preg_match('/^\x00(?:.*?)\x00(.+)/', $k, $matches) ? $matches[1] : $k;
  $array[$k] = $v;
}
var_dump($array);

It does seem odd that there is no way to control/disable this behaviour, since there is no risk of collisions.

like image 64
DaveRandom Avatar answered Oct 26 '22 05:10

DaveRandom


The "class name prefix" is part of the (internal) name of the property. Because you declared both as private PHP needs something to distinguish this from properties $a and $b of any subclass.

The easiest way to bypass it: Don't make them private. You can declare them as protected instead.

However, this isn't a solution in every case, because usually one declares something as private with an intention. I recommend to implement a method, that makes the conversion for you. This gives you even more control on how the resulting array looks like

public function toArray() {
  return array(
    'a' => $this->a,
    'b' => $this->b
  );
}
like image 43
KingCrunch Avatar answered Oct 26 '22 05:10

KingCrunch