CodeIgniter 에는 기본으로 레이아웃을 사용할 수 있지가 않다. 여러개의 뷰로드하기 를 통해서 같단히 레이아웃 효과를 낼 수 있지만, 부족한 부분이 있다.

CodeIgniter 에서 Layout 을 위한 방법이 여러가지 존재한다. 다음을 참고하자.

Layout Library 를 이용한 방법
  • http://codeigniter.com/wiki/layout_library/ 에서 Layout Library를 구하고, 사용법을 확인할 수 있다.
  • 이 라이브러리는 CakePHP 스타일의 레이아웃을 사용할 수 있도록 해준다.
  1. /application/libraries/Layout.php 에 다음 소스를 저장한다.
    <?php  
    if (!defined('BASEPATH')) exit('No direct script access allowed');
     
    class Layout
    {
        var $obj;
        var $layout;
     
        function Layout($layout = "layout_main")
        {
            $this->obj =& get_instance();
            $this->layout = $layout;
        }
     
        function setLayout($layout)
        {
            $this->layout = $layout;
        }
     
        function view($view, $data=null, $return=false)
        {
            $loadedData = array();
            $loadedData['content_for_layout'] = $this->obj->load->view($view,$data,true);
     
            if($return) {
                $output = $this->obj->load->view($this->layout, $loadedData, true);
                return $output;
            } else {
                $this->obj->load->view($this->layout, $loadedData, false);
            }
        }
    }
    ?>
    
  2. 라이브러리 로딩은 2가지 방법이 있는데, 첫번째는 컨트롤러의 생성자에서
    $this->load->library('layout', 'layouts/default');
    // 위에서 layout 라이브러리를 로딩할 때, 두번째 인자가 적용되지 않으므로,
    // 아래와 같이 별도로 default layout 을 설정해주어야 한다.
    $this->layout->setLayout("layouts/default");
    
    와 같이 적어주는 방법과 두번째는 /application/config/autoload.php 에
    $autoload['libraries'] = array('layout');
    
    를 적어주어서, 매번 컨트롤러 생성자에 적어주지 않게 하는 방법이 있다. 그리고 나서, 컨트롤러에서 아래와 같이 해주면, 레이아웃과 내용이 로딩 될 것이다.
    // layout 을 적용하지 않고 출력하고자 할 때
    // $this->load->view('admin/list');
     
    // 다른 layout 을 적용하고자 할 때
    // $this->layout->setLayout("layouts/default");
     
    $this->layout->view('admin/list');
    
  3. /application/views/layouts/default.php
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ko" lang="ko" dir="ltr">
    <head>
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
      <title>CI 레이아웃</title>
    </head>
    <body>
    <?= $content_for_layout ?>
    </body>
    </html>
    
Hook을 이용한 Layout 처리

Hook을 이용한 Layout 정리, http://codeigniter.com/forums/viewthread/57902/ 를 참고하였습니다.

  1. HOOK 사용 설정
    • config/config.php
      $config['enable_hooks'] = TRUE;
      
    • config/hooks.php
      $hook['display_override'][] = array(
          'class'    => 'Yield',
          'function' => 'doYield',
          'filename' => 'Yield.php',
          'filepath' => 'hooks'
      );
      
  2. HOOK 파일 추가
    • hooks/Yield.php
      <?php  if (!defined('BASEPATH')) exit('No direct script access allowed');
       
      class Yield
      {
          function doYield()
          {
              global $OUT;
              $CI =& get_instance();
              $output = $CI->output->get_output();
              $CI->yield = isset($CI->yield) ? $CI->yield : TRUE;
              $CI->layout = isset($CI->layout) ? $CI->layout : 'default';
              if ($CI->yield === TRUE) {
                  if (!preg_match('/(.+).php$/', $CI->layout)) {
                      $CI->layout .= '.php';
                  }
                  $requested = APPPATH . 'views/layouts/' . $CI->layout;
                  $layout = $CI->load->file($requested, true);
                  $view = str_replace("{yield}", $output, $layout);
              } else {
                  $view = $output;
              }
              $OUT->_display($view);
          }
      }
      ?>
      
    • 디폴트 레아이웃 파일은 default.php, 레이아웃 폴더위치는 view/layouts 또는 입맛대로 변경
  3. default.php 레이아웃 파일 추가
    • views/layouts/default.php
      <html>
      <header>
      </header>
      <body>
        <div>
        </div>
        {yield}
        <div>
        </div>
      </body>
      <html>
      
  4. 컨트롤러에서 레이아웃 사용법
    class Test extends Controller {
     
        //레이아웃 파일 설정
        var $layout = 'my_layout_file';
     
        function Test()
        {
            parent::Controller();
        }
     
        function index()
        {
            // 로드되는 view 파일들은 레이아웃 파일안에 {yield} 와 항상 replace  됨.
            $this->load->view('main');
            $this->load->view('sidebar');
        }
     
        function ajax_call()
        {
            // 레이아웃 파일을 사용하지 않을시
            $this->yield = FALSE;
     
            echo json_encode($array);
        }
     
        function need_another_layout()
        {
            $this->layout = 'another_layout';
        }
    }
    
  5. 참고
    layout 파일안에 데이타를 넘겨줘야 할 경우, 다른 view파일을 로드할때 데이타를 같이 넘겨주거나,
    $this->load->vars($data);
    
    위처럼 글로벌로 넘겨주면 됩니다.

PHP 에도 다양한 프레임워크가 존재한다. 그중 유명한 것이 Zend Framework, CakePHP, CodeIgniter 등이다. 이 중에서도 성능이 가장 괜찮고 점점 인기를 더해가고 있는 CodeIgniter 설치방법을 정리해보았다.

아래의 설치방법은 Debian 5.0, 6.0 에서 모두 적용 가능하다.

기본 프로그램 설치
# apt-get install build-essential ssh vim htop ntp
Apache + mod_php 설치
# apt-get install libapache2-mod-php5 php5-mysql

함께 설치되는 패키지들 :
apache2-mpm-prefork php5-common php5-suhosin
→ Apache 가 함께 설치됨

MySQL 5.1 설치
# apt-get install mysql-client-5.1 mysql-server-5.1 libmysqlclient-dev
설치시 root 의 비밀번호를 물어보는데 자신이 원하는 적당한 것으로 지정한다.
사용자, DB 생성
# mysql -u root -p
mysql> CREATE DATABASE 디비이름 DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
mysql> GRANT ALL PRIVILEGES ON 디비이름.* TO '아이디'@'localhost' IDENTIFIED BY '비밀번호' WITH GRANT OPTION;
mysql> FLUSH privileges;
프로젝트 생성
$ mkdir -p /opt/project/프로젝트명/web
$ cd /opt/project/프로젝트명/web
Apache 설정
# cd /etc/apache2/sites-available
# vi 프로젝트명
NameVirtualHost *:80

<VirtualHost *:80>
    ServerName 자신의도메인URL
    DocumentRoot /opt/project/프로젝트명/web
</VirtualHost>

# a2enmod rewrite
# a2ensite 프로젝트명
# /etc/init.d/apache restart
CodeIgniter 설치
  1. http://codeigniter.com/download.php 에서 CodeIgniter_1.7.2.zip 다운로드한다.
  2. 압축을 풀고 /opt/project/프로젝트명/web 에 업로드 한다.
  3. /opt/project/프로젝트명/web 에.htaccess를 작성한다.
    RewriteEngine on
    RewriteCond $1 !^(index\.php|images|robots\.txt)
    RewriteRule ^(.*)$ /index.php/$1 [L]
    
  4. system/application/config/config.php 파일을 열어 기반url(base URL)을 세팅한다.
    $config['base_url'] = "자신의도메인URL";
    
  5. 데이터베이스를 사용한다면 application/config/database.php 파일을 열어서 데이터베이스 정보를 세팅한다.
    $db['default']['hostname'] = "localhost";
    $db['default']['username'] = "아이디";
    $db['default']['password'] = "비밀번호";
    $db['default']['database'] = "디비이름";
    $db['default']['dbdriver'] = "mysql";
    
  6. 마지막으로 보안을 위해서 system 디렉토리를 sys로 변경하고, index.php 의 $system_folder 변수를 변경해준다.
    $system_folder = "sys";
    
    sys 대신 자신이 원하는 다른 것으로 변경하길 바란다.
  7. 웹브라우저에서 자신의도메인URL 로 접속해본다.

PHP에서 메일을 IMAP의 다른 메일박스로 이동을 위해서 imap_mail_move() 함수를 이용합니다. 그리 어려워 보이지 않습니다. 그러나, 실제 이 함수를 사용해보면 메일이 다른 메일박스에 옮겨진 것을 확인할 수 있으나, 원래 메일박스에도 그대로 남아있는것을 보게 됩니다.

어찌된 영문인지 연구를 해보니 원래 메일박스에 그대로 남겨진 메일은 Delete 플래그가 설정이 된 채로 남겨진 것입니다. 이를 알아내기 위해서 이틀이나 소요했습니다. 이것을 확실하게 없애기 위해서는 imap_expunge() 함수를 호출하여 Delete 플래그가 설정된 메일을 삭제해주어야만 합니다.

다른 내용이긴 하지만, IMAP을 다룰때 또 한가지 주의할 점은 메일박스이름은 반드시 UTF-7 로 변환하고서 이용해야 합니다.

대부분의 데몬에 원격에서 연결하는 것은 상당한 부하와 시간을 소비하게 됩니다. DB 의 경우에도 보통 Connection Pool 을 만들어서 커넥션 시간을 줄이고 있습니다.

지금 만들고 있는 웹메일에서 IMAP 서버에 접근할때에도 같은 문제가 발생하고 있습니다. 한번 연결할때마다 약 2초의 시간이 걸립니다. 그래서 페이지를 이동하거나, 메일 내용을 보려고 할때마다 2초 이상의 시간을 기다려야만 했습니다. PHP에서 개발하고 있어서 다른 페이지에서 IMAP 의 연결을 유지할 수 있는 방법이 없었습니다. SESSION 변수를 이용하면 될 듯 하였으나, 테스트 실패했습니다.혹시나 하고 계속 찾아보았지만 PHP에서 해결할 수 있는 방법은 없었습니다.

그렇지만, 방법이 아주 없으면 글을 적지도 않았겠지요. IMAP 연결을 유지하려면 IMAP Proxy 를 사용하면 됩니다. 데비안 리눅스의 경우, apt-get install imapproxy 라고 입력하면 바로 설치되어 실행까지 됩니다. 기본적으로 로컬에 IMAP 이 있다고 가정하고 있으며, 1143 포트를 열고 있습니다. 개발자는 imap_open 함수를 사용할때 localhost:1143 으로 접근하면 됩니다. PHP 뿐만 아니라 다른 환경에서도 적용할 수 있어서 괜찮은 방법인 것 같습니다.

이렇게 구현을 하고 보니, 페이지 이동시 2~3 초 걸리던 것이, 거의 즉시 화면이 전환되었습니다.
상용 웹메일에서는 이것을 어떻게 해결하고 있는지 궁금하군요.

+ Recent posts