I should add out by saying that while KVP-arrays work fine, I prefer objects when doing OOP as $foo->bar->foo
just seems cleaner than $foo->bar['foo']
in my opinion.
PHP has a great way of creating arrays with pre-populated data through $foo = array('foo' => 'bar');
or even the new 5.4 bracket syntax: $foo = ['foo' => 'bar']
, but the same syntax does not seem to exist for objects (stdClass
).
<?php
class Foo {
public $bar = array(
'foo' => 'bar',
'bar' => 'foo'
);
}
$foo = new Foo;
var_dump($foo->bar);
/*
array(2) {
["foo"]=>
string(3) "bar"
["bar"]=>
string(3) "foo"
}
*/
?>
Great - what if we want to do the same with objects without using a __construct
?
Try #1 - casting to object - nope; we can't cast in the declaration of a class variable:
<?php
class Foo {
public $bar = (object)array(
'foo' => 'bar',
'bar' => 'foo'
);
}
/*
Parse error: syntax error, unexpected T_OBJECT_CAST on line 4
*/
?>
<?php
class Foo {
public $bar = json_decode(json_encode(array(
'foo' => 'bar',
'bar' => 'foo'
)));
}
/*
Parse error: syntax error, unexpected '(', expecting ',' or ';' on line 3
*/
?>
<?php
class Foo {
public $bar = {
'foo' => 'bar',
'bar' => 'foo'
};
}
/*
Parse error: syntax error, unexpected '{' on line 3
*/
?>
The only way that seems to work is by using a __construct
and converting the KVP-array to an object, but it just seems completely backwards to declare a variable as one thing, and before we ever use it, cast it to something else.
<?php
class Foo {
public $bar = array(
'foo' => 'bar',
'bar' => 'foo'
);
public function __construct() {
$this->bar = (object)$this->bar;
}
}
$foo = new Foo;
var_dump($foo->bar);
/*
object(stdClass)#2 (2) {
["foo"]=>
string(3) "bar"
["bar"]=>
string(3) "foo"
}
*/
?>
- Is there some short-hand syntax I haven't been able to find?
- If not; is it going to be added in future PHP versions?
- If not/until
then; Is there a better way than having to add
__construct
's every single time? - Should I, instead, just deal with the fact that using an array in this situation is better, even though, in my opinion, it seems messier?
Why?:
Working on a new DB class for a company, I've had to resort to the current code in order to manage saving DB credentials for further inspection later in the code. Of course a different design pattern, such as $connectionHost
, $connectionDatabase
, etc. would work fine - but it seems cluttered to me.
<?php
class DB {
public $connection = array(
'host' => null,
'database' => null,
'user' => null,
'engine' => null
);
public function __construct($host, $database, $user, $engine = 'mysql') {
//Essentially I'd like the following line not to be needed:
$this->connection = (object)$this->connection;
$this->connection->host = $host;
$this->connection->database = $database;
$this->connection->user = $user;
$this->connection->engine = $engine;
}
}
$db = new DB('127.0.0.1', 'server_db', 'my_user');
var_dump($db->connection->host);
?>