TL;TR
Before this code I have a SQL query that sets the value of $mainPrice
Ok, and you want to assign its value to the $price
property. In that case: write a constructor that takes the $mainPrice
as an argument, and assigns it to the $price
property.
The details are all explained below
It's really quite simple: $mainPrice
is (probably) a global variable (which is evil, but that's not the point here). the PayEx
class has its own scope. its properties are to be initialized using constant values or in the constructor (using arguments you pass to it).
A class is a single, portable unit of code. It should therefor not depend on any variable outside of itself, just to do its business. Who's to say that this $mainPrice
variable will be around every single time your class will be used/initialized? And more importantly: when will the private $price = $mainPrice;
statement be evaluated? When the file containing the class definition is require
'd? When the autoloader kicks in? When the first instance is created, or whenever an instance is created? Think about it... you know it doesn't really make sense in an OO context
What would be the appropriate thing to do is something like:
class PayEx
{
private $price = null;
/**
* Constructors - They are there to initialize properties
* @param $mainPrice = null - null makes it optional
*/
public function __construct($mainPrice = null)
{
$this->price = $mainPrice
}
}
$x = new PayEx(123);//price propery is 123
$y = new PayEx();//price property is null
The safest way to set properties, though, is, and will always be: to create custom getter/setter methods. These methods can, for example, preform additional checks on the values you are trying to assign to a property. If invalid data is provided, they can also throw exceptions, containing specific information on what went wrong, making your code easier to use, maintain, and debug:
class PayEx
{
private $price = null;
public function __construct($mainPrice = null)
{
if ($mainPrice !== null)
$this->setPrice($mainPrice);
}
/**
* Custom setter
* @param float $price
* @return $this
* @throws \InvalidArgumentException
*/
public function setPrice($price)
{
if (!is_numeric($price))
throw new \InvalidArgumentException(
sprintf(
'%s expected argument of type float, instead saw non-numeric %s',
__METHOD__,
gettype($price)
)
);
$this->price = (float) $price;
return $this;
}
/**
* custom getter
* @param null|string $format
* @return float|string
*/
public function getPrice($format = null)
{
if ($format === null)
return $this->price;
return sprintf($format, $this->price);
}
}
$x = new PayEx(12.456);
echo $x->getPrice('%.2f');//echoes 12.45
var_dump($x->getPrice());//float 12.456
I hope this gives you some idea as to why getters and setters are used so often in bigger projects.