3

我正在使用 PHP 5.3 的 class_alias 来帮助处理我的 Symfony 1.4 (Doctrine) 表单。我使用单个操作来处​​理多个表单页面,但使用 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 行发送了一个警告错误(无法重新声明类 FormAlias)

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

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

4

3 回答 3

2

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

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

这不使用 class_alias 而是将实例化保持在一个位置。

于 2010-08-03T11:32:08.473 回答
1

我不确定是否可能,但从手册来看,我会说不。一旦类被别名,就无法重置它或用不同的名称重新声明它。但是话又说回来,为什么要使用别名呢?

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

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

无论如何,在使用class_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);
}

如果你使用Symfony Components DI Container,你也可以摆脱硬编码的工厂依赖,只使用服务容器来获取表单。这将是 IMO 最干净的方法。基本上,class_alias在我这里使用只是感觉不合适。

于 2010-08-03T10:54:56.127 回答
0
function class_alias_once($class, $alias) {
    if (!class_exists($alias)) {
        class_alias($class, $alias);
    }
}

这本身并不能解决问题,但是通过使用此功能可以确保您不会收到错误。也许这足以满足您的目的。

于 2010-08-03T10:51:15.617 回答