我們有一個 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 應用程序中,上述工作正常。當頁面重新加載時,表單字段由于設置請求數據而設置,例如在上面的循環(huán)中,它的計算結果為:
$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 調用進行的。當用戶最初輸入搜索條件時,頁面尚未重新加載,因此表單字段似乎已正確填充。此問題發(fā)生在頁面重新加載時。在這種情況下,我們希望使用他們在重新加載頁面之前輸入的值重新填充表單。
您正在尋找的函數是withData
。請記住,請求對象是不可變的,因此您需要將該函數調用的結果分配回請求對象,例如與$this->setRequest($this->getRequest()->withData('f1', 'foo')->withData('f3', 'bar'))
。