我已经烘焙了这个标准的添加类,它可以正常工作。
class ClientsController extends AppController
{
/**
* Add method
*
* @return \Cake\Network\Response|void Redirects on successful add, renders view otherwise.
*/
public function add()
{
$client = $this->Clients->newEntity();
if ($this->request->is('post')) {
$client = $this->Clients->patchEntity($client, $this->request->data);
if ($this->Clients->save($client)) {
$this->Flash->success(__('The client has been saved.'));
return $this->redirect(['action' => 'index']);
} else {
$this->Flash->error(__('The client could not be saved. Please, try again.'));
}
}
$this->set(compact('client'));
$this->set('_serialize', ['client']);
}
使用此add.ctp文件 - 输出应该是:
<div class="clients form large-9 medium-8 columns content">
<?= $this->Form->create($client) ?>
<fieldset>
<legend><?= __('Register Customer') ?></legend>
<?php
echo $this->Form->input('company_indicator');
echo $this->Form->input('name');
echo $this->Form->input('name2');
echo $this->Form->input('address_id');
echo $this->Form->input('address_street');
echo $this->Form->input('address_street_number');
echo $this->Form->input('address_postal_code');
echo $this->Form->input('address_city');
echo $this->Form->input('address_country');
echo $this->Form->input('address_lat');
echo $this->Form->input('address_lng');
echo $this->Form->input('phone1');
echo $this->Form->input('phone2');
echo $this->Form->input('fax');
echo $this->Form->input('website');
echo $this->Form->input('logo');
echo $this->Form->input('vat_number');
echo $this->Form->input('taxId');
echo $this->Form->input('tax_office');
?>
</fieldset>
<?= $this->Form->button(__('Submit')) ?>
<?= $this->Form->end() ?>
</div>
我尝试使用向导步骤
class ClientsController extends AppController
{
/**
* use beforeRender to send session parameters to the layout view
*/
public function beforeRender(Event $event) {
parent::beforeRender($event);
$params = $this->request->session()->read('Form.params');
$this->set(compact('params'));
}
/**
* delete session values when going back to index
* you may want to keep the session alive instead
*/
public function regIndex() {
$this->request->session()->delete('Form');
}
/**
* this method is executed before starting
* the form and retrieves one important parameter:
* the form steps number by counting the number
* of files that start with reg_step
*/
public function regSetup() {
$clientsViewFolder = new Folder(APP.'Template'.DS.'Clients');
$steps = count($clientsViewFolder->find('reg_step.*\.ctp'));
$this->request->session()->write('Form.params.steps', $steps);
$this->request->session()->write('Form.params.maxProgress', 0);
$this->redirect(array('action' => 'regStep', 1));
}
/**
* this is the core step handling method
* it gets passed the desired step number, performs some checks to prevent smart users skipping steps
* checks fields validation, and when succeding, it saves the array in a session, merging with previous results
* if we are at last step, data is saved
* when no form data is submitted (not a POST request) it sets this->request->data to the values stored in session
*/
public function regStep($stepNumber) {
$this->log('regStep($stepNumber)= ' . $stepNumber , 'debug');
/**
* check if a view file for this step exists, otherwise redirect to index
*/
if (!file_exists(APP.'View'.DS.'Clients'.DS.'reg_step'.$stepNumber.'.ctp')) {
$this->redirect('/clients/reg_index');
}
$session = $this->request->session();
/**
* determines the max allowed step (the last completed + 1)
* if choosen step is not allowed (URL manually changed) the user gets redirected
* otherwise we store the current step value in the session
*/
$maxAllowed = $this->request->session()->read('Form.params.maxProgress') + 1;
if ($stepNumber > $maxAllowed) {
$this->redirect('/clients/reg_step/'.$maxAllowed);
} else {
$session->write('Form.params.currentStep', $stepNumber);
}
$client = $this->Clients->newEntity();
$client->name = 'Tiknas';
/**
* check if some data has been submitted via POST
* if not, sets the current data to the session data, to automatically populate previously saved fields
*/
if ($this->request->is('post')) {
/**
* set passed data to the model, so we can validate against it without saving
*/
$client = $this->Clients->patchEntity($client, $this->request->data);
/**
* if data validates we merge previous session data with submitted data, using CakePHP powerful Hash class (previously called Set)
*/
if ($this->Client->validates($client)) {
$prevSessionData = $session->read('Form.data');
$currentSessionData = Hash::merge( (array) $prevSessionData, $this->request->data);
/**
* if this is not the last step we replace session data with the new merged array
* update the max progress value and redirect to the next step
*/
if ($stepNumber < $session->read('Form.params.steps')) {
$session->write('Form.data', $currentSessionData);
$session->write('Form.params.maxProgress', $stepNumber);
$this->redirect(array('action' => 'reg_step', $stepNumber+1));
} else {
/**
* otherwise, this is the final step, so we have to save the data to the database
*/
if ($this->Client->save($currentSessionData))
{
$this->Flash->success(__('Customer created!'));
return $this->redirect('/clients/reg_index');
} else {
$this->Flash->error(__('The client could not be saved. Please, try again.'));
}
}
}
} else {
$this->request->data = $session->read('Form.data');
}
$this->set(compact('client'));
$this->set('_serialize', ['client']);
/**
* here we load the proper view file, depending on the stepNumber variable passed via GET
*/
$this->render('reg_step'.$stepNumber);
}
}
使用此reg_step1.ctp文件会导致错误:
<div class="clients form large-9 medium-8 columns content">
<?= $this->Form->create($client) ?>
<fieldset>
<legend><?= __('Register Customer') ?></legend>
<?php
echo $this->Form->input('company_indicator');
echo $this->Form->input('name');
echo $this->Form->input('name2');
echo $this->Form->input('address_id');
echo $this->Form->input('address_street');
echo $this->Form->input('address_street_number');
echo $this->Form->input('address_postal_code');
echo $this->Form->input('address_city');
echo $this->Form->input('address_country');
echo $this->Form->input('address_lat');
echo $this->Form->input('address_lng');
echo $this->Form->input('phone1');
echo $this->Form->input('phone2');
echo $this->Form->input('fax');
echo $this->Form->input('website');
echo $this->Form->input('logo');
echo $this->Form->input('vat_number');
echo $this->Form->input('taxId');
echo $this->Form->input('tax_office');
?>
</fieldset>
<?= $this->Html->link('Next step',
array('action' => 'reg_step', $params['currentStep'] + 1),
array('class' => 'button')); ?>
<?= $this->Form->end(); ?>
</div>
错误明细
==&GT;无效的数据类型,必须是数组或\ ArrayAccess实例。 ==&GT; InvalidArgumentException
⟩Cake \ View \ Helper \ FormHelper-&gt;输入 APP / Template \ Clients \ reg_step1.ctp,第9行 这对应于这一行 echo $ this-&gt; Form-&gt; input(&#39; company_indicator&#39;);
我尝试了同样的评论这一行,但我得到了同样的错误。
我检查了两个示例中为空的$ client。 (YES $ client是一个实体)
我搜索了这个错误,但发现只有HASH错误与这种情况无关。控制器中一定有错误,但我找不到它。为什么在此上下文中引发此错误?我在哪里搜索才能找到真正的问题?有什么想法吗?
StackTrace:
2016-02-15 21:50:50 Error: [InvalidArgumentException] Invalid data type, must be an array or \ArrayAccess instance.
Request URL: /pam/clients/reg-step/1
Referer URL: http://localhost/pam/clients/regIndex
Stack Trace:
#0 C:\Users\D052192\OneDrive\xampp\htdocs\pam\vendor\cakephp\cakephp\src\Network\Request.php(1158): Cake\Utility\Hash::get(NULL, 'company_indicat...')
#1 C:\Users\D052192\OneDrive\xampp\htdocs\pam\vendor\cakephp\cakephp\src\View\Form\EntityContext.php(208): Cake\Network\Request->data('company_indicat...')
#2 C:\Users\D052192\OneDrive\xampp\htdocs\pam\vendor\cakephp\cakephp\src\View\Helper\FormHelper.php(2385): Cake\View\Form\EntityContext->val('company_indicat...')
#3 C:\Users\D052192\OneDrive\xampp\htdocs\pam\vendor\cakephp\cakephp\src\View\Helper\FormHelper.php(1387): Cake\View\Helper\FormHelper->_initInputField('company_indicat...', Array)
#4 C:\Users\D052192\OneDrive\xampp\htdocs\pam\vendor\cakephp\cakephp\src\View\Helper\FormHelper.php(1115): Cake\View\Helper\FormHelper->checkbox('company_indicat...', Array)
#5 C:\Users\D052192\OneDrive\xampp\htdocs\pam\vendor\cakephp\cakephp\src\View\Helper\FormHelper.php(1023): Cake\View\Helper\FormHelper->_getInput('company_indicat...', Array)
#6 C:\Users\D052192\OneDrive\xampp\htdocs\pam\src\Template\Clients\reg_step1.ctp(9): Cake\View\Helper\FormHelper->input('company_indicat...', Array)
#7 C:\Users\D052192\OneDrive\xampp\htdocs\pam\vendor\cakephp\cakephp\src\View\View.php(992): include('C:\\Users\\D05219...')
#8 C:\Users\D052192\OneDrive\xampp\htdocs\pam\vendor\cakephp\cakephp\src\View\View.php(952): Cake\View\View->_evaluate('C:\\Users\\D05219...', Array)
#9 C:\Users\D052192\OneDrive\xampp\htdocs\pam\vendor\cakephp\cakephp\src\View\View.php(587): Cake\View\View->_render('C:\\Users\\D05219...')
#10 C:\Users\D052192\OneDrive\xampp\htdocs\pam\vendor\cakephp\cakephp\src\Controller\Controller.php(611): Cake\View\View->render('reg_step1', NULL)
#11 C:\Users\D052192\OneDrive\xampp\htdocs\pam\src\Controller\ClientsController.php(250): Cake\Controller\Controller->render('reg_step1')
#12 [internal function]: App\Controller\ClientsController->regStep('1')
#13 C:\Users\D052192\OneDrive\xampp\htdocs\pam\vendor\friendsofcake\crud\src\Controller\ControllerTrait.php(51): call_user_func_array(Array, Array)
#14 C:\Users\D052192\OneDrive\xampp\htdocs\pam\vendor\cakephp\cakephp\src\Routing\Dispatcher.php(114): App\Controller\AppController->invokeAction()
#15 C:\Users\D052192\OneDrive\xampp\htdocs\pam\vendor\cakephp\cakephp\src\Routing\Dispatcher.php(87): Cake\Routing\Dispatcher->_invoke(Object(App\Controller\ClientsController))
#16 C:\Users\D052192\OneDrive\xampp\htdocs\pam\webroot\index.php(37): Cake\Routing\Dispatcher->dispatch(Object(Cake\Network\Request), Object(Cake\Network\Response))
#17 {main}
答案 0 :(得分:4)
查看堆栈跟踪,请求数据(Request::$data
)为null
,而Hash::get()
不喜欢这样。
问题源于您的第二次$session->read('Form.data')
调用,在某些时候该值尚不存在/不再存在,因此该方法将返回null
,并且您将使用它覆盖请求数据
根据您的向导逻辑的适用性,确保您要么检索一个空数组(就像您在第一次调用时所做的那样),或者在这些情况下不要覆盖请求数据。