Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any way to convert an array to class properties?

There is a way to get class properties and convert it using (array) casting.

$user = (array) get_object_vars($userObject)

But I wonder, I didn't find any direct method to convert array to class properties.

Suppose I have user class with following implementation:

class User
{
    private $id = 0;
    private $fname = '';
    private $lname = '';
    private $username = '';
}

I have following array:

$user = array(
    'id'=> 2,
    'fname' => 'FirstName',
    'lname' => 'LastName',
    'username' => 'UserName'
);

I am looking for a type cast just like we have (object). The issue is (object) type cast converts array to stdClass object, but here I want my array to be converted in to my specified class.

The example should be stated like: (my assumption, that PHP should have this. Or it may already have some thing like this and I dont know.)

$userobj = (object User) $user;

And the result of above syntax should be just like:

$userobj->id = $user['id'];
$userobj->fname = $user['fname'];
$userobj->lname = $user['lname'];
$userobj->username = $user['username'];

I want to know if there any direct method, not a logic of mapping. Looking for language level trick.

Note: I am aware of the use of foreach to get above done. I am looking for some direct method if available in PHP but not get into focus yet (may be!).

Following doesn't solve my question: Convert/cast an stdClass object to another class

like image 981
Saurin Dashadia Avatar asked May 20 '15 14:05

Saurin Dashadia


1 Answers

An array is not an object. So you can't cast it with a language construct. Even casting user defined objects in PHP is not possible.

So you have to write your own logic. There are some fancy approaches by serialize() the object, change the class name and unserialize() it again to automate the process.

Also you could write a cast function using reflection. But everything needs user logic.

See also this post on SO: Type casting for user defined objects

So if you really like to cast objects I ended up with this function (see it in action):

function cast($to, $obj)
{
    $toLength = strlen($to);
    $serializedObj = preg_replace('/^O:\\d+:"[^"]+"/', 'O:' . $toLength . ':"' . $to . '"', serialize($obj));

    $serializedObj = preg_replace_callback('/s:(\\d+):"([^"]+)";(.+?);/', function($m) use($to, $toLength) {
        $propertyName = $m[2];
        $propertyLength = $m[1];

        if(strpos($m[2], "\0*\0") === false && ($pos = strrpos($m[2], "\0")) !== false) {
            $propertyName = "\0" . $to . "\0" . substr($m[2], $pos + 1);
            $propertyLength = ($m[1] + $toLength - $pos + 1);
        }

        return 's:' . $propertyLength . ':"' . $propertyName . '";' . $m[3] . ';';
    }, $serializedObj);

    return unserialize($serializedObj);
}

$user = array(
    'id'=> 2,
    'fname' => 'FirstName',
    'lname' => 'LastName',
    'username' => 'UserName'
);

$userObj = cast(User::class, (object)$user);

print_r($userObj);

But I would never ever use this function in production. It's just an experimental thing.

Update

Okay I rethought how casting is handled in Java. In Java you actually can just cast from an object to a child object of it. You can't cast from any object to any other.

So you could do this in Java:

$apple = new Apple();
$macintoshApple = (MacintoshApple)$apple;

given that MacintoshApple extends Apple.

But you can't cast two unrelated objects like:

$apple = new Apple();
$pear = (Pear)$apple;
like image 81
TiMESPLiNTER Avatar answered Sep 21 '22 07:09

TiMESPLiNTER