我编写了如下的custom finder方法:
public function findSubstanceListNotifications(Query $query, array $options)
{
$date_start = $options['date_start'];
$date_end = $options['date_end'];
$list_id = $options['list_id'];
$list_substances = TableRegistry::getTableLocator()->get('TblListsSubstances')->find()
->select('substance_id')->where(['list_id IN' => $list_id])->enableHydration(false);
if ($list_substances->isEmpty()) {
return false;
}
$query = $this->find()
->select(['RevisionSubstances.date', 'RevisionSubstances.comment', 'RevisionSubstances.id', 'Substances.name', 'Substances.app_id'])
->where(['substance_id IN' => array_column($list_substances->toArray(), 'substance_id')]);
$query->where(['RevisionSubstances.date >=' => $date_start, 'RevisionSubstances.date <=' => $date_end]);
$query->contain('Substances');
$query->order(['RevisionSubstances.date' => 'DESC', 'Substances.app_id' => 'ASC']);
$query->enableHydration(false);
if ($query->isEmpty()) {
return false;
}
return $query;
}
由于执行此操作时达到内存限制,我收到了PHP致命错误。
我怀疑原因是因为substance_id IN
条件正在使用具有数千个键的数组。
有没有一种替代方法来编写此代码,我现在可以写IN
语句,而不是先使用SELECT
后跟一个数组?类似于MySQL中的子查询。
条件的SQL由$list_substances
描述,但本质上是:
SELECT substance_id FROM tbl_lists_substances WHERE list_id IN(1,2,3,4);
IN()
以上条件使用与登录用户有关的ID。但是,此数组最多只能有20个以下的键,因此我认为这里不会有任何类似的内存问题。但是我也需要在运行子查询时知道如何访问它们。
CakePHP版本是3.7
我已经读过有关在newExpr()
中使用docs的信息,但目前还看不到如何以一种可行的方式注入SELECT
语句。
几千个键很容易就太多了。我不确定您对子查询的关注是什么,但是它应该可以正常工作,只需将$list_substances
作为条件,例如:
->where(['substance_id IN' => $list_substances])