TL;TR
在这段代码之前,我有一个设置$mainPrice值的SQL查询
好的,您想将其值分配给$price 属性。在这种情况下:编写一个将$mainPrice 作为参数的构造函数,并将其分配给$price 属性。
详情都在下面解释
这真的很简单:$mainPrice(可能)是一个全局变量(is evil,但这不是重点)。 PayEx 类有自己的作用域。它的属性将在构造函数中使用常量值或初始化(使用你传递给它的参数)。
类是一个单一的、可移植的代码单元。因此,它应该不依赖于自身之外的任何变量,只是为了做自己的事情。谁会说这个$mainPrice 变量会在每次使用/初始化您的类时出现?更重要的是:何时会评估 private $price = $mainPrice; 语句?当包含类定义的文件是require'd?自动装载机何时启动?什么时候创建第一个实例,或者什么时候创建一个实例?想一想……你知道它在 OO 上下文中真的没有意义
适当的做法是:
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
最安全的设置属性的方法是,并且永远是:创建自定义的 getter/setter 方法。例如,这些方法可以对您尝试分配给属性的值进行额外检查。如果提供了无效数据,它们也可以抛出异常,包含有关问题的具体信息,使您的代码更易于使用、维护和调试:
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
我希望这能让您了解为什么在大型项目中如此频繁地使用 getter 和 setter。