2012-12-10 2 views
1

클래스에 대한 이벤트 처리기를 만들고 있지만 코드 평가 대신 클로저를 사용하는 것이 더 나은지 궁금합니다.eval() 대신 이벤트 처리를 위해 클로저를 사용하는 것이 더 좋습니까?

eval()을 사용하는 유일한 이유는 클래스 내의 모든 항목에 액세스 할 수 있기 때문입니다 (실제로는 안전하지 않습니다 : D).하지만 클로저가 할 수 있는지 여부는 알 수 없습니다.

나는 이런 식으로 뭔가 한 경우 :

<?php 
    class SomethingCool { 
     protected $handlers; 

     public function addHandler($cmd, closure $func) { 
      $this->handlers[$cmd][] = $func; 
     } 

     public function handle($cmd) { 
      if(!isset($this->handlers[$cmd])) 
       return false; 
      foreach($this->handlers[$cmd] as $func) 
       $func(); 
     } 
    } 
?> 

<?php 
    $wut = new SomethingCool(); 
    $wut->addHandler('lol', function() use($wut) { 
           $wut->handle('lol'); 
          } 
        ); 
?> 

가 오류없이 실행할 것인가를? 나는 그것을 스스로 시험 할 것이지만, 나는 그 순간에 할 수 없다.

+0

'unset' 참조 해제로 인한 명백한 오류 외에도 ... –

+0

'$ this'는 무엇을 참조해야합니까? –

+0

참고 : http://php.net/manual/en/functions.anonymous.php#107949 –

답변

2

당신이 eval를 사용하여 핸들러를 작성하는 경우는 다음과 같이 코드를 작성하게 될 겁니다 :

탈출 시세 및 편집기에서 강조 깨진 구문을 분명히 끔찍한 문제에서 별도로
$wut->addHandler('lol', '$this->handle(\'lol\');'); 

는,이 문제를 소개합니다 모호한 의존성. 귀하의 코드에서 $this은 무엇을 말합니까? 코드에서와 같이 그대로 작동하지는 않습니다. 특정 컨텍스트 내에서 평가되는 것에 달려 있습니다. 이것은 코드를 진짜 엉망으로 만든다. 이 핸들러가 호출되면

$wut->addHandler('lol', function (SomethingCool $sc) { 
    $sc->handle('lol'); 
}); 

SomethingCool 함수 인수 자체를 주입하는 것이다

대안 의존성 주입된다. 그보다 훨씬 강력합니다. 즉,이 콜백을 다른 컨텍스트로 전달할 수 있고 원하는 것을 무엇이든 할 수 있다는 것을 의미합니다. 콜백은 더 이상 특정 컨텍스트 내에서 평가되는 것에 의존하지 않습니다.

는 다른 방법으로, 클로저를 사용

$wut->addHandler('lol', function() use ($wut) { 
    $wut->handle('lol'); 
}); 

이것은 당신이 당신의 의존성이 어디에서 오는지 확인되고 당신이 그것을에 따라 달라질 수 있음을 알 같은 이점이 있습니다.

그렇습니다. 무엇이든eval보다 좋습니다.

+0

우, 그게 가장 좋은 방법 같아. 입력 dewd에 감사드립니다, 나는 집에있을 때 이것을 테스트 할 것입니다. LOL 예, 내가 왜 eval()을 떠나고 싶다고 생각하니? 그것은 악합니다. –

+0

위대한 작품! 고마워 친구. –

+0

OP가 아직 upvote 수 없습니다 ... +1 :) –

0

SomethingCool의 인스턴스를 각 처리기로 전달하지 않는 이유는 무엇입니까? 당신은 또한 핸들러를 제거 할 수 있도록하려면

public function handle($cmd) 
{ 
    if (!isset($this->handlers[$cmd])) { 
     return; 
    } 
    foreach ($this->handlers[$cmd] as $func) 
     $func($this); // pass ourself to each handler 
    } 
} 

$wut->addHandler('lol', function(SomethingCool $obj) { 
    // $obj refers to the SomethingCool instance 
}); 

$wut->handle('lol'); 

, BTW, 당신은 또한 각 명령의 범주에 대한 SplObjectStorage를 사용할 수 있습니다.

관련 문제