| 제목 | CI3 에서 Doctrine ORM(Object-relational mapping) 사용하기 | ||
|---|---|---|---|
| 글쓴이 | 가리비 | 작성시각 | 2019/04/01 00:45:27 | 
|  | |||
| 안녕하세요? 얼마전에 codeigniter 에서 ORM 사용하는 방법에 대해 알게됐는데 국내엔 정보도 많이 없구 개인 블로그에 올리는것 보다는 여기에 올리는게 좋을듯 해서 올려봅니다. 참고로 설치 후 사용 방법만 공유드릴거고 ORM 에 관해선 저도 지식이 없습니다.. (이제 공부하려고.. ㅎ) 
 준비물 : 컴포저 컴포저로 설치 된 코드이그나이터 (본인은 3.1.10 에서 진행했습니다.) MariaDB (추가) PHP 7.1 버전 이상 .. (본인은 7.3에서 진행했습니다.) 
 그럼 시작하도록 하겠습니다. packgist 에서 검색하면 제일 많이 사용한 ORM 이라면서 Doctrine 이 최상단에 나옵니다. 이걸 설치할 겁니다. 
 
 우선 vendor 디렉토리에서 composer.json 을 설정해줍니다. 
{
    "require": {
        "codeigniter/framework": "^3.1",
        "doctrine/orm": "*"
    },
    "autoload": {
        "psr-4": {
            "": "vendor/codeigniter/framework/application/models/Entities"
        }
    }
}
 autoload 에서 저 경로는 수정해주셔도 됩니다. 키에 해당하는 저 "" 는 네임스페이스가 되는 것 같은데, 저기에 값을 넣어주게되면 오토로딩이 제대로 안되는 것 같아요. 다른 분들은 어떠실지 모르겠네요. (컴포저 업데이트하게되면 vendor/composer/autoload_psr4.php 여기에 해당 오토로딩 위치가 나오게 되니 참고하시면 됩니다.) 
 아무튼 저렇게 수정해주고 컴포저에 composer update 혹은 심볼릭 링크 안 거신 저 같은 분들은 php composer.phar update 이런식으로 설치하면 의존성 패키지랑 같이 설치가 됩니다. 
 이후 vendor/codeigniter/framework/application/libraries 이쪽으로 가셔서 Doctrine.php 를 생성해 주고 아래와 같이 코드를 넣습니다. 
<?php
use Doctrine\Common\ClassLoader,
	Doctrine\ORM\Configuration,
	Doctrine\ORM\EntityManager,
	Doctrine\Common\Cache\ArrayCache,
	Doctrine\DBAL\Logging\EchoSQLLogger;
class Doctrine {
	public $em = null;
	public function __construct()
	{
		// load database configuration from CodeIgniter
		require_once APPPATH.'config/database.php';
		// Set up class loading. You could use different autoloaders, provided by your favorite framework,
		// if you want to.
		require_once APPPATH.'../../../doctrine/common/lib/Doctrine/Common/ClassLoader.php';
		$doctrineClassLoader = new ClassLoader('Doctrine',  APPPATH.'libraries');
		$doctrineClassLoader->register();
		$entitiesClassLoader = new ClassLoader('models', rtrim(APPPATH, "/" ));
		$entitiesClassLoader->register();
		$proxiesClassLoader = new ClassLoader('Proxies', APPPATH.'models/proxies');
		$proxiesClassLoader->register();
		// Set up caches
		$config = new Configuration;
		$cache = new ArrayCache;
		$config->setMetadataCacheImpl($cache);
		// composer 의 경로를 확인하면서 수정해주세요.
		$driverImpl = $config->newDefaultAnnotationDriver(array(APPPATH.'models/Entities'));
		$config->setMetadataDriverImpl($driverImpl);
		$config->setQueryCacheImpl($cache);
		// Proxy configuration
		$config->setProxyDir(APPPATH.'/models/proxies');
		$config->setProxyNamespace('Proxies');
		// Set up logger
		// 이 부분의 주석을 해제하면 쿼리가 나옵니다.
		//$logger = new EchoSQLLogger;
		//$config->setSQLLogger($logger);
		$config->setAutoGenerateProxyClasses( TRUE );
		// Load the database configuration from CodeIgniter
        require APPPATH . 'config/database.php';
		// Database connection information
		$connectionOptions = array(
			'driver' => 'pdo_mysql',
			'user' =>     $db['default']['username'],
			'password' => $db['default']['password'],
			'host' =>     $db['default']['hostname'],
			'dbname' =>   $db['default']['database']
		);
		// Create EntityManager
		$this->em = EntityManager::create($connectionOptions, $config);
	}
}주석 잘 유의 하시고 해당 코드를 넣어주세요. 그 다음 해당 위치에서 ../../../../bin/doctrine 를 실행 한번 해줍니다. 이건 사실 정상적으로 동작하는 건지는 잘 모르겠는데 실행했을 경우 별다른 메세지가 나오지 않는다면 정상적으로 경로가 맞다고 볼 수 있겠습니다. 
 이후에 아까 composer.json 에 설정해둔 
"autoload": {
        "psr-4": {
            "": "vendor/codeigniter/framework/application/models/Entities"
        }
    }이 위치로 가서 ORM 으로 연동할 php 파일을 만듭니다. 
 
<?php
/**
 * @Entity @Table(name="product")
 **/
class Product {
	/** @Id @Column(type="integer") @GeneratedValue **/
    protected $sn;
	/** @Column(type="string") **/
	protected $name;
	public function getName()
	{
		return $this->name;
	}
}
 사용하시는 테이블 명, 클래스 명을 유의해서 넣어주세요. 주석처럼 보이는 저 곳에 값을 넣어주지않으면 에러가 납니다. 그리고 주석에 해당하는 부분에 테이블 명을 꼭 넣어주어야되고, Id 부분에는 Primary Key를 꼭 넣어달라고 하네요. 
 마지막으로 config/autoload.php 에서 library 쪽에 Doctrine 을 추가해주거나 $this->load->library('doctrine'); 이런식으로 로드를 해주면 됩니다. 
 
public function doctrine()
    {
        //오토로딩 안되서 임시방편으로 했던 방법..
        //include_once APPPATH.'models/Entities/Product.php';
        $em = $this->doctrine->em;
        $product = $em->find('Product', 1);
        if ($product === null) {
            echo "No product found.\n";
            exit(1);
        }
        echo sprintf("%s\n", $product->getName());
    }
 컨트롤러 쪽에서 이런식으로 테스트를 진행했는데 잘 나오네요. 
 doctrine 에 대한 자세한 사용방법은 https://www.doctrine-project.org/projects/doctrine-orm/en/2.7/cookbook/integrating-with-codeigniter.html 여기서 확인해주세요. | |||
| 다음글 | XSS filtering에 대해서 (5) | ||
| 이전글 | CI3에서 CSRF 와 AJAX 사용시 팁.. (2) | ||
| 
                                한대승(불의회상)
                                /
                                2019/04/01 10:08:46 /
                                추천
                                0
                             | 
| 
                                배강민
                                /
                                2019/04/01 10:10:57 /
                                추천
                                0
                             
                                오홍 한번 해봐야겠네요
                             | 
| 
                                가리비
                                /
                                2019/04/01 11:14:03 /
                                추천
                                0
                             CI 사용자로써 예전에 들었던 씁쓸한 말로는 'CI는 ORM 도 없잖아' ... ORM 이 도대체 뭘까? 사실 최근까지도 별 생각 없다가 채용공고에 ORM 사용 경험 우대 조건이 있었습니다. 그래서 찾아본 이 방법. 오토로딩이 잘 안되서 밤을 샜지만 뭐.. 그만큼 보람은 있지않을까 싶네요. | 
| 
                                배강민
                                /
                                2019/04/01 13:02:55 /
                                추천
                                0
                             CI4는 왜 ORM이라는 표현을 사용하지 않는지 모르겠지만, 라라벨의 옐로퀀트 ORM과 같은 개념을 제공합니다. https://codeigniter4.github.io/CodeIgniter4/models/model.html#configuring-your-model | 
| 
                                가리비
                                /
                                2019/04/01 15:00:11 /
                                추천
                                0
                             
                                제목을 그냥 codeigniter 에서 CI3 으로 바꿨습니다. ㅎㅎㅎ..
                             | 
| 
                                kaido
                                /
                                2019/04/01 16:23:14 /
                                추천
                                0
                             다른말이긴 합니다만 CI 에서 ORM 없잖아? 하면 라이브러리 넣으면 되는데요? 같은 PHP 하늘 아래 다를리가 없잖아요? 라고 반박 해주었지요 ㅋㅋ | 
좋은 정보 감사합니다.