Reputation: 17944
What I have:
$tom = new Driver;
$bmw = new Car;
$benz = new Car;
What I want to have:
foreach (Car::$all_cars as $car) {
$tom->setRating($car, $rating); // $rating comes from user input
}
Question:
How to implement this?
Constraints:
What I think:
Class Driver {
private $cars;
public function __construct() {
$his->cars = new \stdClass();
foreach (Car::$all_cars as $car) {
$this->cars->$car = NULL;
}
}
public setRating($car, $rating) {
$this->cars->$car = $rating;
}
}
Class Car {
public static $all_cars = array();
public $name;
public function __construct($name) {
$this->name = $name;
self::$all_cars[] = $this->name;
}
}
$bmw = new Car('bmw');
$benz = new Car('benz');
$tom = new Driver;
foreach (Car::$all_cars as $car) {
$tom->setRating($car, $rating); // $rating comes from user input
}
Upvotes: 2
Views: 2307
Reputation: 316969
PHP allows you to set properties on any object, e.g.
$tom = new StdClass;
$tom->bmw = 95;
Likewise, you can use variable variables for the property names, as long as the property name is a string, e.g.
$car = 'bmw';
$tom = new StdClass;
$tom->$car = 95;
This will put a public property bmw
on $tom
, which you can then access with
echo $tom->bmw; // prints 95
You cannot assign an object to a property, because it is not a string, e.g.
$car = new Car;
$tom = new StdClass;
$tom->$car = 95;
cannot work. You have to add a __toString
method to the Car object and set the name as a property of the Car:
Class Car
{
private $name;
public function __construct($name)
{
$this->name = $name;
}
public function __toString()
{
return $this->name;
}
}
Because assigning a property name is a string context, PHP will automatically use the Car's name property now when you try to use the Car instance in a string context. There is no sane way to infer the name from the variable name instead, e.g. you cannot do
$bmw = new Car;
and hope to get bmw out of it. The name has to be in the object.
I have provided an example that works with the code you gave at https://3v4l.org/TjC89
Upvotes: 1