[mvc]간단한 php mvc 만들기 2

이전 강좌 [mvc]간단한 php mvc 만들기 1 에서는 php mvc 패턴의 기본적인 이해를 돕기 위해 model 부분은 빼고 페이지 구성과 연결 관계를 알아보는데 주력했다. 이제 여기서는 데이터베이스를 포함한 어플리케이션을 구성해보기로 하자. 즉 model 부분을 구성하여 데이터베이스을 어떻게 처리하는지 경험해볼 것이다.

● 데이터베이스 준비

XAMPP나 기타 웹서버를 사용하고 MySql 데이터베이스를 사용한다면 phpMyAdmin 응용프로그램을 잘 알 것이다. 지금부터 MySql에 데이터베이스와 테이블을 만들고 임시 데이터를 입력해보자.

# database , table 만들고 데이터 입력하기

phpMyAdmin을 실행하고 화면에서 [데이터베이스]를 선택한 후 표시되는 화면에서 [새 데이터베이스 만들기] 아래의 입력대화상자에 데이터베이스명 “mymvc”를 입력하고 데이터정렬방식으로 “utf8_general_ci”를 선택한 후 [만들기] 버튼을 누르면 데이터베이스 “mymvc”가 생성된다.

데이터베이스 만들기

데이터베이스 만들기

이제 만들어진 데이터베이스에 테이블 “board”를 만들어보자. 데이터베이스를 만들고 나면 목록에 데이터베이스명 “mymvc”가 표시된다. 이 이름을 클릭하면 데이터베이스 선택 화면으로 이동하고 테이블을 만들 수 있는 인터페이스가 표시된다.

테이블 만들기

테이블 만들기

테이블 명에 “board”를 입력하고 칼럼수를 5로 입력하여 실행버튼을 누른다.

테이블 구성

테이블 구성

테이블 board의 칼럼 구조는 다음과 같다.

board

컬럼명 종류 Null 기본값 설명 MIME
idx int(11) 아니오
title varchar(100) 아니오
content text 아니오
writer varchar(20) 아니오
wdate datetime 아니오

인덱스

인덱스가 설정되지 않았습니다!
키 이름 종류 고유값 압축됨 컬럼명 관계성 데이터정렬방식 Null 설명
PRIMARY BTREE 아니오 idx 10 A 아니오

이 메서드는 데이터베이스를 연결하고 그 결과로 DB 연결객체 $db 를 생성하는 코드를 포함하고 있다.

여기서 핵심적인 부분은 $this->db = new PDO(…) 부분이다. PDO DB connection은 아래와 같다.

위 코드에서 DB_TYPE과 DB_HOST, DB_NAME, DB_USER, DB_PASS는 config.php에서 정의한 상수이므로 이 상수들에 대입된 값을 적용해보면 이 코드는 ‘mysql:host=127.0.0.1;dbname=mymvc;charset=utf8′,’root’,”,$options) 가 된다. 여기서 추가된 $options는 아래와 같이 배열로 저장한 설정값들이 포함된다.

PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_OBJ

위 설정은 db에서 select 된 값을 fetch 할 때 적용하는 모드이다. 여기서는 FETCH_OBJ로 설정했다. FETCH_OBJ는 $row->title 과 같이 데이터를 출력할 수 있는 모드이다.

PDO의 fetch 모드에 대해 간단히 살펴보면 아래와 같은 것들이 있다.

PDO::FETCH_ASSOC : 추출된 데이터를 칼럼명으로 구분하는 배열로 반환($row[‘title’])
PDO::FETCH_NUM : 추출된 데이터를 칼럼 번호로 구분하는 배열로 반환, 첫 번째 칼럼은 0 ($row[0])
PDO::FETCH_BOTH : 칼럼명과 번호로 모두 접근 가능한 배열 반환
PDO::FETCH_OBJ : 레코드 셋을 객체로 반환하며 $row->title 과 같이 접근가능
이 외에서 몇 가지 모드가 더 있다. 기타 fetch 스타일에 관한 정보는 아래 링크를 통해 알아보자.

http://php.net/manual/en/pdostatement.fetch.php

DB를 연결할 때 PDO는 별도의 fetch 모드를 정해주지 않으면 PDO::FETCH_BOTH가 기본 값이 된다.

PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING

이 부분은 에러가 발생할 때 어떻게 처리할 지를 정하는 부분인데 PDO::ERRMODE_WARNING 은 에러가 발생하면 이를 표시해주도록 하고 있다. ATTR_ERRMODE의 값으로는 PDO::ERRMODE_WARNING 외에도 PDO::ERRMODE_SILENT, PDO::ERRMODE_EXCEPTION 이 있다. PDO::ERRMODE_SILENT는 에러가 발생해도 이를 표시하지 않도록 하며 PDO::ERRMODE_EXCEPTION는 예외처리 설정에 따르도록 하고 있다.

이 부분은 각각의 콘트롤러에서 model 파일을 열어 실행하고 새로운 model 객체를 생성하도록 하고 있다. 앞으로 model을 불러오려면 $board_model = $this->loadModel(‘BoardModel’); 과 같은 형식으로 하면 된다. strtolower($model_name) 코드는 입력된 모델 이름이 대문자를 포함하고 있더라도 모두 소문자로 변환해 파일명을 지정하기 때문에 앞으로 model 파일은 반드시 소문자로만 저장해야 할 것이다.

return new $model_name($this->db); 코드는 불러들인 model 파일로부터 새로는 model 객체를 생성하여 반환해준다. 이 때  DB 연결객체($this->db) 파라미터로 함께 넘겨준다. loadModel(‘BoardModel’)과 같이 호출하였다면, applicaion/model/boardmodel.php 파일을 읽어들이고, DB 연결 객체를 파라미터로 넘기며 객체 BoardModel을 생성한다.

● model 파일 만들기

이제 실제로 사용할 model 파일을 만들어보기로 하자. 이전의 강좌에서는 model 파일을 만들지 않았는데 이제 board를 연결할 모델을 하나 만들어보자.

application\models 폴더에 boardmodel.php를 아래의 코드를 포함해 저장해보자.

코드를 보면 클래스 명이 BoardModel인 것을 알 수 있다.  이 클래스 안에는 기본적으로 DB 연결객체를 받아서 객체로 지정하는 생성자 __construct($db) 와 게시판 리스트를 추출할 때 호출할  getBoardList() 메서드, 글 보기 때 호출할 getBoardView($idx) 메서드가 포함되어 있다. 각각을 살펴보자.

이 코드는 $model_name($this->db) 와 같이 객체를 생성할 때 받아온  DB 연결 객체를 클래스 자신의 프라퍼티로 만들어 주는 과정이다. try{ //…} catch() {/…} 구문은 try 구문 안에서 원하는 작업을 수행하고 이 때 에러가 발생하면 catch 구문이 처리되도록 한다. 여기서는 파라미터로 받아온 $db를 $this->db로 저장하며 이 때 에러가 발생하면 ‘데이터베이스 연결에 오류가 발생했습니다’라는 메시지를 출력하며 작업을 종료하도록 하고 있다. 문제가 없다면 $this->db에 DB 연결 객체가 저장될 것이다.

이 메서드는 board 테이블로부터 모든 행을 반환 받아 그 결과를 반환하는 기능을 한다. PDO의 메서드를 사용하므로 mysql_connect를 사용하던 학생들에게는 생소할 수 있지만 알고보면 훨씬 쉽다.

아마도 $query = $this->db->prepare($sql); 부분이 가장 생소할 것이다. 이것은 쿼리 문을 실행하기 전에 미리 준비하는 것으로 구문이나 데이터의 오류를 미리 체크하도록 한다. 이 방법을 사용하면 SQL injection 같은 공격을 미리 막을 수 있다. 이렇게 미리 준비한 후에는 $query->execute(); 구문으로 쿼리를 실행하게 되고, return $query->fetchAll(); 구문을 통해 모든 결과를 fetch하여 모든 행에 대한 추출결과를 반환한다.

이 코드는 view.php 페이지에서 보게 될 게시글의 내용 보기를 위한 메서드이다. 이 메서드는 $idx 즉 글 번호를 기본적으로 받아오게 되어 있다. 물론 완벽하게 완성되는 코드에는 만일 $idx가 전달되지 못한 경우와 $idx가 정수가 아닌 경우 등을 모두 걸러내도록 해야겠지만 여기서는 일단 생략한다.

이 메서드는 getBoardList()메서드와 비슷하지만 마지막에 fetchAll 대신에 fetch를 사용한 것이 다르다. 이 것은 보통 반복문 속에서 다음의 레코드 한 줄을 반환하는데 여기서는 하나의 행이 추출되었으므로 그 하나의 행을 배열로 변환하여 반환하게 된다.

이 결과는 나중에 $row->title 과 같은 형식으로 받을 수 있다.

● board 콘트롤러 수정하기

이전 강좌에서 board 콘트롤러를 만든 적이 있다. 그러나 아직 DB 연결 전이라 model 부분은 생략되어 있었다. 이제 model 파일을 만들었으므로 이를 불러와 처리하는 코드로 수정해보자.

# application\controller\board.php

 

이전 강좌의 코드에 몇 줄이 추가된 것을 제외하고는 큰 변화는 없다. 먼저 index 메서드를 살펴보자. 다음의 코드가 추가되었다.

$board_model = $this->loadModel(‘BoardModel’); 코드는 모델을 불러와 클래스를 생성하고 이를 $board_model에 저장하는 코드이다. loadModel 메서드는 앞에서 만든 controller.php에 저장되어 있는데 어떻게 이 파일에서 호출할 수 있을까? 그것은 이 콘트롤러가 선언된 부분을 살펴보면 알 수 있다.

class Board extends Controller

위 코드를 보면 이미 설명한 바 있듯이 Board 라는 클래스를 생성하면서 Controller 라는 클래스를 상속받도록 한 것이다. 이렇게 하면 controller.php에 있는 Controller 클래스가 실행되고 그 클래스에 포함된 프라퍼티와 메서드가 Board에도 그대로 적용되는 것이다.

이 코드는 클래스 BoardModel 안에 포함된 메서드 getBoardList()를 호출하여 반환된 결과를 $board_list에 저장하도록 한다. boardmodel.php 파일을 살펴보면 board 테이블을 select 하여 그 결과를 반환(return)하게 되어 있는데 이를 $board_list가 받아서 저장하는 것이다. $board_list는 실제로 테이블을 select 한 전체 값들이 저장된 배열이고 이 배열은 뒤에서 볼 view 파일인 index.php에서 활용하게 된다.

이 코드는 view 메서드에 추가된 코드이다. 역시 BoardModel 클래스 파일을 열어 model 객체를 생성한다. 그리고 나서 getBoardView($idx)와 같이 하여 하나의 글 내용을 배열로 추출하여 $board_view에 저장한다. 여기서 $idx가 어디서 왔는지 생각해보자. 이 부분은 application\libs\application.php 파일에서 찾아볼 수 있다. application.php 파일에 보면 콘트롤러를 생성하고 메서드를 호출할 때 첫 번째와 두 번째 값(주소 끝에 /로 구분되어 입력된 값)을 사용하고 나머지는 파라미터로 넘기기로 했었다. 따라서 /board/view/3 을 브라우저 주소창에 입력하고 실행하면 board 콘트롤러 객체를 생성하고 그 속의 view 메서를 실행하며 3은 괄호 () 안에 파라미터로 넘겨주게 된다. 이 첫 번째 파라미터를 $idx 라는 변수로 받은 것이다.

● view 파일 수정하기

이전 강좌에서 board 콘트롤러를 위한 view 파일 세 개(index.php, write.php, view.php)를 만들어 두었다. 그러나 이 view 파일들은 DB 연결 전이라 그냥 텍스트로 처리하여 화면에 보이게만 하였다. 이제 실제 DB에 저장된 값들을 표시하고 활용하는 view 파일들로 만들어보자.

# application\views\board\index.php

이전 강좌의 코드에서는 이 파일의 ul 태그 안에 여러 줄의 li 태그를 직접 입력하여 글 내용을 표시하고 링크를 추가했었다.

그러나 여기에서는 앞의 board 콘트롤러가 boardmodel을 생성하고 index 메서드를 호출하여 반환받은 배열 $board_list를 활용함으로써 실제 DB에 저장된 내용을 목록에 표시하도록 한다.

foreach는 배열의 크기에 따라 처음부터 반복하며 값을 추출하여 사용할 수 있도록 하는 구문이다. foreach($board_list as $row)와 같이 하면 $board_list 배열을 한 줄 씩 추출하여 $row에 저장한다. 따라서 반복이 진행되는 동안 각 행의 값들은 $row에 저장되므로 실제 출력할 때는 $row 배열을 활용하면 된다.

이렇게 해서 반복되는 동안 글 번호와 제목, 글쓴이와 날짜가 표시되는 li를 화면에 출력하게 된다.

나머지 코드는 크게 바뀐 것이 없다.

이제 실제 이 결과가 실행되는지 확인해보자. 예제의 메뉴에서 게시판을 클릭하거나 주소창에서 http://127.0.0.1/board/ 또는 http://127.0.0.1/board/index 와 같이 입력해보자.

board list 실행 결과

board list 실행 결과

화면에 정상적으로 글 목록이 표시된 것으 확인 할 수 있다. 각각의 리스트는 /board/view/번호 와 같은 링크를 가지고 있으므로 글 목록을 클릭하면 view 메서드가 실행될 것이다. 물론 번호는 파라미터로 넘겨져 view 메서드가 $idx로 받아 처리하고 그 결과를 반환하게 되어 있다.

이제 글보기의 view인 view.php 파일을 수정해보자.

# application\views\board\view.php

코드를 보면 board 콘트롤러에서 boardmodel을 통해 얻어온 데이터 결과 $board_view 배열을 화면에 표시해주는 것으로 변경했다. 이 결과는 어떻게 되는지 실행해보자.

위 게시판 목록에서 하나의 줄을 클릭해보면 board view로 넘어간다. 결과를 확인하면 다음과 같다.

글보기 페이지

글보기 페이지

이렇게 해서 데이터베이스의 내용을 화면에 목록과 보기로 표시해주는 mvc 프로그램의 예제를 만들어 보았다. 아래에 전체 소스와 온라인 데모 링크를 제공하였다.

다운로드 : php-mvc-simple-htdocs-2.zip
온라인데모 : http://webskills.kr/php-mvc/v2/

다음 글에는 글 쓰기, 삭제, 수정은 어떻게 처리하는지 살펴보기로 하자.

 

Share the joy
  •  
  •  
  •  
  •  

One thought on “[mvc]간단한 php mvc 만들기 2

댓글 남기기