Integrasi Doctrine ORM pada Zend Framework 3


22/09/2017 08:19:03 326 Web

$ composer require doctrine/doctrine-orm-module
Using version ^1.1 for doctrine/doctrine-orm-module
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 22 installs, 0 updates, 0 removals
  - Installing zendframework/zend-hydrator (2.3.0): Downloading (100%)         

  Please select which config file you wish to inject 'Zend\Hydrator' into:
  [0] Do not inject
  [1] config/modules.config.php
  [2] config/development.config.php.dist
  Make your selection (default is 0):1

  Remember this option for other packages of the same type? (y/N)
Installing Zend\Hydrator from package zendframework/zend-hydrator
  - Installing psr/log (1.0.2): Loading from cache
  - Installing symfony/debug (v3.3.9): Loading from cache
  - Installing symfony/polyfill-mbstring (v1.5.0): Loading from cache
  - Installing symfony/console (v3.3.9): Loading from cache
  - Installing doctrine/cache (v1.6.2): Downloading (100%)         
  - Installing doctrine/lexer (v1.0.1): Downloading (100%)         
  - Installing doctrine/inflector (v1.2.0): Downloading (100%)         
  - Installing doctrine/collections (v1.4.0): Downloading (100%)         
  - Installing doctrine/annotations (v1.4.0): Downloading (100%)         
  - Installing doctrine/common (v2.7.3): Downloading (100%)         
  - Installing doctrine/instantiator (1.0.5): Loading from cache
  - Installing doctrine/dbal (v2.5.13): Downloading (100%)         
  - Installing doctrine/orm (v2.5.11): Downloading (100%)         
  - Installing zendframework/zend-paginator (2.7.0): Downloading (100%)         

  Please select which config file you wish to inject 'Zend\Paginator' into:
  [0] Do not inject
  [1] config/modules.config.php
  [2] config/development.config.php.dist
  Make your selection (default is 0):1

  Remember this option for other packages of the same type? (y/N)
Installing Zend\Paginator from package zendframework/zend-paginator
  - Installing zendframework/zend-filter (2.7.2): Downloading (100%)         

  Please select which config file you wish to inject 'Zend\Filter' into:
  [0] Do not inject
  [1] config/modules.config.php
  [2] config/development.config.php.dist
  Make your selection (default is 0):1

  Remember this option for other packages of the same type? (y/N)
Installing Zend\Filter from package zendframework/zend-filter
  - Installing zendframework/zend-inputfilter (2.7.4): Downloading (100%)         

  Please select which config file you wish to inject 'Zend\InputFilter' into:
  [0] Do not inject
  [1] config/modules.config.php
  [2] config/development.config.php.dist
  Make your selection (default is 0):1

  Remember this option for other packages of the same type? (y/N)
Installing Zend\InputFilter from package zendframework/zend-inputfilter
  - Installing zendframework/zend-form (2.10.2): Downloading (100%)         

  Please select which config file you wish to inject 'Zend\Form' into:
  [0] Do not inject
  [1] config/modules.config.php
  [2] config/development.config.php.dist
  Make your selection (default is 0):1

  Remember this option for other packages of the same type? (y/N)
Installing Zend\Form from package zendframework/zend-form
  - Installing zendframework/zend-cache (2.7.2): Downloading (100%)         

  Please select which config file you wish to inject 'Zend\Cache' into:
  [0] Do not inject
  [1] config/modules.config.php
  [2] config/development.config.php.dist
  Make your selection (default is 0):1

  Remember this option for other packages of the same type? (y/N)
Installing Zend\Cache from package zendframework/zend-cache
  - Installing zendframework/zend-authentication (2.5.3): Downloading (100%)         
  - Installing doctrine/doctrine-module (1.2.0): Downloading (100%)         

  Please select which config file you wish to inject 'DoctrineModule' into:
  [0] Do not inject
  [1] config/modules.config.php
  [2] config/development.config.php.dist
  Make your selection (default is 0):1

  Remember this option for other packages of the same type? (y/N)
Installing DoctrineModule from package doctrine/doctrine-module
  - Installing doctrine/doctrine-orm-module (1.1.5): Downloading (100%)         

  Please select which config file you wish to inject 'DoctrineORMModule' into:
  [0] Do not inject
  [1] config/modules.config.php
  [2] config/development.config.php.dist
  Make your selection (default is 0):1

  Remember this option for other packages of the same type? (y/N)
Installing DoctrineORMModule from package doctrine/doctrine-orm-module
zendframework/zend-hydrator suggests installing zendframework/zend-serializer (^2.6.1, to use the SerializableStrategy)
symfony/console suggests installing symfony/event-dispatcher ()
symfony/console suggests installing symfony/filesystem ()
symfony/console suggests installing symfony/process ()
doctrine/orm suggests installing symfony/yaml (If you want to use YAML Metadata Mapping Driver)
zendframework/zend-paginator suggests installing zendframework/zend-db (Zend\Db component)
zendframework/zend-paginator suggests installing zendframework/zend-json (Zend\Json component)
zendframework/zend-filter suggests installing zendframework/zend-crypt (Zend\Crypt component, for encryption filters)
zendframework/zend-filter suggests installing zendframework/zend-i18n (Zend\I18n component for filters depending on i18n functionality)
zendframework/zend-form suggests installing zendframework/zend-captcha (^2.7.1, required for using CAPTCHA form elements)
zendframework/zend-form suggests installing zendframework/zend-code (^2.6 || ^3.0, required to use zend-form annotations support)
zendframework/zend-form suggests installing zendframework/zend-i18n (^2.6, required when using zend-form view helpers)
zendframework/zend-form suggests installing zendframework/zendservice-recaptcha (in order to use the ReCaptcha form element)
zendframework/zend-cache suggests installing zendframework/zend-serializer (Zend\Serializer component)
zendframework/zend-cache suggests installing zendframework/zend-session (Zend\Session component)
zendframework/zend-cache suggests installing ext-apc (APC or compatible extension, to use the APC storage adapter)
zendframework/zend-cache suggests installing ext-apcu (APCU >= 5.1.0, to use the APCu storage adapter)
zendframework/zend-cache suggests installing ext-dba (DBA, to use the DBA storage adapter)
zendframework/zend-cache suggests installing ext-memcache (Memcache >= 2.0.0 to use the Memcache storage adapter)
zendframework/zend-cache suggests installing ext-memcached (Memcached >= 1.0.0 to use the Memcached storage adapter)
zendframework/zend-cache suggests installing ext-mongo (Mongo, to use MongoDb storage adapter)
zendframework/zend-cache suggests installing ext-redis (Redis, to use Redis storage adapter)
zendframework/zend-cache suggests installing ext-wincache (WinCache, to use the WinCache storage adapter)
zendframework/zend-cache suggests installing ext-xcache (XCache, to use the XCache storage adapter)
zendframework/zend-cache suggests installing mongofill/mongofill (Alternative to ext-mongo - a pure PHP implementation designed as a drop in replacement)
zendframework/zend-authentication suggests installing zendframework/zend-db (Zend\Db component)
zendframework/zend-authentication suggests installing zendframework/zend-crypt (Zend\Crypt component)
zendframework/zend-authentication suggests installing zendframework/zend-ldap (Zend\Ldap component)
zendframework/zend-authentication suggests installing zendframework/zend-session (Zend\Session component)
doctrine/doctrine-module suggests installing doctrine/data-fixtures (Data Fixtures if you want to generate test data or bootstrap data for your deployments)
doctrine/doctrine-module suggests installing zendframework/zend-mvc-console (^1.1.10 if you are using ZF3)
doctrine/doctrine-orm-module suggests installing zendframework/zend-developer-tools (zend-developer-tools if you want to profile operations executed by the ORM during development)
doctrine/doctrine-orm-module suggests installing doctrine/migrations (doctrine migrations if you want to keep your schema definitions versioned)
Writing lock file
Generating autoload files

config\autoload\local.php

<?php
use Doctrine\DBAL\Driver\PDOMySql\Driver as PDOMySqlDriver;

return [
    'doctrine' => [
        'connection' => [
            'orm_default' => [
                'driverClass' => PDOMySqlDriver::class,
                'params' => [
                    'host'     => '127.0.0.1',                    
                    'user'     => 'root',
                    'password' => 'r4h4s14',
                    'dbname'   => 'zend_blog',
                ]
            ],            
        ],        
    ],
];

module\Application\config\module.config.php

    ...
    'doctrine' => [
        'driver' => [
            __NAMESPACE__ . '_driver' => [
                'class' =>  \Doctrine\ORM\Mapping\Driver\AnnotationDriver::class,
                'cache' => 'array',
                'paths' => [__DIR__ . '/../src/Entity']
            ],
            'orm_default' => [
                'drivers' => [
                    __NAMESPACE__ . '\Entity' => __NAMESPACE__ . '_driver'
                ]
            ]
        ]
    ] 
        ...

Entity Post

Application\Entity\Post.php pada module/Application/src/Entity/Post.php dengan code:

<?php

namespace Application\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * This class represent a single post in a blog
 * @ORM\Entity
 * @ORM\Table(name="rofil_blog_posts")
 */
class Post 
{
    const STATUS_DRAFT = 1;
    const STATUS_PUBLISHED = 2;

    /**
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     * @ORM\Column(name="id", type="integer")
     */
    protected $id;

    /**
     * @ORM\Column(name="title", type="string", length=255)
     */
    protected $title;

    /**
     * @ORM\Column(name="body", type="text")
     */
    protected $body;

    /**
     * @ORM\Column(name="published", type="boolean")
     */
    protected $published;

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

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

        return $this;
    }

    public function getTitle()
    {
        return $this->title;
    }

    public function setTitle($title)
    {
        $this->title = $title;

        return $this;
    }

    public function getBody()
    {
        return $this->body;
    }

    public function setBody($body)
    {
        $this->body = $body;

        return $this;
    }

    public function getPublished()
    {
        return $this->published;
    }

    public function setPublished($published)
    {
        $this->published = $published;

        return $this;
    }
}

kemudian jalankan

./vendor/bin/doctrine-module orm:schema-tool:update --dump-sql --force

Kemudian untuk menampilkan pada Controller misalkan IndexController.php maka perlu melakukan injection EntityManager pada constructor. Pada IndexController tambahkan constructor sebagai berikut:

    ...
    use Application\Entity\Post;
    ...
    private $entityManager;

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

sedangkan pada method indexAction() tambahkan kode untuk mengambil data sebagai berikut:

    ...
    public function indexAction()
    {
        $posts = $this->entityManager->getRepository(Post::class)->findAll();
        return new ViewModel(["posts" => $posts]);
    }
    ...

Kita akan membuat IndexControllerFactory yang digunakan untuk meng-instantiate IndexController sekaligus melakukan inject terhadap dependency yang diperlukan pada constructor. IndexControllerFactory terdapat pada directory Controller/Factory/IndexControllerFactory.php dengan code sebagai berikut:

<?php

namespace Application\Controller\Factory;

use Interop\Container\ContainerInterface;
use Zend\ServiceManager\Factory\FactoryInterface;
use Application\Controller\IndexController;

/**
 * This is the factory for IndexController. Its purposes is to instantiate the controller
 */
class IndexControllerFactory implements FactoryInterface
{
    public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
    {

        $entityManager = $container->get('doctrine.entitymanager.orm_default');
        // $entityManager = $this->getServiceLocator()->get(\Doctrine\ORM\EntityManager::class);;
        // Instantiate the controller and inject dependencies
        return new IndexController($entityManager);
    }
}

Adapun module.config.php pada bagian controller perlu dirubah dengan mendelegasikan IndexControllerFactory sebagai class yang digunakan untuk melakukan instantiate terhadap controller IndexController sebagai berikut:

    ...
    'controllers' => [
        'factories' => [
            // Controller\IndexController::class => InvokableFactory::class,
            Controller\IndexController::class => Controller\Factory\IndexControllerFactory::class,
        ],
    ],
    ...