Mezzio 프레임워크에서 DB 사용법

 

Laminas 프로젝트Mezzio 프레임워크는 정말 문서가 부실합니다. 예전 Zend Framework(ZF)도 문서가 잘되어 있지는 않았지만 Mezzio는 좀 심한 편인데 웹 프레임워크임에도 문서에 DB 연결에 대한 부분이 없습니다. 제아무리 미니멀한 프레임워크이고 Laminas MVC에 있는 것을 참고하면 된다고 해도 최소한의 설명은 있어야 하는데 그것조차 없습니다. 이때문에 Mezzio 문서에서 안내하는 github의 소스들이나 검색을 통해 찾을 수 있는 소스들에서의 DB 구성 방식이 모두 다릅니다. 프레임워크를 사용하는 중요한 이유 중 하나가 통일성인데 그것을 스스로 무너지게 하고 있는 것입니다. 너무 한심해서 그냥 라라벨로 갈아탈까 생각중이지만 어쨌든 Mezzio에서의 기본적인 DB 연결과 사용법을 알아보겠습니다.

1. DB 연결 구성

DB 작업에 필요한 laminas-db를 설치해 줍니다.

composer require laminas/laminas-db

설치시 나오는 질문에는 config/config.php를 선택합니다. 패키지가 설치되었다면 DB 연결 설정을 해줍니다. 설정은 config/autoload/global.php에 해도 되고 config/autoload 디렉토리에 별도 파일을 만들어도 됩니다. 여기서는 database.global.php라는 파일을 만들어 설정하겠습니다. 설정 방법은 예전 ZF와 같은 형식입니다.

<?php
declare(strict_types=1);

return [
    'db' => [
        'driver' => 'Pdo',
        'dsn' => 'mysql:dbname=laminastutorial;host=localhost;charset=utf8',
    ],
];

2. 요청 핸들러 생성

DB 쿼리를 테스트할 요청 핸들러를 만듭니다.

composer mezzio handler:create "App\Handler\CountHandler"

만들어진 CountHandlerFactory.php 파일을 아래와 같이 수정합니다. 팩토리 클래스에서 DB 어댑터를 만든 후 핸들러에 넘겨주고 그 핸들러 객체를 리턴하는 것입니다.

<?php
...
use Laminas\Db\Adapter\AdapterInterface;
...
    public function __invoke(ContainerInterface $container) : CountHandler
    {
        $dbAdapter = $container->get(AdapterInterface::class);
        return new CountHandler($container->get(TemplateRendererInterface::class), $dbAdapter);
    }
...

CountHandler.php 파일을 아래와 같이 수정합니다. 팩토리 클래스에서 넘겨준 DB 어댑터를 사용해 test 테이블의 전체 개수를 표시하는 것입니다. 자세한 DB 사용법은 laminas-db 문서를 참고하시면 됩니다.

<?php
...
use Laminas\Db\Adapter\AdapterInterface;
use Laminas\Db\TableGateway\TableGateway;
use Laminas\Db\Sql\Select;
use Laminas\Db\Sql\Expression;

class CountHandler implements RequestHandlerInterface
{
    ...
    private $dbAdapter;

    public function __construct(TemplateRendererInterface $renderer, AdapterInterface $dbAdapter)
    {
        $this->renderer = $renderer;
        $this->dbAdapter = $dbAdapter;
    }

    public function handle(ServerRequestInterface $request) : ResponseInterface
    {
        $testTable = new TableGateway('test', $this->dbAdapter);
        $resultSet = $testTable->select(function (Select $select) {
            $select->columns(array('cnt' => new Expression('COUNT(*)')));
        });
        $count = $resultSet->current()->cnt;

        return new HtmlResponse($this->renderer->render(
            'app::count',
            ['count' => $count]
        ));
    }

핸들러 생성시 같이 만들어진 템플릿 파일도 아래 같이 수정합니다. 제가 사용하는 템플릿 엔진은 Plates입니다.

<h1>Total Count : <?= $this->e($count) ?></h1>