2 回答
TA贡献1777条经验 获得超3个赞
一旦您将属性声明为公共属性,您就无法限制对它的访问,因此无法仅通过 setter 强制设置它。
但是在 Yii 中有一种方法可以让财产看起来是公开的,即使它不是。
如果你的类JournalListElement继承自 \yii\base\BaseObject(Yii 中的大多数类都继承自 this)并且如果你将 setter 和 getter 声明为 this
class ReportPayment extends JournalListElement
{
private $paymentAmnt;
public setPaymentAmnt($value)
{
...
}
public getPaymentAmnt()
{
...
}
}
然后您仍然可以paymentAmnt像这样访问该属性,就像它是公开的一样:
$report = new ReportPayment();
$report->paymentAmnt = 20;
echo $report->paymentAmnt;
那是因为\yii\base\BaseObject里面有__set和__get魔法方法的实现。当您尝试访问无法访问的属性时,这些方法将调用setPropertyName()或者getPropertyName()是否存在此类方法。
如果属性是,private您仍将直接从 ReportPayment 类中访问它。您将通过 getter/setter 从类外部或从扩展 ReportPayment 的类自动访问它。
如果属性是,protected您将直接从 ReportPayment 和扩展它的所有类中访问它。您将通过来自 ReportPayment 类或其子类之外的 getter/setter 访问它。
在纯 php 中,您可以通过自己实现__set和__get方法来获得类似的结果。
迭代属性
您可以使用 ReflectionClass 来获取所有属性的列表(包括私有属性),但我不建议这样做。使用这种方式违背了OOP的原则,以后可能会出现问题。例如在您需要添加更多私有属性的情况下。在这种情况下,您将不得不编辑所有 foreach 循环以跳过新属性。
可能的更好方法:
1) 返回可见属性数组的方法:
class ReportPayment extends JournalListElement
{
... code declaring properties and getters/setters
public function getProperties()
{
return ['paymentType', 'paymentNum', 'paymentAmnt', ...];
}
}
foreach ($object->getProperties() as $prop) {
echo $object->$prop;
}
2) 将属性转换为数组的方法
class ReportPayment extends JournalListElement
{
... code declaring properties and getters/setters
public function asArray()
{
return [
'paymentType' => $this->paymentType,
'paymentNum' => $this->paymentNum,
'paymentAmnt' => $this->paymentAmnt,
...
];
}
}
foreach ($object->asArray() as $prop => $value) {
echo $prop . ": " . $value;
}
3) 实现Iterator接口。您可以在此处找到更多详细信息。自己的Iterator接口实现允许您控制 foreach 通过哪些键/值。
这些方法的最大优点是类本身仍然控制循环经过的属性。
TA贡献1876条经验 获得超7个赞
通过反射,您可以遍历对象属性,即使它们是私有的:
$reflect = new ReflectionClass($reportPaymentObject);
$props = $reflect->getProperties(ReflectionProperty::IS_PUBLIC | ReflectionProperty::IS_PROTECTED | ReflectionProperty::IS_PRIVATE);
foreach ($props as $prop) {
print $prop->getName() . "\n";
}
- 2 回答
- 0 关注
- 221 浏览
添加回答
举报