我们有一个 CakePHP 3.x 应用程序,我们已将其更新到最新的 CakePHP 4.x。作为这项工作的一部分,我们还从 PHP 7 更改为 PHP 8。
在测试应用程序时,我们注意到一个功能已停止工作。
该应用程序是一个可搜索的数据库,并与 Redis 集成以进行缓存。其中一项功能意味着用户搜索在页面重新加载之间得以保留。这是通过将序列化表单数据写入 Redis,然后将其重新填充回模板中的 input
字段来实现的。这意味着用户可以看到他们输入的搜索条件;刷新页面时,他们不需要重新输入搜索条件。
CakePHP 3.x 应用程序中重新填充 input
表单字段的代码如下所示:
$form_fields = ['f1', 'f2', 'f3'];
$form_fields
数组包含模板中 input
表单的名称。举个例子:
<input type="text" name="f1">
代码的下一部分重新填充表单。在本例中,$user_search
是从 Redis 获取并反序列化的数据数组。例如,我们可能有 $user_search['f1']
和 $user_search['f3']
包含 Redis 数据; f2
未填充,因为用户没有使用该字段进行搜索。
foreach ($form_fields as $form_field) { $this->request->getData()[$form_field] = (isset($user_search[$form_field])) ? $user_search[$form_field] : ''; }
在 Cake 3.x 应用程序中,上述工作正常。当页面重新加载时,表单字段由于设置请求数据而设置,例如在上面的循环中,它的计算结果为:
$this->request->getData()['f1'] = 'foo'; $this->request->getData()['f3'] = 'bar';
这意味着请求数据的“foo”为 f1
,“bar”为 f3
。 f2
中没有任何内容,因此根据 : '';
条件将其设置为空字符串。
在 CakePHP 4.x 应用程序中,这不起作用;页面重新加载时,所有表单字段均未填充。我已经通过将上面提到的 : '';
条件修改为 : 'test';
来确认它们没有被设置为空字符串,并确保字符串“test”没有显示在字段中。 p>
数据存在于 Redis 中,并且我已经确认 $user_search
包含上面显示的内容 - 换句话说,数据没有丢失,所以我们已经排除了这一点。
当我阅读 https://book.cakephp.org/4/en/controllers/request-response.html 时,我看不到设置请求数据的示例。有一个方法 getData()
可以实现您所期望的功能 - 它读取请求数据。
有没有办法在 Cake 4.x 中设置请求数据,以便上面的代码可以工作?
在普通 PHP 中,我们所做的相当于
$_POST['f1'] = 'foo'; $_POST['f2'] = ''; // empty string as no value set by user $_POST['f3'] = 'bar';
据我所知,这在 PHP 中曾经并且仍然有效;您可以使用代码中的任何内容设置/覆盖请求数据。如果这是错误的,请告诉我应该做什么。
为了清楚起见,我们以这种方式设置请求数据的原因是因为搜索是通过 ajax 调用进行的。当用户最初输入搜索条件时,页面尚未重新加载,因此表单字段似乎已正确填充。此问题发生在页面重新加载时。在这种情况下,我们希望使用他们在重新加载页面之前输入的值重新填充表单。
您正在寻找的函数是
withData
。请记住,请求对象是不可变的,因此您需要将该函数调用的结果分配回请求对象,例如与$this->setRequest($this->getRequest()->withData('f1', 'foo')->withData('f3', 'bar'))
。