How do you declare a class property as an object?
I tried:
public $objectname = new $Object();
But it didn't work. Additionally, why should you do it like that?
Isn't it better to just instantiate that object and just use its members?
How do you declare a class property as an object?
I tried:
public $objectname = new $Object();
But it didn't work. Additionally, why should you do it like that?
Isn't it better to just instantiate that object and just use its members?
Why are template strings not allowed as literal object keys?
Template strings are expressions, not literals1. You can only use string literals (and identifiers) for property names, for everything else - that is not known to be static - you need a computed property name.
Is it for performance reasons?
No, that's unlikely. It's to ease parsing, and makes it easy to distinguish constant (statically known) property names from dynamically computed ones.
And mostly, it's a feature that no one needs. It doesn't simplify or shorten anything, and what you would achieve with it is already possible.
Will the syntax be allowed sometime in the future?
Nope.
1: Even when they're called "template literals", technically they aren't literals. And: templates don't even need to be strings, they can evaluate to anything.
It is not possible to prevent the constructor from being called when the object is constructed (line 9 in your code). If there is some functionality that happens in your __construct()
method that you wish to postpone until after construction, you should move it to another method. A good name for that method might be init()
.
Why not just do this?
class Test {
public function __construct($param1, $param2, $param3) {
echo $param1.$param2.$param3;
}
}
$ob = new Test('p1', 'p2', 'p3');
EDIT: I just thought of a hacky way you could prevent a constructor from being called (sort of). You could subclass Test
and override the constructor with an empty, do-nothing constructor.
class SubTest extends Test {
public function __construct() {
// don't call parent::__construct()
}
public function init($param1, $param2, $param3) {
parent::__construct($param1, $param2, $param3);
}
}
$ob = new SubTest();
$ob->init('p1', 'p2', 'p3');
This is might make sense if you're dealing with some code that you cannot change for some reason and need to work around some annoying behavior of a poorly written constructor.
In the constructor, yes.
class User
{
public $x = "";
public $y = null;
public $w = array();
public function __construct()
{
$this->y = new ErrorVO();
}
}
Edit
KingCrunch made a good point: You should not hard-code your dependencies. You should inject them to your objects (Inversion of Control (IoC)).
class User
{
public $x = "";
public $y = null;
public $w = array();
public function __construct(ErrorVO $y)
{
$this->y = $y;
}
}
new User(new ErrorVD());
You may use Factory Pattern. Basket, Billing and Delivery objects should be created by the 3rd-party service API wrapper class:
$svc = new The3rdPartyServiceApiWrapper();
$svc->init(); // connect, get session etc.
if ($svc->fail()) die("halp! error here!");
$basket = $svc->createBasket();
$baskSumm = $basket->getBasketSummary();
$billing = $svc->createBilling();
$billSumm = $billing->getBillingSummary();
$delivery = $svc->createDelivery();
$delSumm = $delivery->getDeliverySummary();
The best way to connect Basket, Billing and Delivery class with the API is storing a reference to the API class, then they can call any method of it, not just getSession().
Another advantage is, that if you have an identified entity, e.g. a User, then the wrapper class can grant you, that there will be no double objects in the scene.
If the main program creates the users, there should be different objects with the same user, which is wrong:
$user1 = new User("fred12");
$user2 = new User("fred12");
VS if the API wrapper creates them, the wrapper class should keep a "cache" of users, and return with the same User object for the same request:
$user1 = $svc->createUser("fred12");
$user2 = $svc->createUser("fred12"); // $user2 will be the same object
(Maybe it's not a best example, if a program creates twice the same User, it means that the program has major design faulty.)
UPDATE: explanation of svc class
The The3rdPartyServiceApiWrapper should look like this:
function getSessionId() {
return $this->sessionId; // initialized by constructor
} // getSessionId()
function createBasket() {
$basket = new Basket($this);
return $basket;
} // createBasket()
The Basket:
function Basket($s) { // constructor of Basket class
$this->svc = $s;
//... the rest part of constructor
} // Basket() constructor
function doSomethingUseful() {
// if you wanna use the session:
$sess = $this->svc->getSessionId();
echo("doing useful with session $session");
// you may access other api functions, I don't know what functions they provide
$this->svc->closeSession();
} // doSomethingUseful()
From the PHP manual on class properties (emphasis mine):
Either create it inside the constructor (composition)
or inject it in the constructor (aggregation)
or use setter injection.
You want to favor aggregation over composition.