CodeIgniter

Library & form validation

수업소개

Library는 라이브러리의 목적에 따라서 사용법이 천차만별이기 때문에 한가지 방식으로 설명하는 것은 어렵다. 이번 수업에서는 CI에서 제공하는 Library 중에서 사용자의 입력 데이터를 검증하는 Form Validation의 사용법을 알아본다. 부가적으로 Twitter Bootstrap의 form 관련 기능도 함께 살펴보면서 웹 에플리케이션에서 데이터를 쓰는 방법에 대해서 알아본다. 앞선 Model 수업의 보충수업적 성격도 가지고 있다. 

선수지식

Library

이미 Helper에서 살펴봤듯이 라이브러리는 재활용 가능성이 있는 로직을 재활용 하기 좋은 형태로 만들어둔 것이다. CI는 자주 웹개발에서 자주 사용되는 로직들을 내장(Core) 라이브러리로 제공하고 있다. 내장 라이브러리를 확장(extend)해서 필요에 따라 수정해 사용할 수 있고, 직접 라이브러리를 만들수도 있다. 

라이브러리의 사용

아래와 같은 방법으로 someclass 라이브러리를 로드 할 수 있다. 

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

그 다음부터는 아래와 같은 방식으로 some_method를 호출해서 사용할 수 있다. 

$this->some_class->some_method

Form Validation

폼은 사용자가 입력한 정보를 받는 UI이다. 사용자는 시스템의 목적이면서 취약점이다. 사용자는 실수하기 쉽고, 공격자일 가능성이 있다. 따라서 사용자가 입력한 모든 정보는 검증되어야 하고, 이 작업을 Form Validation이라고 한다. 

CI에서는 Form Validation 라이브러리를 기본적으로 제공하는데, 지금부터 예제를 통해서 CI의 form validation에 대해서 알아본다. 

예제

application/controllers/topic.php

차이점

코드

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Topic extends CI_Controller {
    function __construct()
    {       
        parent::__construct();
        $this->load->database();
        $this->load->model('topic_model');
    }
    function index(){        
        $this->_head();

        $this->load->view('main');

        $this->load->view('footer');
    }
    function get($id){        
        $this->_head();

        $topic = $this->topic_model->get($id);
        $this->load->helper(array('url', 'HTML', 'korean'));
        $this->load->view('get', array('topic'=>$topic));

        $this->load->view('footer');
    }
    function add(){
        $this->_head();
        
        $this->load->library('form_validation');

        $this->form_validation->set_rules('title', '제목', 'required');
        $this->form_validation->set_rules('description', '본문', 'required');
        
        if ($this->form_validation->run() == FALSE)
        {
             $this->load->view('add');
        }
        else
        {
            $topic_id = $this->topic_model->add($this->input->post('title'), $this->input->post('description'));
            $this->load->helper('url');
            redirect('/topic/get/'.$topic_id);
        }
        
        $this->load->view('footer');
    }
    function _head(){
        $this->load->view('head');
        $topics = $this->topic_model->gets();
        $this->load->view('topic_list', array('topics'=>$topics));
    }
}
?>

application/models/topic_model.php

차이점

코드

<?php
class Topic_model extends CI_Model {

    function __construct()
    {    	
        parent::__construct();
    }

    function gets(){
    	return $this->db->query("SELECT * FROM topic")->result();
    }

    function get($topic_id){
        $this->db->select('id');
        $this->db->select('title');
        $this->db->select('description');
        $this->db->select('UNIX_TIMESTAMP(created) AS created');
    	return $this->db->get_where('topic', array('id'=>$topic_id))->row();
    }

    function add($title, $description){
        $this->db->set('created', 'NOW()', false);
        $this->db->insert('topic',array(
            'title'=>$title,
            'description'=>$description
        ));        
        return $this->db->insert_id();
    }
}

application/views/add.php

<form action="/index.php/topic/add" method="post" class="span10">
	<?php echo validation_errors(); ?>
	<input type="text" name="title" placeholder="제목" class="span12" />
	<textarea name="description" placeholder="본문" class="span12" rows="15" ></textarea>
	<input class="btn" type="submit" />
</form>

application/views/get.php

차이점

코드

<div class="span10">
    <article>
        <h1><?=$topic->title?></h1>
        <div>
            <div><?=kdate($topic->created)?></div>
            <?=auto_link($topic->description)?>
        </div>
    </article>
    <div>
        <a href="/index.php/topic/add" class="btn">추가</a>
    </div>
</div>

application/views/head.php

차이점

코드

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8"/>
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
	    <!-- Bootstrap -->
	    <link href="/static/lib/bootstrap/css/bootstrap.min.css" rel="stylesheet" media="screen">
	    <style>
	    	body{
	    		padding-top:60px;
	    	}
	    </style>
	    <link href="/static/lib/bootstrap/css/bootstrap-responsive.css" rel="stylesheet">			    
    </head>
    <body>
    	<div class="navbar navbar-fixed-top">
		  <div class="navbar-inner">
		    <div class="container">
		 
		      <!-- .btn-navbar is used as the toggle for collapsed navbar content -->
		      <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
		        <span class="icon-bar"></span>
		        <span class="icon-bar"></span>
		        <span class="icon-bar"></span>
		      </a>
		 
		      <!-- Be sure to leave the brand out there if you want it shown -->
		      <a class="brand" href="#">JavaScript</a>
		 
		      <!-- Everything you want hidden at 940px or less, place within here -->
		      <div class="nav-collapse collapse">
		        <!-- .nav, .navbar-search, .navbar-form, etc -->
		      </div>
		 
		    </div>
		  </div>
		</div>
    	<div class="container">
				<div class="row-fluid">

태그

태그명 : Library

태그주소 : https://github.com/egoing/codeigniter_codeingeverbody/tree/Library

댓글

댓글 본문
  1. Sansol Park
    CodeIgniter 4에서의 `redirect` 문제와 관련하여, 버전의 차이와 CodeIgniter 4의 새로운 방식 때문에 발생하는 문제가 있을 수 있습니다. CodeIgniter 4는 CodeIgniter 3와 다르게 `redirect` 메서드의 동작 방식이나 URL 구조가 약간 달라졌기 때문에, 이에 맞춰 변경해줄 필요가 있습니다.

    ### CodeIgniter 4에서의 Redirect 처리 방법

    #### 1. **`base_url()` 설정 확인**
    - 먼저, `config.php` 파일의 `$config['base_url']`을 올바르게 설정했는지 확인해야 합니다. CodeIgniter 4에서는 설정 파일의 경로가 변경되었으며, 환경 변수 `.env`를 통해 `base_url`을 설정할 수 있습니다.
    - 예를 들어, `.env` 파일에 다음과 같이 `app.baseURL`을 설정합니다:

    ```
    app.baseURL = 'http://localhost/폴더명/public/'
    ```

    #### 2. **CodeIgniter 4에서 `redirect()` 함수 사용하기**
    - CodeIgniter 4에서는 `redirect()` 메서드가 `response` 객체의 메서드로 제공됩니다. 이를 사용해 리디렉션을 수행할 수 있습니다.

    예를 들어, 컨트롤러에서 다음과 같이 사용할 수 있습니다:

    ```php
    return redirect()->to(base_url('topic/get/' . $topic_id));
    ```

    - 이 방식은 `base_url()` 함수를 통해 기본 URL을 가져오고, 그 후 경로를 추가하여 리디렉션을 처리합니다.

    #### 3. **특정 URL로 리디렉션하기**
    - 특정 URL로 리디렉션을 해야 할 경우, `redirect()->to()` 메서드를 사용합니다:

    ```php
    return redirect()->to('http://localhost/폴더명/public/topic/' . $topic_id);
    ```

    이 코드는 직접 URL을 지정하여 리디렉션할 때 유용합니다.

    #### 4. **Route 설정 확인**
    - CodeIgniter 4에서 특정 라우트로 리디렉션할 경우, `routes.php` 파일에서 해당 경로가 설정되어 있는지 확인해야 합니다. 경로가 제대로 설정되지 않으면 리디렉션이 실패할 수 있습니다.

    예를 들어, `app/Config/Routes.php` 파일에 다음과 같이 경로를 설정합니다:

    ```php
    $routes->get('topic/get/(:num)', 'Topic::get/$1');
    ```

    그런 다음 리디렉션은 다음과 같이 처리됩니다:

    ```php
    return redirect()->to('/topic/get/' . $topic_id);
    ```

    #### 5. **index.php 제거 문제**
    - `index.php`가 URL에 포함되어야 하는 문제는 `public/.htaccess` 파일이 제대로 설정되지 않았기 때문일 수 있습니다. `.htaccess` 파일을 설정하여 `index.php`를 제거할 수 있습니다.

    `.htaccess` 파일을 확인하여 다음 내용이 포함되어 있는지 확인하세요:

    ```plaintext
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)$ index.php/$1 [L]
    ```

    이 설정이 있으면 URL에서 `index.php`를 제거할 수 있습니다. 만약 이 설정이 제대로 되어 있음에도 불구하고 `index.php`가 여전히 필요하다면, 서버 설정이나 다른 구성 요소가 문제일 수 있습니다. Apache 웹 서버의 `mod_rewrite` 모듈이 활성화되어 있는지 확인하세요.

    ### 요약
    - CodeIgniter 4에서는 `redirect()` 메서드를 `response` 객체를 통해 사용합니다.
    - `.env` 파일에서 `app.baseURL`을 설정하고, 그에 따라 리디렉션 URL을 작성합니다.
    - `index.php` 문제는 `.htaccess` 설정과 Apache 서버의 `mod_rewrite` 모듈 활성화 여부를 확인하여 해결할 수 있습니다.

    이 설정들이 제대로 되어 있다면, 리디렉션 문제는 해결될 것입니다.
    대화보기
    • 공부하기
      코드이그나이터4 하시면서 보시는 분들중에
      Redirect

      $this->response->redirect('http://localhost/폴더명/public/topic/'.$topic_id);
      이렇게 해야만 하는데
      해결법 아시는분...
    • 존레논아부지
      2022-10-26 완
    • jeisyoon
      2021.08.18 Library & Form Validation - OK

      Redirect 가 안되어 다음과 같이 수정하여 해결 하였습니다.

      config.php 수정 : $config['base_url'] = 'http://localhost/';
      topic.php 수정 : redirect(base_url().'index.php/topic/get/'.$topic_id);
    • 미댈
      도움이 됐습니다 ^^
      저도 redirect가 안돼서
      config.php에
      $config['base_url'] = 'http://localhost:80/';
      topic.php에는
      redirect(base_url().'index.php/topic/get/'.$topic_id);
      라고 추가하니까 됩니다.
      index.php는 없어도 된다고 하시는데 저는 안돼서 넣었습니다.
      대화보기
      • 미댈
        세번째 영상 7분쯤에

        function add($title, $description){
        $this->db->insert('topic',array(
        'title'=>$title,
        'description'=>$description
        'created'=>'now()'
        ));
        echo $this->db->last_query();
        echo $title;
        }

        에서 'created'=>'now()' 때문에 에러뜨시면 바로 뒤에 나오는 강의처럼

        function add($title, $description){
        $this->db->set('created', 'NOW()', false);
        $this->db->insert('topic',array(
        'title'=>$title,
        'description'=>$description
        ));
        echo $this->db->last_query();
        echo $title;
        }

        위처럼 $this->db->set('created', 'NOW()', false); 로 하시면 잘 동작합니다.
      • 서준수
        혹시나 싶어 글 남깁니다.
        해당 강의는 굉장히 오래전에 올린 것이기 때문에 부트스트랩 버전문제가 있습니다.
        현재와 많은 차이가 있으며 대부분이 변경되어 따라가도 정상 동작하지 않습니다.
      • jenny
        완료!
      • lunaman
        관련 글입니다.

        http://codeigniter-kr.org......386

        아마존서버 이용하는데 redirect 작동안해서
        base_url() 찍어보니 사설아이피를 보여주고 있더군요. ㅠㅠ;
        대화보기
        • Yosi Gom
          <?php echo validation_errors('<div class="error">', '</div>'); ?>

          이렇게 바꿔 넣으니까 잘 되네요!!
        • 김세창
          정말 재미있게 배웠습니다!!^^ ㅎㅎ 꿀잼..
        • Treasure_b
          현재 학습중입니다.

          3,06 사용중인데 redirect가 아예 안먹혀서

          topic.php 에서는 redirect(base_url().'topic/get/'.$topic_id);
          config.php 에서 $config['base_url'] = 'http://도메인주소'; 로 해결했습니다.
        • Jonny
          도움이 됐어요! 감사합니다!
          대화보기
          • 늘생릭코네
            잘 보았습니다
          • 신입1
            감사합니다. 말씀대로 수정과 삭제까지 완성했는데, 효율적인 코드인지는 모르겟어요 ㅠㅠㅋ
          • Jinny
            이고잉님이 응용해보라고 하셔서 삭제버튼도 만들어 봤습니다... 정말 힘드네요ㅠㅠㅠㅠ 중간에 삭제할 건지 한번 더 묻는 페이지 만들다 죽는 줄 알았습니다... 스스로 만들면서 깨우친건데, 이고잉님 진짜 대단하세요....
          • Jinny
            감사합니다 다만 저는 $config['base_url'] = 'http://localhost:8080/';이 아니라 $config['base_url'] = 'http://localhost:80/'; 으로 하니까 되더라구요! 어쨌든 덕분에 해결했습니다!
            대화보기
            • kala555
              저도 url이 http://[::1]/index.php/topic/get/28 이런식으로 떠서 검색을 해보니
              ::1은 ip6의 loopback이라고 하네요. 왜 이 값이 들어 갔는지는 잘 모르겠습니다.
              해결 방법은 /config/config.php의 base_url을 설정해 주면 됩니다.
              $config['base_url'] = 'http://localhost:8080/';

              끝에 반드시 '/'로 끝나야 합니다.
            • yoojat
              header('Location:/index.php/topic/get/'.$topic_id);
              결국 php 기본 내장 함수를 사용해서 해결하긴 했는데 여전히 찝찝하네요;;
              대화보기
              • yoojat
                저도 마찬가지로
                redirect('/topic/get'.$topic_id); 리다이렉트 하였는데
                [::1]에서 연결을 거부했습니다. 이렇게 뜨네요...

                URL 은 http://[::1]/index.php/topic/get/28 이렇게 뜬 상태입니다;;
              • Siwon Lee
                aledmana // 저도 안되서 id 최대값 가져오는 함수 만들어서 썼어요..ㅠㅠ


                topic.php

                $this->load->helper('url');
                $max_id = $this->topic_model->max_id();
                foreach($max_id as $entry) {
                redirect('/topic/get/'.$max_id->id);
                }



                topic_model.php

                public function max_id(){
                $this->db->select_max('id');
                return $this->db->get('topic')->row();
              • aledmana
                redirect('/topic/get'.$topic_id); 리다이렉트 하였는데
                [::1]/index.php/topic/get/11와 같이 localhost에 연결이 안되는데 왜 그런가요?
              • JustStudy
                고맙습니다
              • layman
                $this->input->get() 메소드 사용 방법좀 알려주세요.
                예로, a태그에 url과 파라미터를 보냈을 경우에는 get으로 전달되잖아요.

                코드이그나이터 사용자 메뉴얼에는 get()메소드에 인자 없이 호출하면 모든 get형식 파라미터를 연관배열로 받을 수 있다는데, 빈 배열이 넘어오더라구요.

                여기에서는 컨트롤러 function에서 바로 파라미터에 $id라고 써두셨는데, 그것과 $this->input->get()은 차이가 없는건지요?
              • SeungGyou Lee
                아...ㅋㅋㅋ 잼있어요.
              • will
                if ($this->form_validation->run() == FALSE){} 구문을 사용할때

                $this->form_validation->set_rules()조건문 자체가없으면 값이 무조건 false로 리턴됩니다. 참고들 하셔야할듯
              • 샤핀
                기존의 다른 강좌에 비해서 타이핑 하고 진행하는 속도가 빠른 편인거 같습니다. 중간 중간 따라가다가 제 오타로 인한 에러가 잦네요. ㅋ. 좋은 강의 감사드립니다.
              • 오오오오...
              • 김승갑
                잘이해되네요 ㅎ
              • styner007
                아,,
                <php?
                이렇게 한칸띄워지고 php 구문이 시작되었었내요 ,,, 꼼꼼하게 살펴보았어야,하는데,,감사합니다 ..
              • egoing
                그렇다면 혹시 php가 시작하는 구분자에 공백이 있을수도 있습니다.
                예를들어 아래 밑줄부터 코드가 시작된다면 <?php 사이에는 공백이 있게 됩니다.
                이 또한 출력이기 때문에 이런 문제가 생길 수 있습니다.
                -----------------------

                <?php
                대화보기
                • styner007
                  선생님 예제 그대로 따라 쳤는데요,,,
                  대화보기
                  • egoing
                    리다이렉션은 헤더를 브라우저에게 전송하는 것인데 헤더가 전송되기 전에 컨텐츠라 나타나면 http 표준 위반이기 때문에 오류가 발생합니다. 혹시 리다이렉션 명령 이전에 화면에 출력되는 내용이 있는지 확인해보세요.
                    대화보기
                    • styner007
                      문제가 있습니다.
                      Cannot modify header information - headers already sent by (output started at /Applications/mampstack-5.4.24-0/apache2/htdocs/CodeIgniter/application/controllers/topic.php:1)
                      이런식으로
                      redirect 함수위쪽에서 url helper 를 부르는 구문을 넣으면 에러가납니다.
                      물론 이걸 빼버리면 redirect 함수를 호출할 수 없다고 에러가 나오고요 ㅠㅠ
                    • Kyongrok Kim
                      무료 인터넷 강의가 이렇게 길어도 되나요? ^^ 긴 시간 강의하시느라 수고 하셨습니다. 감사합니다.
                    버전 관리
                    egoing@gmail.com
                    현재 버전
                    선택 버전
                    graphittie 자세히 보기