php - 我们可以向 CakePHP 表对象添加自定义值吗?

标签 php cakephp cakephp-3.0

查询表时我有一个 Cake 对象:

$invoices = TableRegistry::get('invoices')->find('all', ['conditions' => ['order_number =' => $orderNumber]]);

这很好用。然后我想向该对象添加其他数组键/值,如下所示:

$invoicesTmp = array();
$invoicesTmp['customer'] = "name of customer";

但是$invoicesTmp与$invoices不兼容。 (一个是数组,另一个是 CakePHP 对象)

我已经尝试过这个:

compact($invoices, $invoicesTmp);

但这并没有奏效。

最佳答案

Table 对象的 find() 方法返回一个 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 接口(interface),这意味着我们可以对其执行一系列收集方法。最常见的方法是 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'));

更新:

根据评论,您似乎希望使用两个具有不同列名称的不同表,但这些列代表相同的数据。

字段别名

您可以重命名 SQL 查询中的字段以共享通用别名。

  $table = TableRegistry::get($whichTable ? 'table_a' : 'table_b');
  $records = $table->find()
               ->select([
                   'id',
                   'invoice_id',
                   'name' => ? $whichTable ? 'customer_name' : 'invoice_name'
               ])->all();

以上内容根据所使用的表为name选择不同的列。这允许您始终在 View 中使用 $record->name,无论哪个表。

我不喜欢这种方法,因为它使 View 文件的源代码看起来引用了实际上并不存在的实体的属性。稍后返回代码时您可能会感到困惑。

字段映射

从MVC的角度来看。只有 Controller 知道 View 需要什么。因此,如果您将这些知识表达为映射,就会更容易。

  $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'));

稍后在您的 View 中输出列,您可以这样做:

  foreach($records as $record) {
        echo $record->get($map['name']);
  }

关于发生的事情和原因变得冗长。您可以在 View 中看到 Controller 提供了名为 name 的内容与实际字段之间的映射。您还知道 $map 变量是由 Controller 注入(inject)的。您现在知道去哪里更改它。

关于php - 我们可以向 CakePHP 表对象添加自定义值吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47865478/

相关文章:

javascript - 如果之前的进程正常工作,Symfony 不会发送响应

jquery - 在 cakePHP 中调用 ajax 时使用操作 url 的最佳实践

CakePHP Auth only for Admin Prefix

php - 在cakephp中更新多表

sql - CakePHP 3 : how to make a sum of 2 columns

php - 关联数组中最常见的值

php - 在 Laravel 5.1 验证之前修改输入

php - 我使用 cakephp3.4.13 进行验证时发生了什么?

php - 如何使用 Ajax for MYSQL 插入、编辑、删除、显示条目?

php - CAKEPHP - 自引用表覆盖变量