여태까지 배웠던 것을 이용해서 위키 사이트를 업데이트해 보자. 핵심은 모든 기능을 db와 연동시키는 것이다.
글을 작성하는 기능이다. (create.php 코드를 찍었어야 했는데 스크린샷을 잘못 찍었다.)
글 작성 위치와 기능 자체는 이전 php문 수업과 동일하나, 작성한 글이 db에 하나의 row로서 들어간다는 점이 중요하다.
연결 변수 $conn을 통해 INSERT문으로 row를 집어넣는다. SQL Server라는 글을 작성하는 모습이다.
성공적으로 글이 등록되었다. 위의 ordered list는 db 테이블에 있는 항목들의 title을 모두 불러오므로 ol에 추가되었다면 db에 추가된 것이라고 보아도 무방하다.
글을 썼다면 수정할 수 있는 기능이 생겨도 좋을 것이다. 수정할 대상이 되는 글이 있어야 하므로, 특정 글을 지정하지 않아도 나오는 create 버튼과는 달리 update 버튼은 특정 글을 클릭해야 나오도록 하는 것이 적절할 것이다. id 변수를 담은 isset문을 조건으로 한 if문 안에 넣고 변수명을 $update_link로 한다. 이 링크는 전용 php 페이지로 연결될 것이며, php문을 통해 html 사이에 끼워넣어진다.
update.php 링크는 create.php와 유사하나 제목과 내용에는 기존 글의 제목과 내용이 value 값으로 담겨 있다. 이 내용은 DB에서 SELECT문으로 가져와지며, 입력되는 값 역시 한 번의 필터링을 거쳐 DB로 들어간다.
위 명령어는 topic이라고 하는, 글을 올리는 게시판에서 각각의 글의 정보를 담는 데이터베이스를 만든 것이다.
명령문 하나당 하나의 필드를 생성했다. 각각의 명령어를 해독해 보자.
CREATE TABLE topic( => topic이라는 table을 만든다 -> id INT(11) NOT NULL AUTO_INCREMENT,
=> 글의 식별번호(아이디). 정수, 11자리까지 노출. 비워둘 수 없음. 서로 중복되지 않게 등록될 때마다 증가하도록 함 -> title VARCHAR(100) NOT NULL, => 글의 제목. 100글자를 넘으면 잘림. 비워둘 수 없음
-> description TEXT NULL, => 글의 내용. 텍스트로 구성됨. 비워진 상태도 가능. -> created DATETIME NOT NULL, => 생성 시점. 그 시점의 날짜와 시각을 기록. 비워둘 수 없음 -> author VARCHAR(30) NULL, => 글쓴이. 30글자를 넘으면 잘림. 비워둘 수 없음 -> profile VARCHAR(100) NULL, => 글쓴이의 세부사항. 100글자를 넘으면 잘림. 비워둘 수 없음 -> PRIMARY KEY(id)); => 가장 중요한 칼럼(각 글을 구별하는 키)를 id로 설정
이번에는 작성한 글을 수정할 수 있게 기능을 추가해볼 것이다. 방식은 작성 기능 구현 때와 유사하다.
작성 때 글을 작성하는 페이지 create.php와 작성하는 기능을 구현해주는 create_process.php를 만들었던 것처럼
수정에도 update.php와 update_process.php를 각각 만들어 사용할 것이다.
update.php 화면이다. a태그로 된 update 링크를 누르는 것으로 진입할 수 있다.
필요한 것이 몇 가지 더 있어 추가했다.
type="hidden"인 input 태그를 하나 더 추가했다. 이것은 사용자의 눈에는 보이지 않으나 값을 담고 있고, 제출을 누르면 다른 input 태그들과 마찬가지로 파일로 전송된다. 항목의 제목을 수정할 경우 수정되기 이전의 원래 제목을 저장하고 있을 무엇인가가 필요하므로, hidden인 input을 사용해 이 값을 사용자 모르게 old_title이라는 이름으로 함께 전달하도록 했다.
input 태그에 value를 추가했다. 이 값은 디폴트 입력값을 의미한다. placeholder와는 다르게 사용자가 클릭해도 사라지지 않으며, 자유로운 수정이 가능하다. 수정하기 전의 항목이 가지고 있던 원래의 제목과 내용을 담는 데 사용했다.
소문자이던 제목을 대문자로 바꾸고, 내용에도 약간의 수정을 넣었다. 반영되는지 보자.
제출을 누르면 바로 수정한 내용이 반영된다. 우측은 update의 기능적인 부분을 담고 있는 php로,
여태까지 우리는 코드를 담아 정리하는 도구로 함수를 사용해 왔다. 그러나 이 함수도 많아지면 역시 너저분해 보일 수 있고, 다시 가독성을 저해하게 된다. 그러면 자연히 이를 담아 정리할 더 큰 개념이 필요해지게 되는데,
이때 등장하는 것이 '객체(object)'이다.
앞서 만들었던 nightDayHandler 함수에서 반복되었던 부분을 다시 별도의 함수인 setColor로 정리했다.
바꾸고 싶은 색상을 인자로 넣고, 모든 a태그의 색상을 바꾸고 싶을 때마다 setColor 함수만 부르면 되게끔 했다.
그런데 리팩토링 과정에서 코드를 정리해 가다 보면 위와 같이 링크의 색을 바꾸는 것뿐만 아니라
글씨의 색, 배경의 색 등 다양한 요소의 색을 바꾸고 싶어질 수도 있다. 이 함수들도 setColor라고 하면 되나?
당연하지만 안 된다. JS에서 이름 중복은 에러는 아니지만, 앞에 적혀 있는 함수를 뒤에 적힌 동명의 함수가 덮어쓰도록 되어 있고-그러면 당연히 앞의 함수는 무용지물이 된다.
그러면 프로그래머는 당연히 이와 같은 중복을 피해야 할 것인데, 모든 setColor 함수를 이름만으로 구분지을 건가?
코드가 짧고 요소가 적은 초기에야 이와 같은 방법이 통하겠지만, 요소가 늘어남에 따라 점점 이 방식에도 한계가 올 것이다. (A 엘리먼트의 글씨의 색을 바꾸는 함수와 B 엘리먼트의 글씨의 색을 바꾸는 함수... 이런 것들을 전부 이름에 적어서 구분한다면 함수 이름만으로 코드가 꽉 찰 것이다!)
그러나 그럴 필요는 없다. 함수를 분류하는 객체라는 도구가 이미 마련되어 있다. 우리는 객체를 배우면 그 객체를 생성한 뒤, 객체 이름을 적고 .을 적은 뒤 함수 이름을 적으면 된다. 객체 이름만 다르다면 그 뒤에 오는 함수 이름은 얼마든지 중복되어도 상관없다.
리팩토링: 코딩이 완료된 후 기존의 코드와 기능은 같게 두되 코드를 조금 더 효율적으로 만들어 유지보수하는 작업
소프트웨어가 커지고 복잡해지면 틈틈이 리팩토링을 해 주어야 좋은 프로그램을 만들 수 있다
리팩토링의 예로는 어떤 것들이 있는지 보자.
위에 만들었던 나이트/데이 버튼이 밑에서도 보이게끔 하고 싶으면 위의 코드를 그대로 아래에 복사 및 붙여넣기하면 된다. 하지만 이렇게 해서 만든 버튼은 올바르게 작동하지는 않는다. 토글 기능 자체는 작동되지만, 버튼에 표시되는 이름도 나이트/데이로 바뀌어야 하는데 그러지 않고 있기 때문이다.
원인은 같은 아이디를 가진 버튼이 두 개 있기 때문이다. (선택자를 배울 때 같은 아이디를 가진 개체가 두 개 이상 있으면 안 된다고 했던 이유도 이러한 맥락일 것이다.) 때문에 value를 바꾸면 바뀌는 것은 위에 있는 버튼의 value이다.
해결을 위해서는 아래쪽 버튼의 id를 다르게 해주면 된다.
아래쪽 버튼의 id를 night-day2로 바꾸었다. 버튼의 이름이 정상적으로 바뀌는 것을 확인할 수 있다.
개선할 점은 더 있다. 코드가 너무 길다. 자기 자신의 아이디를 가리키는 데 일일이 document.querySelector('#night-day2') 라는 표현을 사용하고 있으니 코드가 쓸데없이 길어질 수밖에 없다.
태그 안에서 객체가 자기 자신을 지칭할 때는 쓸 수 있는 1인칭 대명사가 따로 있다.
this이다.
코드를 우측처럼 바꾸었지만 여전히 잘 작동한다.
훨씬 보기가 낫다. 이렇게 하면 사실상 id도 필요가 없어진다. (외부에서 해당 태그를 지칭하는 일이 현재로선 없기 때문에)
자기 이름이 무엇이 됐든 사람들에게 자신을 소개할 때는 누구든 '나'나 '저'라고 하지 않던가.
개선한 코드를 위쪽 버튼이 있는 자리에도 똑같이 복붙해 주었다.
그런데 이 코드에는 아직도 중복이 남아 있다. document.querySelector('body') 이다.
이건 어떻게 제거하면 될까?
간단하다. 우리가 평소에 C 등의 언어를 가지고 코딩할 때는 특정 값을 변수로 지정하여, 그 값을 불러낼 때마다 변수의 이름을 사용했다.
여기에서도 마찬가지이다. var target = document.querySelector('body'); 와 같이 해당 값을 아예 변수로 지정해 버리고,