且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

我们可以将自定义值添加到CakePHP表对象吗?

更新时间:2022-06-16 21:58:53

Table对象的 find()方法返回 Cake\ORM\Query 对象。此对象用于构建SQL查询并执行它们。它具有一些功能来定义应如何返回查询结果。

The find() method of a Table object returns a Cake\ORM\Query object. This object is used to build SQL queries and to execute them. It has some features to define how the results from the query should be returned.

当CakePHP从数据库中获取结果时,记录将存储为数组,然后CakePHP将其转换为 Entity 对象。称为水合的过程称为水合。实体。如果您禁用水合,则记录将仅作为数组返回。

When CakePHP fetches results from the database the records are stored as an array, and CakePHP then converts them to Entity objects. A process called "hydration" of entities. If you disable hydration the records are returned as just an array.

$query = TableRegistry::get('invoices')
                 ->find()
                 ->where(['order_number'=>$orderNumber])
                 ->enableHydration(false);

foreach($query as $record) {
    pr($record);
}

上面创建了一个查询对象,您可以迭代查询记录,因为对象本身支持

The above creates a query object, and you can iterate over the query records because the object itself supports iteration.

查询对象实现 Cake\Collection\CollectionInterface 接口,这意味着我们可以执行许多收集方法在上面。最常见的方法是 toArray()

The query object implements the Cake\Collection\CollectionInterface interface, which means we can perform a bunch of collection methods on it. The most common method is the toArray().

$invoices = TableRegistry::get('invoices')
                 ->find()
                 ->where(['order_number'=>$orderNumber])
                 ->enableHydration(false)
                 ->toArray();

$ invoices 变量现在是一个有效的数组对象,包含所有记录,每个记录都作为数组对象。

The $invoices variable is now a valid array object holding the all the records with each record as an array object.

您现在可以轻松地使用 array_merge 为每个记录分配额外的元数据。 / p>

You can now easily use array_merge to assign extra metadata to each record.

$invoices = array_map(function($invoice) {
     return array_merge(['customer'=>'name of customer'], $invoice);
}, $invoices);

$this-set(compact('invoices'));

已更新:

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

Based upon the comments it appears you wish to use two different tables with different column names, but those columns represent the same data.

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

You can rename fields in the SQL query to share a common alias.

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

上面根据哪个表为 name 选择了不同的列正在被使用。这使您无论在哪个表中都可以始终在视图中使用 $ record-> name

The above selects a different column for name depending upon which table is being used. This allows you to always use $record->name in your view no matter which table.

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

I don't like this approach, because it makes the source code of the view file appear to reference a property of the entity that doesn't really exist. You might get confused when returning to the code later.

从MVC角度来看。只有控制器知道视图需要什么。因此,如果您表达此知识作为映射会更容易。

From a MVC perspective. Only the controller knows what a view needs. So it's easier if you express this knowledge as a mapping.

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

稍后在视图中输出您按如下方式进行操作的列:

Later in your view to output the columns you do it like this:

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

关于发生的事情以及原因,这变得冗长。您可以在视图中看到控制器提供了 name 与实际字段之间的映射。您还知道 $ map 变量是由控制器注入的。您现在知道去哪里进行更改了。

It becomes verbose as to what is happening, and why. You can see in the view that the controller provided a mapping between something called name and the actual field. You also know that the $map variable was injected by the controller. You now know where to go to change it.