2009-11-26 6 views
1

클래스를 만들었습니다. 나는 어떤 객체 (대부분 retreived 데이터베이스 행)를 입력으로 보여주고, 어떤 필드를 보여야하는지, 그리고 원하는 버튼을 말해 준다. 다음 그것은 아주 좋은 html 테이블을 렌더링합니다! 꽤 굉장한 것 같아요.PHP : 클래스에 함수 전달

$ot = new ObjectTable(); 
$ot->objects = $some_objects; 
$ot->fields = array('id','name','description','image'); 
$ot->buttons = array('edit','delete'); 
$ot->render(); 

그러나 나는 또한 보여주는 데이터를 조작 할 수 있기를 원합니다. 예를 들어, '설명'필드를자를 수 있기를 원합니다. 또는 'picture.jpg'대신 텍스트로 이미지 축소판을 표시 할 수 있습니다. 이러한 함수를 클래스에 전달하는 방법을 모르겠습니다. 아마도 같은 :

$ot->functions = array(null,null,'truncate','thumbnail'); 

는하지만 좀 실제 코드, 또는 방법 매개 변수를 전달하는 방법을 실행하기 위해 이러한 문자열을 변환하는 방법을 모르겠어요.

내가 원하는 것을 수행하는 좋은 방법이 있어야합니다. 방법?

답변

7

확인이 question과 대답은 :

PHP5.3의로서 당신은 주위 방법 을 통과 closures or functors를 사용할 수 있습니다. 그 전에는 create_function()이라는 익명의 함수를 이라고 쓸 수도 있지만, 다소 어색하다. .

하지만 필터 오브젝트를 렌더러에 전달하면 가장 잘 해결할 수 있습니다. 모든 필터는 동일한 방법을 사용해야하므로 전략 패턴 방식으로 사용할 수 있습니다 (예 :먼저 인터페이스를 쓰기 :

interface Filter 
{ 
    public function filter($value); 
} 

그런

public function addFilter($field, Filter $filter) 
{ 
    if(in_array($field, $this->fields)) { 
     $this->_filters[$field][] = $filter; 
    } 
    return $this; 
} 

을 필터를 허용하도록 인터페이스

class TruncateFilter implements Filter 
{ 
    protected $_maxLength; 
    public function __construct($maxLength = 50) 
    { 
     $this->_maxLength = (int) $maxLength; 
    } 
    public function filter($value) 
    { 
     return substr(0, $this->_maxLength, $value) . '…'; 
    } 
} 

당신의 ObjectTable을 부여를하는 방법을 구현하는 필터를 작성하고 당신은 당신의 ObjectTable 인스턴스화, 사용을 수행 할 때

$ot = new ObjectTable(); 
$ot->objects = $some_objects; 
$ot->fields = array('id','name','description','image'); 
$ot->addFilter('description', new TruncateFilter) 
    ->addFilter('name', new TruncateFilter(10)) 
    ->addFilter('image', new ThumbnailFilter); 

그런 다음 render() 메서드를 수정하여 렌더링 할 필드에 대해 설정된 필터가 있는지 확인하고 해당 필드에 filter() 메서드를 호출합니다.

public function render() 
{ 
    foreach($this->fields as $field) { 
     $fieldValue = // get field value somehow 
     if(isset($this->filters[$field])) { 
      foreach($this->filters[$field] as $filter) { 
       $fieldValue = $filter->filter($fieldValue) 
      } 
     } 
     // render filtered value 
    } 
} 

이렇게하면 무한한 필터를 추가 할 수 있습니다.

+0

와우, 대단한 답장. 고마워요! – tape2

+0

당신은 환영합니다 :) – Gordon

2

당신은 create_function()을 찾고 있습니다.

그러나 런타임에 함수를 만들고 클래스에 추가하면 나에게 소리가 들리지 않습니다. 그것은 매우 빠르게 유지 보수의 악몽이 될 가능성이 있습니다. 원하는 것을 성취 할 수있는 더 좋은 방법이 있습니다. 어떤 종류의 조작이 데이터에 작용할 것인가? 그것들을 "tools"클래스에 저장하고 필요한 경우 테이블 객체와 연결하는 방법은 어떻습니까?

2

$ functions = array (null, null, 'truncate', 'thumbnail');
$ function_1 = $ functions [3];
$ my_string = '줄 바꿈 할 문자열';

$ result = call_user_func ($ functions [2], $ my_string);

여러 매개 변수를 전달하려면 call_user_func_array를 대신 사용하십시오.

3

PHP에는 pseudo-type called "callback"이 있으며, 실제로는 위장시에 못생긴 폐쇄입니다. 당신은 call_user_func() 또는 call_user_func_array()를 사용하여 이러한 콜백을 호출 할 수 있습니다

$callback = 'strlen'; 
echo call_user_func($callback, '123'); 
// will output 3 (unless you're using a strange encoding) 
+0

고든 (Gordon)이 정확하게 지적했듯이, PHP 5.3은 이제 못생긴 클로저를 사용합니다. 나는 PHP 5.2에 붙어 있기 때문에 완전히 잊어 버렸습니다. – soulmerge

1

당신은 또한 당신의 이름을 나타내는 문자열을 기반으로 함수를 호출 할 수있는 call_user_func을 탐험 할 수 있습니다.

+0

Damnit, 다시 맞습니다! – Skilldrick