문제

나는 객체 지향 프로그래밍에 비교적 처음입니다. 나는 개념을 거의 이해하지만 실제로 말하면 Zend 프레임 워크 응용 프로그램에서 모델을 가장 잘 사용하는 방법에 대한 정보를 찾는 데 어려움을 겪고 있습니다.

구체적으로 데이터베이스 테이블을 사용하지 않는 모델 (아무것도 확장하지 않음)이 있습니다. Getters와 Setter를 사용하여 보호 된 회원에 액세스합니다. 나는이 모델을보기에 가장 잘 표시하는 방법에 어려움을 겪고 있습니다. 내 뷰 템플릿에서 논리를 원하지 않지만 다음 상황에서 나 자신을 발견합니다.

내 컨트롤러에서 :

$object = new Object();
$object->setName('Foo Bar');
$this->view->object = $object;

내보기 템플릿에서 :

<h2><?= $this->object->getName() ?></h2>

나는 내 뷰 템플릿에서 함수를 호출하는 것을 좋아하지 않지만 더 나은 방법을 모릅니다. 나는 내 모델의 회원이 공개되는 것을 원하지 않지만 기본적으로 동일한 결과를 얻고 싶습니다.

<h2><?= $this->object->name ?></h2>

나는 컨트롤러가 모델에 대한 모든 것을 알아야하는 모든 작업을 수행하기를 원하지 않습니다.

$object = new Object();
$object->setName('Foo Bar');
$this->view->object = $object;
$this->view->object->name = $object->getName();

Zend 프레임 워크에서 모델을 사용하는 모범 사례는 무엇입니까? Zend 프레임 워크 에서이 모델/보기 딜레마를 이해하는 데 도움이되는 튜토리얼을 추천 할 수 있습니까?

도움이 되었습니까?

해결책

한 가지 가능성은 Php에서 Magic __s 및 __get 메소드를 사용하는 것입니다. 나는 추상 모델 클래스 내에서 그렇게 사용합니다.

abstract class Model_Abstract
{
    protected $_data;

    // Private Data Members assigned to protected $_data
    public function __construct($data = null)
    {
        // Makes it so that I can pass in an associative array as well as 
        // an StdObject.
        if(!is_object($data)) {
            $data = (object) $data;
        }

        $this->_data = $data;

    }

    public function __get($key)
    {
        if (method_exists($this, '_get' . ucfirst($key))) {
            $method = '_get' . ucfirst($key);
            return $this->$method();            
        }
        else {
            return $this->_data->$key;
        }   
    }

    public function __set($key, $val)
    {
        if ( method_exists( $this, '_set' . ucfirst($key) ) ) {
            $method = '_set' . ucfirst($key);
            return $this->$method($val);            
        }
        else {
            $this->_data->$key = $val;
            return $this->_data->$key;
        }
    }
}


class Model_User extends Model_Abstract
{
    //Example overriding method for the property firstName in the $_data collection.
    protected function _getFirstName()
    {
        // Do some special processing and then output the first name.
    }
}

이렇게하면 필요에 따라 속성에 대한 Getters 및 Setter를 지정할 수 있지만 모든 속성에 대해 보일러 플레이트 기능을 정의 할 필요가 없도록합니다. 값. 예를 들어, 여러 장소에서 기능을 사용하여 ISO 준수 날짜 (MySQL에 저장된대로)를 사용자에게보다 작고 읽을 수있는 형식으로 변경합니다.

컨트롤러에 무엇을 배치 해야할지까지는 보는 것이 좋습니다. 이 게시물 컨트롤러 내에 배치 할 취급에 대한 구체적인 피드백.

어떤 사람들은 오히려 모델을 뷰에 자동으로로드하고 컨트롤러를 모두 스커트하는 도우미가 있다고 생각합니다. 개인적으로 나는 Zend 프레임 워크와 PHP의 맥락에서 모델의 상태가 종종 요청에서 나온 것에 의존하기 때문에 컨트롤러에서 모델을 전달하는 것이 의미가 있다고 말합니다 (확실히 처리해야합니다. 컨트롤러에서).

업데이트: 의견의 비판에 따르면, 내가 지적 할 한 가지는 데이터베이스 액세스 계층과 도메인 (또는 모델) 레이어가 실제로 두 가지 다른 것이지만 활성 레코드는 함께 혼합되어 있다는 것입니다. 나는 물었다 이 질문 얼마 전과이 문제에 대한 유용한 피드백을 받았습니다. 모델과 관련하여 무엇을 하든지 모델의 데이터가 출처하는 위치에 관계없이 모든 도메인 객체에 대해 일관된 API를 제공하려고합니다.

SAEM의 답변에 의해 제공되는 한 가지 이점은 하나 이상의 도메인 객체에서 뷰 개체에 속성 / 기능 반환 값을 직접 매핑하는 기능을 제공한다고 가정합니다. 이론적으로보기 내의 사용은 다음과 같습니다.

// Mapped from Model_User::_data->last_name and Model_User::_data->first_name
$this->name 

다른 팁

다른 개발자 만 템플릿으로 작업하려는 경우 모델을 통과하는 것이 좋습니다. 다음은 MVC의 Jeff Atwood 게시물에 대한 링크입니다. 모델-뷰 컨트롤러 이해

This isn't particularly geared towards zend framework, but the problem is rather general, in my mind.

It seems you're on the right path, instead of hard wiring the model to the view, inside the controller. You'd rather have that abstract, especially important if you're mapping a tonne of models, or mapping the same model over and over again.

Something simple would be to write a bunch of mapping functions, which would be fine if all you were avoiding is mapping the same thing over and over.

If you wanted a more general solution, that also addressed avoid writing that boiler plate code, and keeping things more DRY, I suggest creating a mapper class.

You could create a ViewModelMapper, which would take a model, or a few models and map them to the view.

class ViewModelMapper
{
    public function __construct($view)
    {
        //set the properties
    }

    public function addModel($model, $overrideViewProperty = null)
    {
        //add the model to the list of models to map, use the view's property 
        // name to figure out what to map it to? Allow for an override just in case.
    }

    public function getMappedView()
    {
        //take the view, map all the models
    }
}

You could then instance this on your controller, and setup the mappings, so the controller controls the mapping still, but all the boiler plate and coding logic is centralized, for all controller maps, except for the rare exceptions.

For a good read on model architecture, read this post. It doesn't specifically talk about the view, but it's definitely worth reading.

I ended up adding a getViewClass() function to my models. The controller calls this function to get the protected variables it wouldn't otherwise have access to, and the view doesn't have to worry about calling any getters.

//controller
$object = new Object();
$object->setName('Foo Bar');
$this->view->object = $object->getViewClass();

//view template
<h2><?= $this->object->name ?></h2>

I don't know if there is a better way to get the job done in the Zend Framework, but this is one solution.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top