我们可以向 CakePHP Table 对象添加自定义值吗?
Can we add custom values to a CakePHP Table Object?
查询 table:
时我有一个 Cake 对象
$invoices = TableRegistry::get('invoices')->find('all', ['conditions' => ['order_number =' => $orderNumber]]);
这很好用。然后我想将其他数组 key/values 添加到此对象,例如:
$invoicesTmp = array();
$invoicesTmp['customer'] = "name of customer";
但是 $invoicesTmp
与 $invoices 不兼容。 (一个是数组,另一个是 CakePHP 对象)
我试过这个:
compact($invoices, $invoicesTmp);
但这没有用。
Table 对象的 find()
方法 returns Cake\ORM\Query
对象。该对象用于构建 SQL 查询并执行它们。它具有一些功能来定义应如何返回查询结果。
当 CakePHP 从数据库中获取结果时,记录被存储为数组,然后 CakePHP 将它们转换为 Entity
对象。称为实体“水合”的过程。如果禁用水合作用,记录将仅作为数组返回。
$query = TableRegistry::get('invoices')
->find()
->where(['order_number'=>$orderNumber])
->enableHydration(false);
foreach($query as $record) {
pr($record);
}
上面创建了一个查询对象,你可以遍历查询记录,因为对象本身支持迭代。
查询对象实现了Cake\Collection\CollectionInterface
接口,这意味着我们可以在其上执行一堆收集方法。最常见的方法是 toArray()
.
$invoices = TableRegistry::get('invoices')
->find()
->where(['order_number'=>$orderNumber])
->enableHydration(false)
->toArray();
$invoices
变量现在是一个有效的数组对象,保存所有记录,每条记录作为一个数组对象。
您现在可以轻松地使用 array_merge
为每条记录分配额外的元数据。
$invoices = array_map(function($invoice) {
return array_merge(['customer'=>'name of customer'], $invoice);
}, $invoices);
$this-set(compact('invoices'));
更新:
根据评论,您似乎希望使用 两个 具有不同列名的不同 table,但这些列代表相同的数据。
字段别名
您可以重命名 SQL 查询中的字段以共享通用别名。
$table = TableRegistry::get($whichTable ? 'table_a' : 'table_b');
$records = $table->find()
->select([
'id',
'invoice_id',
'name' => ? $whichTable ? 'customer_name' : 'invoice_name'
])->all();
以上根据使用的 table 选择不同的列 name
。这允许您始终在视图中使用 $record->name
,无论哪个 table.
我不喜欢这种方法,因为它使视图文件的源代码看起来引用了一个 属性 并不真正存在的实体。稍后返回代码时,您可能会感到困惑。
字段映射
从 MVC 的角度来看。只有控制器知道视图需要什么。所以如果你表达这个知识作为映射会更容易。
$map = [
'id'=>'id',
'invoice_id'=>'invoice_id',
'name' => ? $whichTable ? 'customer_name' : 'invoice_name'
];
$table = TableRegistry::get($whichTable ? 'table_a' : 'table_b');
$records = $table->find()
->select(array_values($map))
->all();
$this->set(compact('records','map'));
稍后在您的视图中输出您这样做的列:
foreach($records as $record) {
echo $record->get($map['name']);
}
它变得冗长关于正在发生的事情,以及为什么。您可以在视图中看到,控制器提供了名为 name
的内容与实际字段之间的映射。您还知道 $map
变量是由控制器注入的。您现在知道去哪里更改它了。
查询 table:
时我有一个 Cake 对象$invoices = TableRegistry::get('invoices')->find('all', ['conditions' => ['order_number =' => $orderNumber]]);
这很好用。然后我想将其他数组 key/values 添加到此对象,例如:
$invoicesTmp = array();
$invoicesTmp['customer'] = "name of customer";
但是 $invoicesTmp
与 $invoices 不兼容。 (一个是数组,另一个是 CakePHP 对象)
我试过这个:
compact($invoices, $invoicesTmp);
但这没有用。
Table 对象的 find()
方法 returns Cake\ORM\Query
对象。该对象用于构建 SQL 查询并执行它们。它具有一些功能来定义应如何返回查询结果。
当 CakePHP 从数据库中获取结果时,记录被存储为数组,然后 CakePHP 将它们转换为 Entity
对象。称为实体“水合”的过程。如果禁用水合作用,记录将仅作为数组返回。
$query = TableRegistry::get('invoices')
->find()
->where(['order_number'=>$orderNumber])
->enableHydration(false);
foreach($query as $record) {
pr($record);
}
上面创建了一个查询对象,你可以遍历查询记录,因为对象本身支持迭代。
查询对象实现了Cake\Collection\CollectionInterface
接口,这意味着我们可以在其上执行一堆收集方法。最常见的方法是 toArray()
.
$invoices = TableRegistry::get('invoices')
->find()
->where(['order_number'=>$orderNumber])
->enableHydration(false)
->toArray();
$invoices
变量现在是一个有效的数组对象,保存所有记录,每条记录作为一个数组对象。
您现在可以轻松地使用 array_merge
为每条记录分配额外的元数据。
$invoices = array_map(function($invoice) {
return array_merge(['customer'=>'name of customer'], $invoice);
}, $invoices);
$this-set(compact('invoices'));
更新:
根据评论,您似乎希望使用 两个 具有不同列名的不同 table,但这些列代表相同的数据。
字段别名
您可以重命名 SQL 查询中的字段以共享通用别名。
$table = TableRegistry::get($whichTable ? 'table_a' : 'table_b');
$records = $table->find()
->select([
'id',
'invoice_id',
'name' => ? $whichTable ? 'customer_name' : 'invoice_name'
])->all();
以上根据使用的 table 选择不同的列 name
。这允许您始终在视图中使用 $record->name
,无论哪个 table.
我不喜欢这种方法,因为它使视图文件的源代码看起来引用了一个 属性 并不真正存在的实体。稍后返回代码时,您可能会感到困惑。
字段映射
从 MVC 的角度来看。只有控制器知道视图需要什么。所以如果你表达这个知识作为映射会更容易。
$map = [
'id'=>'id',
'invoice_id'=>'invoice_id',
'name' => ? $whichTable ? 'customer_name' : 'invoice_name'
];
$table = TableRegistry::get($whichTable ? 'table_a' : 'table_b');
$records = $table->find()
->select(array_values($map))
->all();
$this->set(compact('records','map'));
稍后在您的视图中输出您这样做的列:
foreach($records as $record) {
echo $record->get($map['name']);
}
它变得冗长关于正在发生的事情,以及为什么。您可以在视图中看到,控制器提供了名为 name
的内容与实际字段之间的映射。您还知道 $map
变量是由控制器注入的。您现在知道去哪里更改它了。