'Programming/CodeIgniter'에 해당하는 글 26건

CSRF (Cross Site Request Forgery)
CI에서는 크로스 사이트 요청 위조에 대한 보호가 가능합니다.
CSRF 보호를 활성화하려면 application/config/config.php 를 열고 다음과 같이 설정합니다.

//$config['csrf_protection'] = false;
$config['csrf_protection'] = true;

 

활성화 한 후 view 페이지에서 form_helper 의 form_open() 함수를 사용하면, 폼의 CSRF 보호를위한 hidden 필드가 자동 삽입됩니다.
<?=form_open('form/update')?>
<input type="hidden" name="csrf_token_name" value="bdd350d889c5d8cf961a412107377844" />

 

 

csrf 보호를 활성화 시킨 상태에서 csrf_token_name ($config['csrf_token_name']) 을 함께 전송하지 않으면,
submit 버튼을 클릭할 경우 http 500 error code 를 발생시킵니다.

 

An Error Was Encountered
The action you have requested is not allowed.

 

 

 

Ajax 통신 역시 마찬가지 입니다.

var csrf = $('input[name=csrf_token_name]').val();

var test = $.ajax({
    type: "post",
    url: "form/ajax_auth",
    data : {csrf_token_name:csrf, ...

 

이런 식으로 csrf_token_name 을 함께 전달해야 500 에러를 피할 수 있습니다.

 


WRITTEN BY
손가락귀신
정신 못차리면, 벌 받는다.

,

pagination 클래스를 사용하여 간단한 페이징 구현을 하였습니다.
$config['base_url']에 지정한 대로 /path/page/no 식으로 링크가 생성되었습니다.
페이징을 사용하는, 예를 들어 게시판에 대한 페이징을 구현하고자 할 때 쿼리스트링은 아래와 유사합니다.

 

list.php?page=10&sfl=name&stx=keyword&sort=code&sc=asc

 

페이지, 검색필드, 검색어, 정렬필드, 정렬방법...
이런것들이 uri 에 포함되게 되는데 세그먼트 방식으로 다시 작성해 보겠습니다.

 

list/page/10/sfl/name/stx/keyword/sort/code/sc/asc

 

기존 pagination 클래스를 그대로 사용할 경우 페이지 링크에 page/no 뒤의 모든 세그먼트(/sfl~)는 사라집니다.
이를 해결하려면 page/no 뒤의 모든 세그먼트를 저장하고 페이지 링크 뒤에 추가해 주면 되겠습니다.
그러기 위해 system/libraries/Pagination.php 클래스 파일을 약간 수정해야 합니다.

 

 

* file : system/libraries/Pagination.php

class CI_Pagination {
    // page/no 뒤의 세그먼트를 저장할 변수 선언
    var $add_segment = '';

    // href 로 검색하여 링크 마지막에 .$add_segment 추가 : 6개 정도
    $output .= $this->first_tag_open.'<a '.$this->anchor_class.'href="'
    .$this->base_url.$this->first_url.$this->add_segment.'">'.$this->first_link
    .'</a>'.$this->first_tag_close;
}

 

이렇게 pagination 을 변경했으면 컨트롤러에서 $config['add_segment'] 에 page/no 뒤의 세그먼트만 저장해 주면 완성입니다.

 

$seg_split = preg_split("/page\/[0-9]*/", $this->uri->uri_string() ); //uri에 /page/숫자 부분이 있다면 $next_seg[1]에 page/no 뒤의 세그먼트가 저장될 것입니다. if ( isset($seg_split[1]) ) { $config['add_segment'] = $seg_split[1]; }

 

이렇게 되면 list/page/10/sfl/name/stx/keyword/sort/code/sc/asc 주소에서 페이징을 클릭하면
page/숫자만 변경되는 것을 확인할 수 있습니다.
system 디렉토리의 소스들을 직접 변경하는 건 좋은 방법이 아니므로 application/libraries 에
class MY_Pagination extends CI_Pagination 식으로 확장하여 사용하는 것이 좋습니다.


WRITTEN BY
손가락귀신
정신 못차리면, 벌 받는다.

,

pagination

Programming/CodeIgniter 2013. 6. 12. 00:18

대부분의 게시판에는 < 1 2 3 4 5 6 7 8 9 > 같이 페이징 기능을 추가합니다.
CI는 페이징을 간단하게 구현할 수 있는 pagination 클래스를 제공합니다.
http://ellislab.com/codeigniter/user-guide/libraries/pagination.html
(file : system/libraries/Pagination.php)

 

Controller를 생성하여 다음의 코드를 입력하면 페이징 기능을 확인할 수 있습니다.

 

$this->load->library('pagination');

$config['base_url'] = 'http://example.com/index.php/test/page/';
$config['total_rows'] = 200;
$config['per_page'] = 20; 

$this->pagination->initialize($config); 

echo $this->pagination->create_links();

 

라고 메뉴얼에는 나와 있지만 어설프게 따라하면 정상적으로 동작하지 않습니다.
한번 따라해 보겠습니다.

 

<?php
class Test extends CI_Controller {

    function index()
    {
        $this->load->library('pagination');
        $config['base_url'] = '/test/page/';
        $config['total_rows'] = 200;
        $config['per_page'] = 20;
        $this->pagination->initialize($config);    // $config 설정대로 페이징 초기화
        echo $this->pagination->create_links();    // 페이징 생성
    }
}
?>

 

controller/test.php 파일로 저장했다면 http://domain/test 로 접속하여 페이징을 확인할 수 있습니다.
1 2 3 > last>
$config['base_url'] 는 위 링크들에 걸릴 기본 경로를 지정하는 것입니다.
/test/page/ 라고 지정했으므로 링크는 /test/page/페이지숫자 가 될 것입니다.
하지만 링크를 클릭하면 404 에러를 보게 됩니다...

 

숫자 2를 클릭하여 2번 페이지로 이동하려 한다면 URL은 http://domain/test/page/2 가 됩니다.
test는 클래스. page는 함수. 2는 파라미터입니다.
그런데 page라는 함수가 위에 없죠.. 그래서 404 에러가 나타난 것입니다.

 

다시...
http://domain/test 주소로 접속하면 http://domain/test/index 를 부르게 됩니다.
test는 클래스 index는 함수 입니다.
$config['base_url'] = '/test/index/' 로 설정한다면 페이징이 정상적으로 작동하는 것을 확인할 수 있을 것입니다.
링크 주소는 http://domain/test/index/페이지숫자 가 되겠습니다.

 

그럼 처음에 의도한대로 $config['base_url'] = '/test/page/' 로 구현할 수 없을까.
page 함수를 생성하면 됩니다.

 

function index()
{
    $this->page();
}

function page()
{
    // pagination
}

 

위와 같이 코딩하였다면 http://domain/test 로 접속하고 페이지 링크는 http://domain/test/page/페이지숫자 가 될 것입니다.
예를 보면 $config 배열을 재정의하고 있는 것을 확인할 수 있는데, 몇가지 중요한 것이 있습니다. 나머지는 style 들이구요.

 

 

  • $config['total_rows']
    총 게시물 수로 생각하면 됩니다. $config['total_rows'] / $config['per_page'] 로 연산한 만큼 페이징이 출력됩니다.

  • $config['per_page']
    한 페이지에 출력될 게시물 수.

  • $config['uri_segment'] = 3
    중요합니다. 여기에 지정되는 숫자는 페이징숫자의 segment와 자릿수가 같아야 합니다.
    /test/page/2 라면 페이징숫자는 3번째 segment.
    /board/test/page/2 라면 페이징숫자는 4번째 segment.
    이것이 올바르게 지정되지 않으면 URL의 페이징 숫자가 변경이 되어도 1 페이지만 보여지는 이상 현상을 감상하실 수 있습니다.
    기본값은 3 입니다.

  • $config['use_page_numbers'] = false
    위의 예에서 페이징 링크를 확인해보면 page/ page/20 page/40 page/60... 식으로 $config['per_page']에 지정한 만큼의 offset으로 표현됩니다.
    이 방식은 mysql 문의 limit x, y 에서 x의 시작점은 즉시 표현할 수 있어서 편리합니다.
    하지만 기존 페이징들 처럼 page/1 page/2 page/3 page4... 식으로 표현하려면 $config['use_page_numbers'] 값을 true로 지정하면 됩니다.
    숫자를 페이지 수로 사용할 것이냐, 게시물 수로 사용할 것이냐 입니다.
    기본값은 false 입니다.

  • $config['first_url'] = ''
    [처음][이전] 3 4 5 [다음][맨끝] 이라고 링크가 있을 때 [처음] 이나 1페이지를 클릭했을 때 지정될 페이징숫자를 지정합니다.
    기본값은 공백이어서 [처음] 이나 1페이지를 클릭한다면 /test/page 를 표시하게 됩니다. /test/page/0 과 같은 것입니다.
    $config['use_page_numbers'] 가 false 면 첫페이지는 /test/page/0 가 되고
    $config['use_page_numbers'] 가 true 면 첫페이지는 /test/page/1 이 됩니다.
    필요에 따라 설정할 수 있습니다.

WRITTEN BY
손가락귀신
정신 못차리면, 벌 받는다.

,

1. 지역에 맞는 텍스트(국가별 언어)

제어 구문에서의 출력되는 모든 문자는 lang 파일에서 language 변수를 사용해야 합니다.

INCORRECT:
return "Invalid Selection";

CORRECT:
return $this->lang->line('invalid_selection');


2. Private 메소드와 변수

클래스로부터 내부적으로만 접근가능한 메소드와 변수는 밑줄로 시작해야 합니다.

convert_text()  // public method
_convert_text()  // private method


3. Short Open Tags

서버에 short_open_tag 가 enable 이 아닐 수도 있으므로 항상 짧은 시작태그(<?)가 아닌 완벽한 시작태그(<?php)를 사용합니다.

INCORRECT:
<? echo $foo; ?>
<?=$foo?>

CORRECT:
<?php echo $foo; ?>


4. 한 줄당 한 구문 (One Statement Per Line)

한 줄에 여러 구문을 사용하지 않습니다.

INCORRECT:
$foo = 'this'; $bar = 'that'; $bat = str_replace($foo, $bar, $bag);

CORRECT:
$foo = 'this';
$bar = 'that';
$bat = str_replace($foo, $bar, $bag);


5. 문자열(Strings)

변수 해석이 필요하지 않는 한 항상 문자열에 작은 따옴표를 사용하고, 변수 해석이 필요한 곳에 중괄호를 사용합니다.
또한 문자열이 작은 따옴표를 포함한다면 문자열에 큰 따옴표를 사용할 것입니다.
이스케이프(\) 문자를 사용하지 않도록 합니다.

INCORRECT:
"My String"     // no variable parsing, so no use for double quotes
"My string $foo"    // needs braces
'SELECT foo FROM bar WHERE baz = \'bag\'' // ugly

CORRECT:
'My String'
"My string {$foo}"
"SELECT foo FROM bar WHERE baz = 'bag'"


6. SQL Queries

Mysql 키워드는 항상 대문자로 씁니다. SELECT, INSERT, UPDATE, WHERE, AS, JOIN, ON, IN, ...
긴 쿼리는 읽기 쉽도록 각 절마다 여러 라인으로 나눕니다.

INCORRECT:
// keywords are lowercase and query is too long for
// a single line (... indicates continuation of line)
$query = $this->db->query("select foo, bar, baz, foofoo, foobar as raboof, foobaz from exp_pre_email_addresses
...where foo != 'oof' and baz != 'zab' order by foobaz limit 5, 100");

CORRECT:
$query = $this->db->query("SELECT foo, bar, baz, foofoo, foobar AS raboof, foobaz
                                        FROM exp_pre_email_addresses
                                        WHERE foo != 'oof'
                                        AND baz != 'zab'
                                        ORDER BY foobaz
                                        LIMIT 5, 100");


7. 기본 함수 인자 (Default Function Arguments)

잘못된 호출시 PHP 오류를 방지하기 위해 기본적인 인수를 사용합니다.

function foo($bar = '', $baz = FALSE)

WRITTEN BY
손가락귀신
정신 못차리면, 벌 받는다.

,


1. 클래스나 파일 이름

클래스나 파일명이 너무 단순하다면 다른 PHP 스크립트와 충돌할 수 있으므로, 고유한 접두어를 붙이는 것이 좋습니다.
개발자의 이름이나 회사의 이름을 접두어로 쓰면 좋습니다.

INCORRECT:
class Email  pi.email.php
class Xml  ext.xml.php
class Import  mod.import.php

CORRECT:
class Pre_email  pi.pre_email.php
class Pre_xml  ext.pre_xml.php
class Pre_import mod.pre_import.php



2. 데이터베이스 테이블 이름

추가적으로 작성하는 모든 테이블은 'exp_' 접두어를 사용하고, 그 뒤에 개발자나 회사 이름으로 식별 가능한 접두어를 넣고, 그 다음 테이블 이름을 간략하게 기술합니다.

INCORRECT:
email_addresses  // missing both prefixes
pre_email_addresses // missing exp_ prefix
exp_email_addresses // missing unique prefix

CORRECT:
exp_pre_email_addresses



3. 공백 (Whitespace)

코드에 공백을 넣고 싶을 때 스페이스가 아닌 을 사용하는 것이 단계별 들여쓰기에도 좋고, 아주 미세하지만 소스코드의 크기도 줄여줍니다.


4. 코드 들여쓰기

Allman 스타일의 들여쓰기를 사용하세요.
클래스 선언만 제외하고, 중괄호는 항상 한라인을 차지하도록 하며, 자기가 속한 조건문과 같은 레벨의 들여쓰기를 합니다.

INCORRECT:
function foo($bar) {
    // ...
}

foreach ($arr as $key => $val) {
    // ...
}

if ($foo == $bar) {
    // ...
} else {
    // ...
}

for ($i = 0; $i < 10; $i++)
    {
    for ($j = 0; $j < 10; $j++)
       {
       // ...
       }
    }

CORRECT:
function foo($bar)
{
    // ...
}

foreach ($arr as $key => $val)
{
    // ...
}

if ($foo == $bar)
{
    // ...
}
else
{
    // ...
}

for ($i = 0; $i < 10; $i++)
{
    for ($j = 0; $j < 10; $j++)
    {
       // ...
    }
}



5. 괄호의 여백

일반적으로 괄호에는 공백을 사용하지 말아야 합니다.
가독성을 높이고 함수와 구별하기 위해, PHP 조건문에 매개변수를 사용할때는 예외입니다.

INCORRECT:
$arr[ $foo ] = 'foo';

CORRECT:
$arr[$foo] = 'foo'; // no spaces around array keys

 

INCORRECT:
function foo ( $bar )
{
}

CORRECT:
function foo($bar) // no spaces around parenthesis in function declarations
{
}

 

INCORRECT:
foreach( $query->result() as $row )

CORRECT:
foreach ($query->result() as $row) // single space following PHP control structures, but not in interior parenthesis

WRITTEN BY
손가락귀신
정신 못차리면, 벌 받는다.

,