PHP how to implement the Data Mapper pattern in MVC

I'm trying to implement and get my grasp on the Data Mapper pattern in my MVC project. I know this has been asked before, but I'm still not sure if I'm moving in the right direction. I've pasted my Controller, Datamapper and Domain Object/Entity code right below:

Controller

The user lands on mywebsite.com/dashboard/index and gets to see a list of events from the event log database table. The index() function creates an Datamapper instance and passes a the database wrapper. Then an HTML table is dynamically generated with data fetched from the Data mapper.

class DashboardController extends BaseController { 
    public function index() {
        require_once '../app/domain/mappers/EventMapper.php';
        require_once '../app/include/HTMLTableCreator.php';

        try {
            $eventMapper = new EventMapper(new Database('db'));
            $table = new HTMLTableCreator($eventMapper->findByLimit(20));
        } catch (DatabaseException $e) {

        }

        $this->view('/home/dashboard', ['table' => $table->toString()]);
    }   
}

Datamapper

This class contains the findByLimit() method for retrieving the last 20 log events from the database. The fetchCollection() method populates the Domain Entities and collects these in an array to be returned to the controller.

Should I create a generic collection function to be used by multiple Data mappers when the SQL query returns multiple rows (= multiple domain objects)? And can a Data mapper use any type of Data Source?

require_once '../app/domain/entities/Event.php';
require_once '../app/domain/interfaces/EventMapperInterface.php';

/**
 * EventMapper class
 */
class EventMapper implements EventMapperInterface {

    protected $dbh;
    protected $elements;

    public function __construct(Database $dbh) {
        $this->dbh = $dbh;
    }

    public function fetchCollection($objects) {
        foreach($objects as $object) {
            $event = new Event();
            $event->setId($object['id']);
            $event->setDateTime($object['datetime']);
            $event->setMessage($object['message']);
            $event->setHostname($object['hostname']);

            $this->elements[] = $event;
        }

        return $this->elements;
    }

    public function findByLimit($limit = 20) {
        $events = $this->dbh->sql_select('SELECT * FROM eventlog LIMIT ' . $limit, []);

        return $this->fetchCollection($events);
    }   
}

Domain Object/Entity

At last the domain object with some simple getters and setters. Would this be the place to do validation on the properties of a Domain Object?

class Event {

    protected $id;
    protected $dateTime;
    protected $message;
    protected $hostname;

    public function setId($id) {
        $this->id = $id;
    }

    public function getId() {
        return $this->id;
    }

    public function setDateTime($dateTime) {
        $this->dateTime = $dateTime;
    }

    public function getDateTime() {
        return $this->dateTime;
    }  

    // rest omitted for clarity
}

Am I missing something in my implementation?


Should I create a generic collection function to be used by multiple Data mappers when the SQL query returns multiple rows (= multiple domain objects)?

No. If your obects have properties which are 1=1 with db table columns, then use an existing approach; eg PDO-FETCH-CLASS. At any rate, it is cleaner to have one mapper per entity. If they are very generic, then use the "super" mapper.

And can a Data mapper use any type of Data Source?

Assuming that DataSource is some kind of collection-read-write interface, then surely. You have __construct(Database $dbh) , that can be replaced by __construct(DataSource $ds) .

Other notes: Try to inject the database and the mapper service into the controller.

链接地址: http://www.djcxy.com/p/56238.html

上一篇: 在Zend Framework中使用数据映射器

下一篇: PHP如何在MVC中实现Data Mapper模式