Programming-[Backend]/php, codeigniter

생활코딩 php, codeigniter 강의 - 1. php 기본, codeigniter MVC(w/ Docker, MacOS)

컴퓨터 탐험가 찰리 2024. 4. 2. 14:51
728x90
반응형

1. php 문법

자바와 비교해서 유의해야할 점이나 중요한 부분만 작성해놓는다.
 

공통

자바와 똑같이 세미콜론으로 표현을 끝낸다.
echo 또는 print 명령어로 출력한다.
. 으로 string concatenation을 할 수 있다.
여러 줄 주석은 자바처럼 /* */ 로 처리할 수 있다.
 
$로 변수를 초기화할 수 있다.
변수 사용도 $로 불러와서 사용한다.
 
함수들
var_dump: 타입 및 값 출력
isset: 변수의 null 확인
array("원소들", ...) 로 배열을 선언한다.
scandir(): 특정 경로의 파일 목록을 배열로 불러온다.
basename(): 디렉토리 중 파일의 이름만 따온다. 보안상 공격자가 디렉토리 탐색을 못하도록 막아줄 수 있다.
 
함수
함수는 코드의 복잡도를 낮추고 의미를 부여한다.
function이라는 키워드를 함수 이름 앞에 붙여서 함수를 정의한다.
함수의 파라미터는 $를 붙여주어 선언한다.

<?php
function sum($left, $right){
	return $left + $right;
}
?>

 
모듈
모듈을 import 하는 것은 require 구문으로 할 수 있다.

<?php
require('lib/print.php');
?>

 
require_once를 사용해주면 계층 구조에 따라 중복해서 require를 호출하는 경우에도 에러가 나지 않게 할 수 있다.
 
 
 

2. codeigniter

 

설치(Docker 방식)

 
나는 macOS 환경이고, 굳이 php나 codeigniter를 설치하지 않고 사용하고 싶어서 누군가 미리 만들어놓은 github 소스 코드를 찾았다.
https://github.com/bdsach/codeigniter3-docker/tree/main
 
docker-compose 파일을 보면 mariadb를 사용하고 해당 db에 의존하는 phpmyadmin, php:7.4-apache 서버를 컨테이너로 띄우는 것을 확인할 수 있다. README.md 파일에 나와있는대로 docker compose up -d를 실행하면 컨테이너들이 실행된다. 그리고 호스트의 7700번 포트를 컨테이너의 80번 포트로 매핑하도록 해놔서, localhost:7700으로 접속하면 된다.
 
다만 접속 시, users 테이블이 없다고 나와서 docker desktop으로 직접 container에 접속하여 다음 명령어들을 입력해줬다.

 

mysql -uroot -p

//docker-compose 파일 설정에 이렇게 설정해놨음
password 입력: MYSQL_ROOT_PASSWORD 

//이것도 마찬가지로 docker-compose 설정상 기본 데이터베이스
use MY_DATABASE

// README.md 파일에 포함된 create table users(... 이하 SQL문을 모두 실행한다.

 
그리고 다시 접속해보면 정상적으로 접속이 가능함을 확인할 수 있다.

 
 
강의 코드
브랜치마다 코드들이 나뉘어져있다. 아래 링크는 맨 처음 controller 수업의 코드들이다. 해당 링크는 무시하고 그냥 영상을 보면서 따라해도 되긴한다.
https://github.com/egoing/codeigniter_codeingeverbody/tree/Controller
 
참고자료
codeigniter 한국 포럼 페이지에서 매뉴얼 및 다양한 정보들을 확인할 수 있다.
https://www.cikorea.net/#google_vignette
 

2-1. Controller

controller를 작성하는 규칙이 있다.

  • controllers 패키지 아래에 작성한다.
  • class명과 파일명은 대소문자까지 일치해야한다.
  • 아무런 설정이 없다면 기본적으로 class 내부의 index() 메서드에 정의한 내용대로 실행된다.
  • _로 시작하는 메서드를 만드는 경우 private처리되어 routing에 걸리지 않는다.
class Welcome extends CI_Controller {

    public function index()
    {
       $this->load->view('welcome_message');
       $this->load->view('users', array('users' => $this->db->get('users')->result()));
    }
}

 
이렇게 작성하면,
{host 주소}/index.php/welcome 또는
{host 주소}/index.php/welcome/index
로 라우팅 했을 때 index() 메서드가 실행된다.
 
다음과 같이 일반화하여 표시할 수 있다.

http://example.com/[controller-class]/[controller-method]/[arguments]

 
 

2-2. View

view는 UI와 관련된 html 코드들을 작성하는 곳이다. 서버사이드 렌더링을 해주는 부분이다. view를 작성하는 규칙은 다음과 같다.

  • views 라는 패키지에 위치해야한다
  • $this->load->view("이동할 view 이름"); 으로 작성해준다. view 이름에서 이름 뒤 확장자명 .php 는 작성하지 않는다.

위에서 살펴본 Welcome.php controller의 index() 메서드에는 welcome_message, users라는 이름을 갖는 view를 불러오도록 되어있으므로 아래와 같은 화면이 출력된다.

 
 
 

2-3. Model

데이터와 관련된 부분이 Model이다. 주로 데이터베이스와 연결해서 사용하므로 데이터베이스와 상호작용하는 부분이라고 생각하면 된다. 따라서 model을 이해하기 위해서 데이터베이스와 관련된 내용부터 숙지해야한다.
 
데이터베이스
codeigniter와 관련된 설정은 Basepath/config 패키지에서 한다. 여기서 데이터베이스 관련 설정은 database.php 파일에 적어놓는다.
 
hostname이 'db'라고 되어있다. 그와 더불어 username, password등 기본 정보들이 설정되어있는데, 이는 docker-compose로 처리시 작성해준 부분과 일치해야한다.

$db['default'] = array(
    'dsn'  => '',
    'hostname' => 'db',
    'username' => 'MYSQL_USER',
    'password' => 'MYSQL_PASSWORD',
    'database' => 'MY_DATABASE',
    'dbdriver' => 'mysqli',
    'dbprefix' => '',
    'pconnect' => FALSE,
    'db_debug' => (ENVIRONMENT !== 'production'),
    'cache_on' => FALSE,
    'cachedir' => '',
    'char_set' => 'utf8',
    'dbcollat' => 'utf8_general_ci',
    'swap_pre' => '',
    'encrypt' => FALSE,
    'compress' => FALSE,
    'stricton' => FALSE,
    'failover' => array(),
    'save_queries' => TRUE
);

 
이렇게 설정된 데이터베이스는 각종 라이브러리들을 로드하는 config/autoload.php 부분에 작성하여 로드되도록 해주어야한다. libraries라는 배열에 database라는 배열을 추가해주는 방식이다.

//중략
$autoload['libraries'] = array('database');
//중략

 
controller의 메서드에서 $this->load->database(); 구문을 입력하여 database를 불러올 수 있다.
 
model
models 디렉토리에 작성한다. 이미지 파일상 db에 users 라는 이름의 모델을 생성해놨기 때문에, 아래처럼 Users_Model로 작성해주었다.

<?php
class Users_model extends CI_Model {
    public function __construct()
    {
        parent::__construct();
    }

    public function list() {
        return $this->db->query('SELECT * FROM users')->result();
    }
}

 
생성자는 부모의 생성자를 따르도록 하고, list 메서드를 만들었다. list에서는 

$this->db->query()->result();

 
구문으로 db에 접근하여 query문을 수행하고 그 결과를 result()로 받아온다.
 
그리고 라우팅을 위해 users.php라는 controller를 작성해주었다.

class Users extends CI_Controller {

    public function index()
    {
        $this->load->database();
        $this->load->model('users_model');
        $data = $this->users_model->list();
        foreach($data as $entry) {
        var_dump($entry);
        }
    }
}

 
database()를 불러옥, 모델을 불러온 뒤 모델의 list() 메서드에 접근하여 데이터를 가져오는 방식이다. 그리고 foreach 구문을 사용하여 각 데이터를 출력해주는 방식이다.
index.php/users에 접속하면 users에 넣어둔 데이터들이 잘 출력되는 것을 볼 수 있다.

 
만약 id값만 추출하고 싶다면

var_dump($entry->id);

라고 입력하면 된다. 그리고 이 값들을 view 쪽에서 html 형식으로 그대로 바로 리턴하고 싶다면 아래와 같은 ?= 문법으로 가능하다.

<?php foreach ($users as $user) : ?>
    <div class="row py-2">
        <div class="col">
            <?= $user->id ?>
        </div>
        <div class="col">
            <?= $user->first_name ?>
        </div>
        <div class="col">
            <?= $user->last_name ?>
        </div>
        <div class="col">
            <?= $user->email ?>
        </div>
    </div>
<?php endforeach; ?>

 
 
 
result() 대신 result_array()를 사용하면 object로 entry 값들이 출력되는 것이 아니라 array로 리턴받을 수 있다.
 
다시 Welcome.php Controller로 돌아와서 아래 구문을 이해해보면,

$this->load->view('users', array('users' => $this->db->get('users')->result()));

 
view() 메서드의 첫 번째 인자인 users.php 라는 view로 이동하되, db의 users 모델에 get을 한 결과를 'users'라는 이름으로 전달하도록 view() 메서드의 두 번째 인자로 전달하는 방식인 것이다.
 
 
인자 전달하기
 
메서드의 인자를 아래처럼 controller에서 model로 전달할 수 있다.
 
- controller 코드
get 메서드를 정의하고, $id로 받을 파라미터를 정의했다. 그리고 users_model->get($id)로 메서드를 호출했다.

public function get($id) {
    $this->load->database();
    $this->load->model('users_model');
    $data = $this->users_model->get($id);
    var_dump($data);
}

 
- Users_model
아래처럼 get 메서드를 작성해주면 된다. query문 작성 시 변수는 작은따옴표로 다시 한번 감싸줘야한다. String 방식이라 잘못입력할 위험이 있어서, 아래 두 줄의 주석문처럼 where 절을 써서 쿼리를 줄인 뒤에, get() 메서드로 결과를 가져올 수도 있다. 윗 줄의 내용에 의해서 where절이 적용된 채로 아랫줄의 쿼리 실행문(get)이 실행되기 떄문에 결과가 한정된다. 이처럼 처리하는 방식이 Codeigniter에서 제공하는 Query Builder 방식이고, 이런 방식일 때 데이터베이스 vendor와 상관없이 코드가 정상적으로 동작하므로 추천되는 방식이다. SQL문을 직접 작성하는 방식은 세세한 부분으로 들어가면 데이터베이스 vendor마다 조금씩 다를 수 있기 때문에 이식성이 떨어지고 위험하다.

public function get($id) {
        return $this->db->query("SELECT * FROM users WHERE users.id='$id'")->result();
//        $this->db->where('users.id', $id);
//        return $this->db->get('users')->result();

    }

 
index.php/users/get/1 로 접속하면 아래처럼 출력된다.

 
 
강의에서는 active record라는 방식을 사용하고, result() 대신 row()를 호출하여 1개 건만 가져오는 방식도 소개한다.

return $this->db->get_where('users', array('id'=>$id))->row();

 
 
그리고 database()를 불러오는 부분이나 model을 불러오는 등 멤버 메서드에서 공통적으로 호출하는 부분들은 생성자 부분에 넣어주는 것이 깔끔하다.
 

class Users extends CI_Controller {

    public function __construct()
    {
        parent::__construct();
        $this->load->database();
        $this->load->model('users_model');
    }
    
    // 중략

 
 
 


참조

생활코딩 유튜브 채널
https://www.youtube.com/@coohde

728x90
반응형