Php 使用Kohana 3.1.3中的接口
我正试图在科哈纳建立一个表单向导,并且在学习的过程中也学到了一些东西。我学到的最有效的方法之一是在我的类结构中使用状态模式来管理用户在表单处理过程中可以执行的不同步骤 在做了一些研究之后,我一直在想,最好的方法可能是使用一个接口,让所有的步骤都作为实现接口的状态。在状态验证之后,它会将会话变量更改为下一步,可以在接口的初始加载时读取该变量,并调用正确的状态来使用 这种方法有意义吗?如果是这样,我该如何实现它(如何最好地构造文件系统?) 这是我一直在努力的一个艰难的开始:Php 使用Kohana 3.1.3中的接口,php,oop,interface,kohana,Php,Oop,Interface,Kohana,我正试图在科哈纳建立一个表单向导,并且在学习的过程中也学到了一些东西。我学到的最有效的方法之一是在我的类结构中使用状态模式来管理用户在表单处理过程中可以执行的不同步骤 在做了一些研究之后,我一直在想,最好的方法可能是使用一个接口,让所有的步骤都作为实现接口的状态。在状态验证之后,它会将会话变量更改为下一步,可以在接口的初始加载时读取该变量,并调用正确的状态来使用 这种方法有意义吗?如果是这样,我该如何实现它(如何最好地构造文件系统?) 这是我一直在努力的一个艰难的开始: <?php def
<?php defined('SYSPATH') or die('No direct script access.');
/**
* Project_Builder @state
* Step_One @state
* Step_Two @state
**/
interface Project_Builder
{
public function do_this_first();
public function validate();
public function do_this_after();
}
class Step_One implements Project_Builder {
public function __construct
{
parent::__construct();
// Do validation and set a partial variable if valid
}
public function do_this_first()
{
echo 'First thing done';
// This should be used to set the session step variable, validate and add project data, and return the new view body.
$session->set('step', '2');
}
public function do_this_after()
{
throw new LogicException('Have to do the other thing first!');
}
}
class Step_Two implements Project_Builder {
public function do_this_first()
{
throw new LogicException('Already did this first!');
}
public function do_this_after()
{
echo 'Did this after the first!';
return $this;
}
}
class Project implements Project_Builder {
protected $state;
protected $user_step;
protected $project_data
public function __construct()
{
// Check the SESSION for a "step" entry. If it does not find one, it creates it, and sets it to "1".
$session = Session::instance('database');
if ( ! $session->get('step'))
{
$session->set('step', '1');
}
// Get the step that was requested by the client.
$this->user_step = $this->request->param('param1');
// Validate that the step is authorized by the session.
if ($session->get('step') !== $this->user_step)
{
throw new HTTP_Exception_404('You cannot skip a step!');
}
// Check if there is user data posted, and if so, clean it.
if (HTTP_Request::POST == $this->request->method())
{
foreach ($this->request->post() as $name => $value)
{
$this->project_data["$name"] = HTML::chars($value);
}
}
// Trigger the proper state to use based on the authorized session step (should I do this?)
$this->state = new Step_One;
}
public function doThisFirst()
{
$this->state = $this->state->do_this_first();
}
public function doThisAfter()
{
$this->state = $this->state->do_this_after();
}
}
$project = new Project;
try
{
$project->do_this_after(); //throws exception
}
catch(LogicException $e)
{
echo $e->getMessage();
}
$project = new Project;
$project->do_this_first();
$project->validate();
$project->do_this_after();
//$project->update();
您的方式看起来确实可行,但是我会尝试让它更简单,并使用一些Kohanas内置功能来满足您的需求。例如,我将使用Kostache(mustache)并为每个步骤提供单独的视图类(可能还有模板)。然后控制器变得非常简单。请参见下面的示例(缺少会话内容和步骤编号的验证)。所有验证都在模型中处理。如果存在验证错误,可以抛出异常,然后将错误消息传递回视图
<?php
class Wizard_Controller {
function action_step($step_number = 1)
{
$view = new View_Step('step_' + $step_number);
if ($_POST)
{
try
{
$model = new Model_Steps;
$model->step_number = $step_number;
if ($model->save($_POST))
{
// Go to the next step
$step_number++;
Request::current()->redirect('wizard/step/'.$step_number);
}
}
catch (Some_Kind_Of_Exception $e)
{
$view->post = $_POST;
$view->errors = $e->errors();
}
}
$view->render();
}
}
?>
希望这是有意义的。您基本上是在使用您可能已经发现的。在这个问题上你还需要帮助吗?我肯定有兴趣听到不同的方法。这是有意义的,我一直在思考这些问题,但是在我的控制器中验证后向会话添加元素确实让我的控制器膨胀了。仍然认为必须有一种更干净的做事方式。。。