Php 在Phalcon模型中返回虚拟列
我有一个(简化)表格的模型Php 在Phalcon模型中返回虚拟列,php,model,phalcon,Php,Model,Phalcon,我有一个(简化)表格的模型leads\u contents\u interactions: 我想选择这些,除了id、lead\u content\u id和created\u on列之外,我还想让它返回一个列is\u new,其中类似以下内容: SELECT id, lead_content_id, created_on, IF(created_on > DATE_SUB(NOW(),INTERVAL 1 DAY), 1, 0) AS is_new FRO
leads\u contents\u interactions
:
我想选择这些,除了id
、lead\u content\u id
和created\u on
列之外,我还想让它返回一个列is\u new
,其中类似以下内容:
SELECT
id,
lead_content_id,
created_on,
IF(created_on > DATE_SUB(NOW(),INTERVAL 1 DAY), 1, 0) AS is_new
FROM leads_contents_interactions;
现在我知道我可以用PHQL实现这一点,但是leads\u contents\u interactions
最好不要直接查询,我希望在自然查询时返回这个额外的列,如:
$leads = $user->getRelated(
'leads',
array(
'Lead.deleted_by IS NULL',
'limit'=>1000
)
);
foreach($leads as $lead) {
foreach($lead->interactions as $interaction) {
echo $interaction->id."\t".$interaction->is_new.PHP_EOL;
}
}
铅的型号(简化)
领导内容模型(简化)
领导内容交互模型(简化)
如果要添加表中不存在但作为业务规则存在的列(创建日期>日期子(NOW(),间隔1天),1,0),则需要在模型本身的afterFetch方法中添加该规则: 但是,应该注意的是,如果在记录集上使用toArray()方法,那么它将只使用表本身上存在的列 重写虚拟字段的toArray()方法。 针对David Duncan所说的话: 但是,应该注意的是,如果使用toArray()方法 在记录集上,它将只使用 桌子本身 为了规避这种Phalcon的“限制”,我创建了以下方法覆盖 第一步 基本上,创建一个BaseModel.php并将下一个代码放在那里
/**
* Method override.
*
* This method is inherited from Model::toArray()
* https://docs.phalconphp.com/en/3.2/api/Phalcon_Mvc_Model
*
* We override it here to circumvent a Phalcon limitation:
* https://stackoverflow.com/a/27626808/466395
*
* Basically, the limitation consists that, when one adds 'virtual fields' to a model (for example,
* by way of callback methods like afterFetch()), then using toArray() on that model only returns
* the fields in the database table but not the virtual fields.
*
* @access public
* @param array $columns As per the Model::toArray() method.
* @return array The data of the model, including any custom virtual fields.
*/
public function toArray($columns = null) {
// calls the regular toArray() method
$data = parent::toArray($columns);
// then gets the model's virtual fields, if any
$virtual_fields = [];
if (!empty($this->list_virtual_fields)) {
// iterates, to get the virtual field's name, value, and getter
foreach ($this->list_virtual_fields as $name) {
$getter_name = 'get' . \Phalcon\Text::camelize($name);
$virtual_fields[$name] = $this->{$getter_name}();
}
}
// merges the model's database data with its virtual fields
$data = array_merge($data, $virtual_fields);
return $data;
}
步骤2
然后,在任何应用程序模型中,定义将包含在上述方法覆盖中的虚拟字段列表。例如:
public $list_virtual_fields = [
'status_label'
];
您还应该为这些虚拟字段定义类属性、setter和getter。举个例子:
protected $status_label;
public function getStatusLabel() {
return $this->status_label;
}
public function setStatusLabel(string $status_label) {
$this->status_label = $status_label;
return $this;
}
public function afterFetch() {
$this->setStatusLabel('pending');
}
步骤3
最后,设置整个应用程序中虚拟字段的值。例如:
protected $status_label;
public function getStatusLabel() {
return $this->status_label;
}
public function setStatusLabel(string $status_label) {
$this->status_label = $status_label;
return $this;
}
public function afterFetch() {
$this->setStatusLabel('pending');
}
注意,我的代码使用getter和setter。如果你愿意,你可以改变它。这正是我想要的。谢谢你非常详尽的回答。非常感谢。b、 为了避免在toArray()中不包含虚拟字段的这种Phalcon“限制”,我在这里提供了一个解决方案:
public $list_virtual_fields = [
'status_label'
];
protected $status_label;
public function getStatusLabel() {
return $this->status_label;
}
public function setStatusLabel(string $status_label) {
$this->status_label = $status_label;
return $this;
}
public function afterFetch() {
$this->setStatusLabel('pending');
}