6

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

Community
  • 1
  • 1
Saurin Dashadia
  • 1,140
  • 11
  • 25
  • 3
    You will have to write your own custom method to do that. The reason for that is that object will not know how to handle different properties or properties that have not been defined. Something like $object->load($array). – Yasen Zhelev May 20 '15 at 14:53
  • possible duplicate of [Converting a PHP array to class variables](http://stackoverflow.com/questions/2715465/converting-a-php-array-to-class-variables) – Yasen Zhelev May 20 '15 at 14:56
  • possible duplicate of [Convert/cast an stdClass object to another class](http://stackoverflow.com/questions/3243900/convert-cast-an-stdclass-object-to-another-class) – Richard May 20 '15 at 14:56
  • Try this : http://stackoverflow.com/questions/2715465/converting-a-php-array-to-class-variables – Ahmed Ziani May 20 '15 at 15:01
  • 1
    If you are fetching from a database most APIs have a `fetch_object()` or similar where you can specify the class. – AbraCadaver May 20 '15 at 15:09
  • @AhmedZiani I know this can be done using `foreach`. But I am looking for the solution that is at language level, not at logic level. – Saurin Dashadia May 20 '15 at 15:13
  • @AbraCadaver, exactly the same way I am looking to get My object initialized with array – Saurin Dashadia May 20 '15 at 15:14
  • 2
    Then the direct answer to your question is: no, such a thing does not exist in PHP. – deceze May 20 '15 at 15:22
  • This far it seems like there is no such direct method. I am accepting TiMESPLiNTER's answer as he partially helped me out. – Saurin Dashadia May 21 '15 at 12:00

2 Answers2

1

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;
Community
  • 1
  • 1
TiMESPLiNTER
  • 5,741
  • 2
  • 28
  • 64
0

Based on your response to comment by @AbraCadaver I would look at using something like this to load DB results into an instantiated class of your choice:

// using MySQLi
$mysqli_result = ...; // your mysqli_result object
while($class_obj = $mysqli_result->fetch_object('your_class_name')) {
    // do something
}

// using PDO
$pdo_statement = ...; // your PDOStatement object
while($class_obj = $pdo_statement->fetch_object('your_class_name')) {
    // do something
}
Mike Brant
  • 70,514
  • 10
  • 99
  • 103
  • Hello Mike, My comment was to get something like we have with `fetch_object` but I am not using/fetching data from db. My example explains it well. :) – Saurin Dashadia May 21 '15 at 11:13