2025.06.15. > 이 글은 2021년에 쓰여진 글입니다. > 그 동안 코드이그나이터4도 많이 변했고, 개발의 세계도 많이 변했습니다. > 한동안 비공개로 했다가 다시 공개로 전환한 이유는, 의외로 이 글을 찾으시는 분들의 이메일을 종종 받았기 때문입니다. > 실
HTTP 기초 우리는 이 글에서 웹서비스를 구축하는 방법을 연습합니다. 웹은 http 프로토콜로 통신하므로 http 프로토콜에 대해서 알아보겠습니다. HTTP란? http는 Hyper Text Transfer protocol - 하이퍼 텍스트 트랜스퍼 프로토콜의 약자
HTTP 메소드 HTTP 메소드의 정의 클라이언트는 필요할 때 서버에 자원(Resource - 리소스)을 요청하고, 서버는 요청에 따라 자원을 보내주거나, 변경하는 일을 하게 됩니다. 자원을 어떻게 다루느냐에 따라서 http 메소드가 달라집니다. "동사(verb)"
URI 분리해 보기 http://www.example.com:80/path/to/myfile.html?key1=value1&key2=value2#SomewhereInTheDocument 형태로 된 주소를 많이 본 적이 있으실 겁니다. 위와 같은 인터넷 주소를 URI(U
HTTP 요청 형태 클라이언트가 서버로 메세지를 보내 자원을 요청하는 것을 요청(request - 리퀘스트)라고 부릅니다. HTTP 규약에서 요청 메세지는 아래와 같은 형태로 이루어집니다. 아래 요청은 일반적인 HTTP GET 요청시 요청 메세지입니다. 첫번째 줄은
HTTP와 HTTPS HTTPS는 Hyper Text Transfer Protocol Secure의 약자입니다. S가 Secure - 보안의 약자임에서 알 수 있듯이 클라이언트와 서버 사이의 통신 규약에 보안을 더한 것입니다. 구체적으로는 RSA 알고리즘으로 암복호화
MVC MVC의 정의 MVC는 Model View Controller의 약자로 개발을 할 때 각 파일의 역할을 나누는 프로그래밍 패턴을 말합니다. Model(모델)은 데이터를 나타냅니다. 데이터를 저장하고, 읽어오고, 삭제합니다. View(뷰)는 화면을 나타냅니다.
MVC의 역사 MVC가 유행하기 전, 웹 개발은 데이터, 로직, 출력이 한 군데 섞여 있었습니다. 그때는 그래도 괜찮았습니다. 웹의 초기였고, 다들 그렇게 만들었으니까요. 시스템을 수정한다는 개념보다는 폭발적으로 만들어지기만 하던 시기였으므로 이렇게 만들어도 모든게
준비하기 필요한 프로그램 설치 PHPStorm PHP를 개발할 수 있는 에디터는 세상에 있는 에디터만큼이나 충분히 많습니다. 윈도우즈를 사용한다면 메모장으로도 개발할 수 있죠. 하지만 개발자의 시간은 소중하므로 최대한 개발 생산성에 도움이 되는 도구를 사용하는 것도
XAMPP XAMPP는 아파치(Apache) 웹 서버, 마이에스큐엘(MySQL) 데이터베이스 혹은, 마리아디비 (MariaDB) 데이터베이스, PHP, 펄(Perl)이 합쳐진 패키지입니다. PHP 서버 올인원 패키지인 셈입니다. 개별적으로 아파치, MariaDB, P
GIT GIT은 프로젝트의 소스 코드를 관리하는 버전 관리 시스템(VCS - Version Control System) 중 하나입니다. 현대 개발에서 프로그램의 변경점을 관리하고 소스 코드의 이력을 관리하는 점은 몹시 중요합니다. GIT은 SVN의 뒤를 이어 2021
코드나이터4는 PHP 7.2 버전 이상에서 실행되므로 반드시 PHP 7.2 버전 이상이 필요합니다. 또한 코드이그나이터4가 실행되려면 꼭 필요한 익스텐션이 2개 있습니다. 바로 국제화 익스텐션 intl과 멀티바이트 익스텐션 mbstring입니다. PHP에서 익스텐션이
코드이그나이터4 프로젝트 설치 Composer를 이용한 신규 프로젝트 생성 PHPStorm에서 생성하기 PHPStorm에서 File->New Project를 선택합니다. 팝업에서 Composer Project를 선택합니다. 이미지 Location : 프로젝트 디렉
코드이그나이터4 환경 설정 환경 설정 파일 만들기 .env 파일은 코드이그나이터4의 기본 환경 설정 파일입니다. 만약 .env 파일에 정의되어 있지 않은 내용은 app/Config/App.php에 정의된 내용으로 대체됩니다. 바꾸어 말하면, .env파일의 설정이 코드
첫번째 페이지 보여주기 코드이그나이터4에는 spark라는 파일이 프로젝트 루트에 존재합니다. 이 파일은 코드이그나이터4의 라우팅 규칙을 이해할 수 있는 PHP 내장 웹 서버를 실행시킵니다. 원래 PHP 내장 웹 서버는 코드이그나이터의 라우팅 규칙을 이해할 수 없기 때문
컨트롤러 다루기 이번 장에서 배울 것 코드이그나이터4에서 컨트롤러는 브라우저를 비롯한 클라이언트의 요청(request)을 받아 응답(response)하는 역할을 하는 PHP 클래스입니다. 이번 장에서는 코드이그나이터4의 컨트롤러에 대해 개별 기능 사용법을 익혀 보겠습
엔드포인트 파라미터 입력받기 엔드포인트에 파라미터를 입력받는 방법을 알아보겠습니다. Sample 컨트롤러에 아래의 메소드를 두 개 추가합니다. /app/Controllers/Sample.php http://localhost:8080/sample/param/ci4 UR
만약에 파라미터가 선언된 엔드포인트 메소드에 파라미터가 전달되지 않으면 어떻게 될까요? http://localhost:8080/sample/param에 접속해서 결과를 확인하겠습니다. 확인할 수 있듯이 ArgumentCountError 오류가 납니다. 이런 경우를 방
우리는 이제까지 문자열을 그대로 브라우저에 보여줬습니다. 마치 C언어로 CGI를 만들던 시절처럼 말이죠. 간단한 문자열을 만들기에는 이런 방법도 나쁘지 않지만, 복잡한 HTML을 다루기에는 너무 힘들 겁니다. 그래서 MVC 중 View를 분리하겠습니다. 뷰는 a) 어떤
POST 데이터 읽기 웹 개발에서는 리소스의 조회를 요청하는 GET 외에도 리소스의 변경을 요청하는 POST 요청도 자주 쓰입니다. 이번 챕터에서는 POST 데이터를 읽는 방법을 확인해 보겠습니다. 흐름은 아래와 같습니다. 브라우저에서 http://localhost:
세션 다루기 세션은 서버에 저장되는 정보 조각입니다. 데이터베이스에 저장되는 영구적인 데이터가 아니라, 각 사용자(클라이언트)별로 관리되는 정보를 담을 때 사용합니다. 세션이 가장 많이 쓰이는 예시로는 로그인을 들 수 있습니다. 각 클라이언트마다 서로 다른 로그인 정
JSON 응답하기 현대의 웹 서버는 HTML만 보여주지 않습니다. JSON도 보여주고, XML도 보여주고, 여튼 여러가지 데이터 형식을 보여줍니다. 특히 2000년대 중반 이후 Ajax가 부상하면서 JSON 형식은 필수가 되었죠. 이번 챕터에서는 코드이그나이터에서 JS
유효성 검사하기 웹 프로그래밍의 오랜 격언 중 하나는 "사용자의 입력은 믿지 말 것"입니다. 사용자가 굳이 악의가 있어서라기보다는 사용법이 익숙치 않아서, 혹은 재미로, 어떤 이유로든간에 개발자가 의도한 바와 다르게 작동시킨다는거죠. 그래서 우리는 유효성 검사가 필요합
리다이렉트 리다이렉트는 다른 페이지로 이동하는 것을 말합니다. 기술적으로 말하면 HTTP 응답 헤더에 301 코드와 이동할 페이지를 기재함으로써 클라이언트(브라우저)에게 페이지 이동을 요청하는 것입니다. Sample 컨트롤러에 아래의 메소드를 추가합니다. /app/C
뷰 다루기 뷰 다루기 MVC모델 중 V는 뷰를 다룹니다. 주어진 데이터를 가지고 화면을 구성하는 것을 현대 웹 개발에서는 일반적으로 "템플릿"이라고 부릅니다. 다행히도 PHP는 태생부터 "HTML사이에 데이터 조각을 넣는 방식"으로 설계되었기 때문에 화면을 다루는데
목록 반복문을 통해서 뷰에 목록을 보여주는 방법을 알아보겠습니다. View 컨트롤러에 아래의 메소드를 추가합니다. app/Controllers/View.php (1) PHP의 range 함수를 통해 65-90까지의 숫자 배열을 만들어 냅니다. 참고로 (1)-(3)까
체크 박스를 다루는 방법을 알아보겠습니다. 이번 챕터에서는 체크박스 1개와 체크박스 여러개를 처리하는 방법을 둘 다 확인합니다. 또한 입력한 값을 보존하는 방법도 보겠습니다. 우리가 만드는 화면은 아래와 같습니다. View 컨트롤러에 아래의 메소드를 추가합니다. ap
여러개의 항목 중 하나를 선택하는 라디오 버튼에 대해 알아보겠습니다. 우리가 만들 페이지는 아래와 같습니다. View 컨트롤러에 아래의 메소드를 추가합니다. app/Controllers/View.php 코드를 확인해 보겠습니다. (1) 스포츠 데이터를 연관배열로 정
선택 상자 여러개의 항목 중 하나를 선택하는 선택 상자에 대해 알아보겠습니다. 일반적으로 항목이 적고 한번에 항목을 봐야 할 때는 라디오 버튼을, 선택할 항목이 많다면 선택 상자를 통해 UI를 구성합니다. 우리가 만들 페이지는 아래와 같습니다. View 컨트롤러에 아
HTML에서 기본이 되는 태그인 텍스트 상자를 알아보겠습니다. 텍스트 상자는 한 줄 입력시에 사용됩니다. 우리가 만들 페이지는 아래와 같습니다. View 컨트롤러에 아래의 메소드를 추가합니다. app/Controllers/View.php 특별한 코드는 없으므로 컨트
비밀번호를 입력할 수 있는 상자를 알아보겠습니다. 비밀번호 상자는 텍스트 입력 상자와 동일하지만, 입력한 내용이 HTML에 보이지 않고 * 등으로 가려지는 것이 특징입니다. 우리가 만들 페이지는 아래와 같습니다. View 컨트롤러에 아래의 메소드를 추가합니다. app
텍스트 영역 여러 줄을 입력할 수 있는 텍스트 영역을 알아보겠습니다. 우리가 만들 페이지는 아래와 같습니다. View 컨트롤러에 아래의 메소드를 추가합니다. app/Controllers/View.php 특별한 코드는 없으므로 컨트롤러 설명은 생략합니다. 뷰를 추가
테이블 HTML에서 표를 만들 수 있는 테이블을 알아보겠습니다. 최근에는 레이아웃을 맞출 때 테이블을 잘 안 쓰는 추세기는 하지만, 실제로 표가 필요한 경우는 의외로 많으므로 테이블 태그에 대해 알고는 있어야 합니다. 우리가 만들 페이지는 아래와 같습니다. 이번 챕터
링크 HTML에서 다른 웹 자원 주소로 연결하는 링크를 다루는 방법을 알아보겠습니다. 우리가 만들 페이지는 아래와 같습니다. View 컨트롤러에 아래의 메소드를 추가합니다. app/Controllers/View.php (1) 뷰에 전달할 데이터를 설정합니다. url
이미지 HTML에서 이미지를 표기하는 방법을 알아보겠습니다. 우리가 만들 페이지는 아래와 같습니다. 웹서버의 이미지를 표기하는 방법을 알아보기 위해 예제 이미지를 다운로드하겠습니다. https://www.php.net/images/logos/php-logo.svg 이
첨부파일 코드이그나이터4에서 첨부파일을 다루는 방법을 확인해 보겠습니다. 우리가 만들 페이지는 아래와 같습니다. View 컨트롤러에 아래의 메소드를 추가합니다. app/Controllers/View.php (1) 코드이그나이터4 컨트롤러에서 파일 정보를 가지고 오기
첨부파일 여러개 코드이그나이터4에서 여러개의 첨부파일을 다루는 방법을 확인해 보겠습니다. 주요 로직은 첨부파일과 동일하므로 여러개를 읽을 때 처리 절차만 중점적으로 보면 됩니다. 우리가 만들 페이지는 아래와 같습니다. 코드는 https://github.com/koe
레이아웃 사용하기 많은 사이트들이 레이아웃을 사용합니다. 공통의 헤더, 공통의 푸터 등 어느 페이지에서나 사용되는 공통 화면들이 있고, 본문만 바뀌는 경우가 많습니다. 이렇게 공통된 부분은 한 곳에 모아두고, 본문만 바뀌는 것을 레이아웃이라고 부릅니다. 코드이그나이터
데이터베이스 준비하기 데이터베이스 접속 준비 데이터를 저장하기 위해 데이터베이스를 준비하겠습니다. 우선 XAMPP Control Panel에서 MySQL 항목이 켜져 있는지 확인합니다. Stop으로 되어 있다면 이미 시작된 것입니다. 시작되어 있지 않다면 Start
코드이그나이터4에서 데이터베이스 접속 정보 관리하기 코드이그나이터4에서 대부분의 설정은 .env 파일이나 app/Config/App.php 파일이 담당합니다. 데이터베이스 설정도 마찬가지로 .env파일에서 할 수 있습니다. document_root/.env 파일을 열어
코드이그나이터4의 모델이란? 코드이그나이터4에서 모델은 데이터베이스 테이블과 매핑되는 PHP 클래스입니다. 모델을 통해서 데이터베이스에 생성, 읽기, 수정, 삭제(Create, Read, Update, Delete) 를 할 수 있습니다. 혹시 ORM을 다루어본 적이 있
마이그레이션 마이그레이션이란? 최근에 나온 대부분의 웹 프레임워크는 "마이그레이션"을 사용합니다. 간단하게 말하면, 자동으로 "데이터베이스의 버전 관리"를 하는 겁니다. 많은 서비스에서 프로그램과 데이터베이스는 끊임없이 변화해 나갑니다. 이 중 프로그램은 형상 관리(
풍부한 모델 사용하기 코드이그나이터4는 기본 모델 외에 자동으로 생성,수정,삭제 시간을 넣어주는 기능이 있습니다. 또한 삭제를 컨트롤하는 소프트 딜리트(soft delete)도 있죠. 기본 모델보다 조금 더 풍부한 기능을 사용해 보겠습니다. 데이터베이스 테이블 생성
모델 유효성 검사 모델 유효성 검사 규칙 컨트롤러와 마찬가지로 모델에서도 유효성을 검사할 수 있습니다. 컨트롤러와 모델, 둘 다 유효성을 검사할 수 있다면 어디에서 유효성을 검사해야 할 지 헷깔릴 수도 있는데요. 저는 아래와 같은 규칙으로 검사합니다. 컨트롤러의 값
엔티티 다루기 엔티티의 정의 엔티티는 비즈니스 로직을 다루는 방법 중 하나입니다. 데이터베이스 테이블 한개의 행에 해당하는 객체로 행의 정보 중 비즈니스 로직을 처리하는 부분을 가져와서 분리하는 것입니다. 코드이그나이터4에서 엔티티는 필수는 아닙니다. 반드시 사용할
모델 조인 데이터베이스 테이블 조인의 정의 관계형 데이터베이스를 다루다보면 테이블 하나만 다루는 경우는 거의 없습니다. 대부분 여러 테이블의 데이터를 엮어서 가지고 오죠. 여러 테이블의 데이터를 엮는 것을 조인(join)이라고 부릅니다. 이번에는 코드이그나이터4에서
마크다운 블로그 MVP 만들기 마크다운 블로그 시스템 기획하기 린 스타트업 방법론 많은 기업들은 제품을 출시하기 전에 프로토타이핑을 합니다. 제품이 소비자들에게 어필할 수 있을 지 최소 기능 제품(MVP - Minimal Value Product)을 만든 후 먼저
마크다운 블로그 마크다운이란? 마크다운은 일반 텍스트에 간단한 마크업 기호를 붙여 글을 꾸밀 수 있는 형식을 말합니다. 웹 개발자에게 가장 익숙한 마크업 언어는 HTML(Hyper Text Markup Language) 일텐데요. 마크다운은 이를 경량화한 것입니다.
마크다운 블로그 프로토타입 만들기 게시글 요건 정의하기 블로그는 글을 쓸 수 있는 공간이므로, 게시글이 가장 중요한 기능입니다. 따라서 게시글 기능부터 만들어 보겠습니다. 게시글은 회원이 쓸 수 있는 글입니다. 게시글의 속성은 아래와 같습니다. 게시글 제목 : 4
이번 챕터의 글은 https://github.com/koeunyeon/ci4/tree/blog-controller 에 있습니다. 글 컨트롤러 파일 만들기 컨트롤러를 만들겠습니다. 우선 글 요건에 따라 어떤 기능이 필요한지 정의한 엔드포인트만 먼저 생성합니다. 미리 할
이번 챕터의 코드는 https://github.com/koeunyeon/ci4/tree/blog-publish에 있습니다. 뷰 꾸미기 일단 기능이 작동은 하지만 화면이 너무 볼품없죠. 뷰를 조금 꾸며보겠습니다. CSS 프레임워크 저를 포함한 많은 개발자분들은 디자인
레이아웃 분리하기 블로그 글 목록, 블로그 개별 글 페이지를 둘 다 눌러보시면 공통으로 사용되는 부분이 있습니다. 바로 좌측에 보이는 소개 페이지입니다. 브라우저 인스펙터로 보면 `` 영역임을 알 수 있습니다. 이미지 또한 `` 영역도 반복되죠. 이미지 눈에 보이지
이번 예제는 https://github.com/koeunyeon/ci4/commits/blog-validation 에서 찾을 수 있습니다. 유효성 검사 추가하기 우리가 만든 블로그는 유효성 검사를 하지 않습니다. 따라서 처음에 정한 요건인 제목은 4-100글자, 본문
이번 챕터의 코드는 https://github.com/koeunyeon/ci4/commits/blog-markdown 에서 찾을 수 있습니다. 마크다운 기능 붙이기 마크다운 라이브러리 설치하기 글에 마크다운 기능을 붙여보겠습니다. 우선 PHP 내장 함수로는 마크다운
소셜 로그인 기능 만들기 이번 예제는 https://github.com/koeunyeon/ci4/commits/blog-social-login에 코드가 있습니다. 드디어 로그인 기능을 만들 시간이 왔습니다. 이제껏 우리는 아무나 들어와서 글을 쓸 수 있는 시스템을 만
글 기능 수정하기 이번 챕터의 코드는 https://github.com/koeunyeon/ci4/commits/blog-connect-post-member 에 있습니다. 기능이 거의 다 만들어졌습니다. 이제 글 기능에 회원 기능을 녹여넣으면 MVP는 완성입니다. 수
배포하기 배포란? 배포란 우리 컴퓨터에 있는 소스코드를 누구나 볼 수 있는 인터넷 공간에 올려서 사용자들이 접속해볼 수 있게 하는 겁니다. 빠른 배포가 스타트업을 살게 하죠. 1차 MVP 버전 개발이 완료되었으므로 웹서버에 배포해 보겠습니다. 사실 PHP는 배포라고
웹 호스팅에서 확인하기 필요한 조건 당장 gcp나 aws등 클라우드 서비스를 이용해서 멋지게 배포하고 싶겠지만 백만년은 이르다! 잠시만 참아주세요. 지금은 그저 ftp를 이용해서 파일을 업로드하는 것으로 충분합니다. 간단한 웹 호스팅을 하기 위해 우리는 웹 호스팅 업
마크다운 블로그 리팩토링하기 리팩토링의 필요성 MVP를 런칭하고 나면 다른 스타트업 멤버들이 바빠지기 시작합니다. 인터넷 여기저기에 서비스 오픈을 알리고, 언론사에 보도자료를 뿌리고 때로는 광고를 집행하기도 하는 등 서비스 알리기에 전념하죠. 그동안 개발팀은 뭘 해
엔티티 분리하기 엔티티 분리의 이유 이제껏 우리는 비즈니스 로직을 "컨트롤러"에서 처리했습니다. 데이터를 가공하고 조회하는 일 등이죠. 하지만 원칙론적인 MVC 에서 데이터를 다루는 일은 모델이 합니다. 조금 더 단단한 구조를 만들기 위해 엔티티를 분리해서 비즈니스
단위테스트의 정의 이번 챕터의 코드는 https://github.com/koeunyeon/ci4/commits/refacto-unittest 에 있습니다. 코드이그나이터4는 사람이 직접 테스트하는 엔드 투 엔드 테스트(end-to-end test) 외에 테스트 코드를
글 생성 컨트롤러 수정하기 이번 챕터의 코드는 https://github.com/koeunyeon/ci4/commits/refacto-post-controller 에 있습니다. 엔티티 분리, 서비스 레이어 분리, 단위 테스트까지 마쳤으므로 우리는 잘 동작하는 서비스
글 조회 엔티티/ 서비스 레이어 분리하기 이번 챕터의 코드는 https://github.com/koeunyeon/ci4/commits/refacto-post-read-entity-service 에 있습니다. 글 조회 엔티티 / 서비스 레이어 분리하기에서는 엔티티, 서
글 수정 서비스 레이어 분리하기 이번 챕터의 코드는 https://github.com/koeunyeon/ci4/commits/refacto-post-edit-delete 에 있습니다. 글 수정은 글 생성 + 글 조회 기능이 합쳐져 있죠. 이미 엔티티의 역할은 정해져
글 목록 서비스 레이어 분리하기 이번 챕터의 코드는 https://github.com/koeunyeon/ci4/commits/refacto-post-list 에 있습니다. 모델 반환 타입 변경하기 이제 글 목록 서비스의 마지막 메소드이므로, 글 모델의 반환 타입을 변
테스트! 테스트! 테스트! 이번 챕터의 글은 https://github.com/koeunyeon/ci4/commits/refacto-test 에 있습니다. 테스트를 합시다. 글 기능을 전반적으로 수정했으니 테스트가 필요하겠죠. 우선 직접 눌러가면서 테스트하는 엔드 투
클라우드란 직접 서버를 IDC 등에 두는 것이 아니라 가상의 서버 리소스를 클라우드 회사(AWS, Azure..등)에서 임대하는 방식을 말합니다. 어플리케이션을 클라우드에 배포하게 되면, 여러 장단점이 있습니다. 장점 서버 관리에 대한 스트레스가 줄어듭니다. 서버를
라이트세일이란 AWS 라이트세일은 간단한 가상머신을 제공해주는 서비스입니다. 단순하게 요금 체계만 선택하면 월 정액으로 가상머신을 사용할 수 있습니다. 기존에 AWS에는 EC2라는 가상머신 서비스가 있는데요. EC2는 선택의 폭도 넓고, 과금체계도 복잡한 편이라서
파일을 서버로 옮기는 여러가지 방법 로컬에 있는 파일을 원격 리눅스 서버로 옮기는 방법은 여러가지가 있습니다. 파일질라 - https://filezilla-project.org/ 등을 통해 FTP로 옮기는 방법 scp 명령어를 통해 옮기는 방법 git을 이용해 옮기
writable 디렉토리 권한 바꾸기 writable 디렉토리는 코드이그나이터4에서 임시 파일을 저장하는 디렉토리입니다. 아파치는 데몬(윈도우에서 서비스처럼 백그라운드 실행)으로 실행된는데 반해, 코드이그나이터4가 설치된 디렉토리는 bitnami가 owner이기 때문에
데이터베이스 설정하기 데이터베이스 접속 확인하기 MySQL이 잘 실행되는지 확인해 봅시다. 비밀번호 입력창이 나오면 라이트세일 기본 어플리케이션 암호를 입력합니다. MySQL 콘솔에서 데이터베이스를 조회해 봅니다. 기본 테이블이 있는 것을 확인할 수 있습니다. 데
http://URL 로 이동해 보면 Class 'App\helpers\LoginHelper' not found 오류가 납니다. 소스코드를 확인해 보면, LoginHelper의 네임스페이스 helpers의 대소문자가 틀렸음을 알 수 있습니다. Helpers여야 하는데
이 글이 일반적인 강좌 글과 다르게 여러 가지 이야기를 하는 건, 개발자라는 직업은 기술이 전부가 아니라는 이야기를 하고 싶었습니다. 개발은 분명히 기술(스킬)이 필요한 직업입니다. 시간이 흐를 수록 스킬은 고도화되고, 날카로워지고, 다양한 상황에 적용할 수 있게 되죠
이 글은 2021년에 쓰여진 글입니다.그 동안 코드이그나이터4도 많이 변했고, 개발의 세계도 많이 변했습니다.한동안 시리즈를 비공개로 했다가 다시 공개로 전환한 이유는, 의외로 이 글을 찾으시는 분들의 이메일을 종종 받았기 때문입니다.실은 한 번 책으로 출간했었고 많은