2010-08-03 2 views
3

PHP 5.3의 class_alias를 사용하여 Symfony 1.4 (Doctrine) 양식을 처리하는 데 도움이됩니다. 단일 액션을 사용하여 여러 폼 페이지를 처리하지만 switch 문을 사용하여 사용할 폼 클래스를 선택합니다.기능 테스트에서 PHP의 class_alias를 사용할 때 클래스를 다시 선언 할 때의 문제

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 응답을 다음과 같은 오류가 표시됩니다.

last request threw an uncaught exception RuntimeException: PHP sent a warning error at /.../apps/frontend/modules/.../actions/actions.class.php line 225 (Cannot redeclare class FormAlias)

이렇게하면 양식 제출을 테스트하는 것이 일반적으로 어렵습니다.

아마도 이것은 Symfony의 테스터가 동일한 방식으로 처리량을 정리하지 않았기 때문일 수 있습니다. 이러한 종류의 재 선언을 'unalias'또는 다른 방식으로 허용하는 방법이 있습니까?

답변

2

대체 솔루션으로서 당신은 변수와 새로운 것에 인스턴스화하는 클래스의 이름을 지정할 수 있습니다 :이 class_alias을 사용하지만 하나의 자리에 인스턴스화를 유지하지 않습니다

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

.

+0

깔끔함.그것이 가능하다는 것을 몰랐습니다. class_alias가 다소 중복 된 것처럼 보입니다. 성능 차이가 있다고 가정합니다. – kenneth

+0

class_alias는 별칭이 지정된 클래스 레코드를 유지해야하며 로컬 변수가 도입됩니다. 어떤 것이 더 많은 영향을 미치는지 모릅니다. 이유 때문에 class_alias가 5.3.0에 추가되어야하지만 하나는 생각할 수 없습니다. – Kwebble

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

이 방법으로 문제는 해결되지 않지만이 기능을 사용하면 오류가 발생하지 않습니다. 어쩌면 이것은 당신의 목적을 위해 충분할 것입니다.

+1

Jep, 당신은 완벽합니다. parsekit이나 classkit은 그런 방법이 없습니다. 내 대답에서 그 부분을 삭제했습니다. – NikiC

1

가능한지 확실하지 않지만 설명서에서 판단 할 때 아니오라고 말하고 싶습니다. 클래스가 별칭을 지정하면 클래스를 재설정하거나 다른 이름으로 다시 선언 할 수 없습니다. 그런데 다시 별칭을 사용하는 이유는 무엇입니까?

코드에서 각 추가 case 블록에서 앨리어싱을 수행한다고 가정합니다. 그렇다면 해당 블록에서 양식을 간단하게 인스턴스화 할 수 있습니다 (예 : class_alias를 사용하는 경우

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

당신은 어쨌든 스위치/케이스 블록에 클래스 이름을 하드 코딩되어있다. 그것을 사용하는 이점은 없습니다. 동적으로 처리하려면 '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를 만들 수도 있습니다. 당신이 Symfony Components DI Container를 사용하는 경우

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

, 당신은 또한 하드 코딩 공장 의존성을 없애 그냥 양식을 얻을 수있는 서비스 컨테이너를 사용할 수 있습니다. 그것은 가장 깨끗한 접근 방법이 될 것입니다. 기본적으로 class_alias을 사용하는 것은 나에게 여기에 부적절하다고 느낍니다.

+0

앨리어싱을 보이는 것보다 더 유용하게 만드는 예제에서 보여주지 않은 함수의 복잡성이 더 커졌습니다. 물론 매핑이 더 좋은 방법으로 처리됩니다. – kenneth