将用户提供的(但与模型无关的)参数传递给控制器


Pass user-supplied (but unrelated to the model) parameters to the controller?

在维护用CakePHP 1.3编写的应用程序时出现了这个问题。请记住,虽然我可以并且确实阅读了文档,但我使用Cake的经验相当有限。

应用程序有一个Widget模型和一个WidgetController。在编辑Widget时,用户的一个选择是通过以下三种模式中的一种将数据大量导入到Widget中:添加、删除或用导入的数据替换小部件数据。

当前的实现是一个完全混乱的(有一个"编辑"的行动,执行所有的10个左右不同的突变功能的窗口小部件支持;它通过嗅探提交的表单中的参数来决定要做什么),所以我把"大量的东西"分解成一个新的动作:

function batch($id)
{
    // massively apply data to Widget $id; either add, remove or replace
}

这个动作是由edit视图中的表单触发的:

// Only relevant elements shown
echo $form->create('Widget', array('enctype'=>'multipart/form-data', 'action' => 'batch')); ?>
echo $form->input('id');
echo $form->input('action', array('type'=>'select',
    'options'=>array(
        'append'=>__('Append', true), 
        'replace'=>__('Replace existing', true), 
        'delete'=>__('Delete specified', true)
    ));
echo $form->end(); ?>

实际上,这个表单将action参数捆绑到Widget数组中,我可以从控制器获得它的唯一方法是使用$this->data['Widget']['action']

这是丑陋的和语义错误的,所以我希望有一个更好的方法来做到这一点。

理想情况下,我想提交到URL /widget/batch/X/append,但这是不可能的,因为append部分不固定。所以我就用这些来解决:

  • 以某种方式将动作作为控制器参数传递,如$id
  • 以某种方式传递动作作为命名参数,允许$this->params['named']['action']
  • 不需要安装自定义路由,也不需要JavaScript的其他方式

Cake 1.3能做到吗?

no不能根据post参数将请求路由到不同的操作,也不能单独使用PHP更改表单的操作。这对于任何框架来说都是一样的。

理想情况下,我想提交到URL/widget/batch/X/append,但这是不可能的,因为append部分不是固定的。

唯一的方法是使用javascript -当然,编写一些适当的js来做到这一点并不难。

然而

如果你不想在用户改变他们的选择时使用javascript来操作表单动作,或者只是想要最简单的解决方案——你可以使用setAction在内部将请求重定向到更合适的、专用的控制器动作:

function batch() {
    if (!empty($this->data['Widget']['action'])) {
        $this->setAction($this->data['Widget']['action']);
    }
}
function append() {
    if ($this->data) {
        if ($this->Widget->append($this->data)) {
            $this->Session->setFlash('Widget appended successfully');
        } else {
            $this->Session->setFlash('Error: Unable to append widget');
        }
    }
}

通过这种方式,您可以将现有代码重构为更易于管理和逻辑的方法。