使用PHP';功能测试中的s类_别名

使用PHP';功能测试中的s类_别名,php,symfony1,functional-testing,Php,Symfony1,Functional Testing,我正在使用PHP5.3的class_别名来帮助处理我的Symfony1.4(条令)表单。我使用单个操作处理多个表单页面,但使用switch语句选择要使用的表单类 public function executeEdit(sfWebRequest $request) { switch($request->getParameter('page')) { case 'page-1': class_alias('MyFormPage1Form', 'FormAlias');

我正在使用PHP5.3的class_别名来帮助处理我的Symfony1.4(条令)表单。我使用单个操作处理多个表单页面,但使用switch语句选择要使用的表单类

public function executeEdit(sfWebRequest $request) {
  switch($request->getParameter('page')) {
    case 'page-1':
      class_alias('MyFormPage1Form', 'FormAlias');
    break;
    ...
  }
  $this->form = new FormAlias($obj);
}
这在浏览网站时非常有效,但我的功能测试失败,因为当一个页面被多次加载时,如下所示:

$browser->info('1 - Edit Form Page 1')->

  get('/myforms/edit')->
  with('response')->begin()->
    isStatusCode(200)->
  end()->

  get('/myforms/edit')->
  with('response')->begin()->
    isStatusCode(200)->
  end();
我对第二个请求的响应为500,错误如下:

上一个请求引发了未捕获的异常RuntimeException:PHP在/../apps/frontend/modules/../actions/actions.class.PHP第225行发送了一个警告错误(无法将类重新声明为)

这使得测试表单提交(通常会发回给自己)非常困难

这大概是因为Symfony的测试人员没有以同样的方式清除吞吐量。 有没有办法“unalias”或以其他方式允许这种重新声明

function class_alias_once($class, $alias) {
    if (!class_exists($alias)) {
        class_alias($class, $alias);
    }
}

这并不能解决问题本身,但通过使用此函数,可以确保不会出现错误。也许这就足以满足您的需要。

我不确定这是否可行,但根据手册判断,我会说不。一旦类被别名化,就无法重置它或用其他名称重新声明它。但话说回来,为什么要使用别名呢

根据您的代码,我假设您在每个附加的
案例中执行别名处理。但是如果是这样,您也可以简单地在这些块中实例化表单,例如

public function executeEdit(sfWebRequest $request) {
  switch($request->getParameter('page')) {
    case 'page-1':
      $form = new MyFormPage1Form($obj);
    break;
    ...
  }
  $this->form = $form;
}
使用
class\u alias
时,您仍在将类名硬编码到开关/案例块中。使用它没有好处。如果您想动态地执行此操作,可以创建一个从“page”到“className”的数组映射,然后简单地查找适当的类

public function executeEdit(sfWebRequest $request) {
  $mapping = array(
      'page-1' => 'MyFormPage1Form',
      // more mappings
  );
  $form = NULL;
  $id = $request->getParameter('page');
  if(array_key_exists($id, $mapping)) {
       $className = $mapping[$id];
       $form = new $className($obj);
  }
  $this->form = $form;
}
这样,您还可以将整个映射放在一个配置文件中。或者你可以创建FormFactory

public function executeEdit(sfWebRequest $request) {
    $this->form = FormFactory::create($request->getParameter('page'), $obj);
}

如果您使用的是,还可以摆脱硬编码的工厂依赖关系,只使用服务容器获取表单。在我看来,这是最干净的方法。基本上,在这里使用
class\u别名对我来说不合适。

作为替代解决方案,您可以将要实例化的类的名称指定给一个变量和新的:

public function executeEdit(sfWebRequest $request) {
  $formType;
  switch($request->getParameter('page')) {
    case 'page-1':
      $formType = 'MyFormPage1Form';
    break;
    ...
  }
  $this->form = new $formType();
}

这不使用class_别名,但将实例化保留在一个位置。

Jep,你完全正确。parsekit和classkit都没有这样的方法。把那部分从我的答案中删掉了。我不知道这是可能的。似乎使类别名有些冗余。我假设存在性能差异。class_alias必须保留别名类的记录,这引入了一个局部变量。不知道哪个影响更大。class_alias添加到5.3.0中一定是有原因的,但我想不出原因。函数的复杂性比我在示例中没有展示的更高,这使得别名比看起来更有用。但是,可以肯定的是,映射看起来是更好的处理方法。