我的下面的代码有效,问题是效率不高。
背景
用户可以从电子表格上传数据,以填充我正在处理的应用。 它们上载的几个字段存在于表中,用于根据需要填充视图中的选择框或字段。 例如。国家表
+----+---------+
| id | country |
+----+---------+
| 1 | UK |
| 2 | France |
+----+---------+
电子表格中的数据不是用户友好的ID,因此在电子表格中他们会写文字' UK' France'或者如果他们可以使用ID所以选择,但如果他们通过应用程序中的Web表单编辑数据,将使用ID。
在上传过程中,我将数据排列到一个数组中,其中每个条目都是一个可以验证的新实体,然后我通过Cake的验证器进程传递它。对于上述字段,我有一个自定义验证器,用于检查ID是否存在,或者文本是否与文本字段完全匹配。
代码
验证数据的函数存在于Uploads模型中,并在数据排列后调用(此处不包括在内):
// src/Model/Table/UploadsTable.php
protected function _validateData(array $data) {
$Validator = TableRegistry::get('Laws')->getValidator('Upload');
$validation = [];
foreach( $data as $key => $row) {
$validation[$key] = $Validator->errors($row);
}
return $validation;
}
Laws模型中的验证者
// src/Model/Table/LawsTable.php
public function validationUpload(Validator $validator)
{
$validator = $this->validationDefault($validator);
$validator->setProvider("CustomValidator",\App\Model\Validation\CustomValidator::class);
$validator
->scalar('country_id')
->requirePresence('country_id')
->add('country_id', 'country', [
'rule' => 'country',
'provider' => 'CustomValidator',
'message' => 'Country value not in accepted list.'
]);
}
在自定义验证器
中// src/Model/Validation/CustomValidator.php
class CustomValidator extends Validator
{
public function __construct() {
parent::__construct();
}
public static function country($data) {
$table = TableRegistry::get('Countries')->find()->toArray();
$idKey = array_column($table, 'country','id');
$fieldKey = array_column($table, 'id', 'country');
if(in_array($data, $idKey) || in_array($data, $fieldKey)) {
return true;
}
return false;
}
}
问题
问题是,当用户上传电子表格时,可能有500行,而且我有几个字段遵循此方法。当执行这个脚本时,我得到几千个SQL查询,因为每行调用这些静态函数。领域。
对我来说,明显的解决方案是从方法中删除find()查询,并找到将结果传递给方法的方法,以便脚本的其余部分工作。但我不知道如何提取它们以及将这种数据收集在Cake工作流程中的位置,因为它们被静态调用。