11. 활용 - 글쓰기

https://youtu.be/GtE4ZXm8eNo

 

 

 

여태까지 배웠던 것을 이용해서 위키 사이트를 업데이트해 보자. 핵심은 모든 기능을 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로 들어간다.

중복되는 SQL Server 항목을 Database 항목으로 수정한 모습이다.


12. 활용 - 글삭제

https://youtu.be/t6TtDnulbMU

 

 

글 삭제 기능도 구현해 보자. 삭제는 업로드/수정과는 달리 실행했을 때 이동해야 할 페이지가 없으므로

a 태그가 아닌 input의 버튼 타입으로 구현한다.

삭제도 대상이 있어야 하므로 수정과 마찬가지로 특정 항목에 들어가야만 버튼이 나타나도록 한다.

삭제할 글의 php id 값을 받아 db로 보낸 뒤 delete문을 통해 지운다.

삭제를 실행한 뒤의 모습이다.


13. 관계형 데이터베이스의 도입 ~ 14. 많아지는 테이블

https://youtu.be/0DKV9pyXB-g

 

 

'관계형 데이터베이스'의 의의란 테이블들 사이의 '관계'에 있다고 할 수 있다.

'join' 기능을 사용함으로써 테이블들 간의 관계, 접접을 통해 테이블들을 합칠 수 있고

중복제거를 위해 정보가 여러 테이블에 분산되어도 조인만 하면 다시 하나의 테이블처럼 볼 수 있는 것이다.

그리고 그 조인된 테이블을 php 페이지에서도 쿼리를 통해 확인할 수 있다.

 

기능 시연을 위해 author라는 테이블을 만들었다. 여기에는 작가 이름과 정보, 아이디가 들어갈 것이다.

 

이것은 기존에 있던 테이블인 topic의 구조이다. 기존 테이블에서 작가에 관한 정보 부분을 분리했으며,

작가 아이디 부분만 컬럼으로 남겨놓고 있다.

 

작가 아이디 값을 세팅해준 뒤 join한 모습이다.

topic 테이블의 author_id와 author 테이블의 id 값을 같은 값으로 취급하여, 이 부분을 접점으로 한 뒤

두 테이블을 서로 결합한 것이다.

이제 이 기능을 php에 적용해 보자.


15~16. 테이블 간의 연결 - 읽기~생성

https://youtu.be/Mdsemy535bE

 

 

다시 글 읽기와 생성으로 돌아온다. 이제 작가 아이디라는 정보가 생겼으므로

글마다 항목을 누르면 글 밑에 작가가 누구인지 표시되게끔 하고자 한다.

이런 식이다. db에서 조인된 테이블로부터 작가 이름을 받아온 뒤, 그것을 변수에 담아 php문으로 본문 아래 기재한다.

 

 

$author 변수는 글 작성 시에도 글 아래 기입하도록 되어 있다.

row를 작성할 때 작가가 누구인지 기입하면 author_id가 배당되고, 그 정보가 쿼리를 통해 db에 들어가는 것이다.

 

쿼리 전문은 이러하다. 당연히, 입력값으로 받는 모든 정보는 필터링을 거칠 필요가 있다.

 

성공하면 이와 같은 화면이 뜬다. 돌아가기 버튼을 눌러 메인 화면인 index로 돌아갈 수 있다.


17. 새로운 테이블 - 읽기

https://youtu.be/eLFszaGuI1o

 

 

 

이제 글 이외에도 작가들의 목록도 웹 페이지에서 확인하고 싶다면 어떻게 해야 할까?

우선 별도의 페이지를 만든다. topic 테이블이 표시되는 index 페이지에서는 author 링크를 누르면 author.php로 갈 수 있게 한다.

author.php에서는 topic을 누르면 index로 돌아올 수 있다.

 

작가 정보는 id, 이름, 부가정보가 함께 표시되어야 하기 때문에 표 형태로 나타내는 것이 좋을 것이다.

table 태그를 쓰면 표를 웹에 표시할 수 있다. 한 줄은 tr, 한 칸은 td 태그로 감싼다.

값이 더 없을 때까지 반환하게 하는 mysqli_fetch_array 문을 사용해 테이블 전체의 내용을 반환하게 한다.

최종적으로 완성된 표는 위와 같다.


18. 새로운 테이블 - 생성

https://youtu.be/LHVppMSMLfY

 

 

그러면 이제 작가 정보도 갱신할 수 있게 해 보자.

작가 정보 갱신도 여태까지 해왔던 것에서 크게 벗어나지 않는다.

입력값을 받고, 필터링하고, 이 값들을 db에 보내 INSERT 쿼리를 통해 삽입한다.

 

process_create의 author 버전을 만들어 삽입 작업을 담당하게 한다.


19. 새로운 테이블 - 수정

https://youtu.be/B9fidsr4Io8

 

 

수정 또한 같은 방식으로 실행하되, author 페이지는 항목마다의 페이지를 갖추고 있지 않기 때문에

테이블의 컬럼을 하나 더 써서 수정하는 버튼이 각각 위치하게끔 한다.

update 링크를 누르면 수정하고자 하는 작가의 아이디가 process_update_author.php로 전달된다.

쿼리를 통해 db에서 작가의 이름과 설명이 전달되고, 이 값을 value 삼은 form으로 정보를 수정한다.

(각 입력값은 필터링 및 이스케이프 되어야 한다.)

 

6번 항목에서 문장부호를 지운 내용을 업로드한 것이다.


20. 새로운 테이블 - 삭제

https://youtu.be/XVbwTDfqn-A

 

 

 

삭제 기능은 역시 위와 같이 별도의 링크가 필요하지 않으므로 버튼으로 구현한다.

하나의 DELETE문 쿼리로 처리될 수 있으므로, 버튼을 누르면 해당 쿼리를 담은 process_delete_author.php가 실행되도록 하고 리다이렉트 기능을 통해(header("Location: ()")) 새로고침된 원래의 페이지로 돌아온다.

삭제는 신중해야 하므로, 한 번의 alert를 넣어 쿠션을 깐다.

확인을 눌러야만 삭제가 진행된다.

 

6번 항목을 삭제한 후의 모습이다.

1. 수업소개 ~ 2. PHP와 MySQL의 연동 원리

 

https://youtu.be/NChP-7KMQ_U

웹사이트에서 다뤄야 할 정보의 양, 종류, 사용자가 많아짐에 따라

이전에 고민할 필요 없었던 문제가 대두되기 시작함

-> PHP와 데이터베이스를 연동하는 방법 등장

-> db의 성능, 편의성, 보안성을 그대로 물려받은 현대적 어플리케이션 개발

 

대략적인 구조는 이렇다. 웹 브라우저에서 .php 양식의 파일을 웹 서버에 요청하면

웹 서버는 이를 혼자 처리할 수 없으므로 php에 위탁한다.

php는 이를 받고 MySQL의 저장 장소에 있을 정보를 MySQL에게 요청하고,

MySQL은 요청대로 php에게 정보를 내어준다. 이 정보를 받아 html 파일로 웹페이지를 구성하면

웹서버가 이를 받아 브라우저에게 서비스하게 된다.

 


3. 수업준비 ~ 4. MySQL Client로서의 PHP*

(실제 강의 제목과 차이가 있는데, 해당 영상 댓글에서 이 표현이 더 정확하지 않느냐는 질문이 있었고

영상 업로더가 이에 동의했다.)

https://youtu.be/wKD_ZjyNn3U

 

 

(수업준비는 3-1과 3-2편 영상의 더보기란에 있는 링크에서 코드를 복사하도록 한다.)

 

" db와 연동되는 php는 db 서버에 있어 클라이언트이다 "

: 우리가 앞선 mysql 수업에서 사용했던 mysql 모니터는 mysql 서버에 쿼리를 전달하고 정보를 받아오는 클라이언트였다.

같은 원리로 php는 db와 연동될 때 db에 쿼리를 전달하고, 정보를 받아올 수 있는 클라이언트로서 기능한다.

즉, 모니터에서 db 서버와 상호작용하기 위해 했던 모든 것들을 이제 php로 해야 할 필요가 있다.

 


5. MySQL API 찾기

https://youtu.be/SR00gij8lr4

 

 

php로 mysql에 연결할 수 있는 api를 찾아본다.

보통 mysqli / pdo / mysql 세 가지 종류가 있는데

mysql은 오래되어 사용을 권장하지 않고,

pdo는 다른 관계형 데이터베이스를 사용하게 될 때도 코드를 바꾸지 않고 db를 교체할 수 있으나

객체지향 구조에 익숙하지 않다면 mysqli를 사용하는 것도 좋다.

 

mysqli는 함수 방식으로 제어하며, 이 강의에서는 mysqli를 사용한다.

 


6.1. mysqli_connect

https://youtu.be/3tVZvEHdUMk

 

 

 

php로 만들어진 페이지가 mysql에 접속하게 하는 코드는 다음과 같다.

localhost는 우리가 아는 127.0.0.1 주소이다. 현재 사용 중인 컴퓨터를 가리키는 도메인이다.

root와 111111은 mysql 모니터에서 처음 접속할 때와 같은 입력값이다. 루트 권한과 비밀번호이다.

(교육용이 아닌 목적으로 실제 사용할 땐 저런 비번을 써서는 절대로 안 된다!

사실 이렇게 코드에 비밀번호가 드러나는 방식을 취하는 것 자체가 보안상으로 위험하다.)

opentutorials는 사용할 스키마이다.

 

위 코드로 접속하는 것을 제너럴 로그로 찍어보면 이런 로그가 뜬다.

루트 권한, 현재 위치 로컬호스트로 해당 스키마를 사용하는 접속 시도에 성공했다.


6.2. mysqli_query

https://youtu.be/OrJ3LIzDHQw

 

이번에는 PHP에서 DB 테이블에 내용을 넣는 작업을 해 보자.

내용을 넣는 것은 쿼리문으로 처리해야 하므로

mysqli_query(링크, 쿼리 내용);

과 같은 형식의 코드를 사용할 것이다. 이런 식으로 작성한다.

<?php
$conn = mysqli_connect("localhost", "root", "111111", "opentutorials");
mysqli_query($conn, "
  INSERT INTO topic
    (title, description, created)
    VALUE(
      'MySQL',
      'MySQL is ..',
      NOW()
      )
");
 ?>

일단 db에 접속하는 코드를 맨 윗줄에 쓴 뒤, 그것을 변수에 담는다.

그리고 mysqli_query의 첫 번째 인자로 접속하는 코드를 담은 변수, 다음 인자로 쿼리 내용을 적는다.

 

위 php 코드를 브라우저로 실행시킨 뒤 db 모니터에서 확인해 보면 정상적으로 테이블에 내용이 들어갔음을 알 수 있다.


6.3. mysqli_error

https://youtu.be/2Jh4mmeJLvI

 

 

개발에 있어 에러는 필연적인 것이지만, php는 기본적으로 에러를 알려주는 기능을 지원하지 않는다.

이때 쓰면 좋을 것이 mysqli_error이다.

 

<?php
$conn = mysqli_connect("localhost", "root", "111111", "opentutorials");
$sql = "
  INNSERT INTO topic
    (title, description, created)
    VALUE(
      'MySQL',
      'MySQL is ..',
      NOW()
      )
";
mysqli_query($conn, $sql);
echo mysqli_error($conn);
 ?>

쿼리문을 변수에 담아서 수정하기 좋게 하고, 내용에 일부러 오타를 냈다.(INNSERT)

이때 mysqli_error(링크) 형식 코드를 쓰면 그 연결에서 발생한 에러를 php가 페이지에 표시해 준다.

 

한 단계 더 발전시키면 이런 것도 가능하다.

<?php
$conn = mysqli_connect("localhost", "root", "111111", "opentutorials");
$sql = "
  INSERT INTO topic
    (title, description, created)
    VALUE(
      'MySQL',
      'MySQL is ..',
      NOW()
      )
";
$result = mysqli_query($conn, $sql);
if ($result === false){
  echo mysqli_error($conn);
};
 ?>

이것은 쿼리를 변수화해서 if문의 조건식에 달아놓은 것이다. 쿼리에서 에러가 발생하면 해당 값이 false가 된다.

이 경우 에러를 출력하게 되므로 해당 쿼리로 대상을 좁혀서 에러가 발생했는지 아닌지를 알 수 있게 된다.

 

그러나 이는 개발할 때만 용납되는 방식이며, 실제 시스템에서는 이런 식으로 echo를 써서 에러를 외부에 출력해서는 안 된다. 공격자에게 내부 정보를 넘겨주는 것이나 다름없기 때문이다. (지난주 비박스 웹해킹 게시글 참고)


7. 활용 - 글생성

https://youtu.be/uIemIQzSO0U

 

여태까지 배웠던 기능들을 활용해서 위키 사이트를 만들어 보자.

 

 

우선 사이트의 기조가 되는 화면이다. 처음 접속했을 때는 아래와 같은 화면이 뜰 것이다.

a 태그를 이용해 create를 누르면 create.php 파일이 실행되도록 만들어 준다.

 

create를 눌렀을 때 나타나는 create.php 화면이다.

form 태그와 textarea를 이용해 제목과 본문을 입력할 수 있도록 했다.

제출을 누르면 action인 process_create.php로 넘어간다.

 

post 방식이기 때문에 우선 form에서 작성한 정보가 잘 넘어왔는지 var_dump로 확인해 준다.

 

정보 전송에 문제가 없는 것을 확인했다면 쿼리문을 변수에 넣는다.

INSERT문으로 topic 테이블에 제목, 본문, 생성 날짜가 들어가도록 할 것이다.

생성 날짜는 NOW() 함수를 이용한다.

 

SQL 접속, 쿼리 전달, 실패했을 경우에 대비한 에러 메시지까지 갖춘 코드이다.

에러 메시지는 error_log 함수를 이용해 외부가 아닌 내부 에러로그 파일에 저장되도록 했다.

정상적으로 작동했으며, 모니터에서 확인한 바 INSERT문이 정상 처리된 것을 볼 수 있다.


8. SELECT 사용법

https://youtu.be/AQGpcSc52Vw

 

 

이번에는 SELECT 쿼리로 추출한 내용을 PHP에서 전달받는 방법에 대해 살펴보자.

 

비슷한 방식이다. SELECT문 쿼리를 변수에 담고 mysqli_query문으로 실행한다.

이때 결과값을 잠깐 var_dump로 살펴보자. 이런 배열값이 나올 것이다.

-> 기호를 활용해서 원하는 부분만 추출할 수도 있다. 행의 개수인 num_rows를 추출한 모습이다.

 

 

mysqli_fetch_array를 print_r문으로 출력해서 보면 좀더 깔끔한 결과를 얻을 수 있다.

페이지 소스 보기로 줄바꿈된 것을 본 결과다. 자세히 보면 같은 값이 인덱스로 한 번, 컬럼명으로 한 번 출력되고 있다.

이것이 무엇을 의미하는가?

 

인덱스(숫자)로도 값을 꺼낼 수 있고, 그 값의 필드명을 직접 입력해서도 값을 꺼낼 수 있다는 뜻이다.

후자의 방식이 가능한, 즉 값 자체를 키로 삼을 수 있는 배열을 연관 배열이라고 한다.

 

mysqli_fetch_array는 하나의 배열이기 때문에, 이를 변수에 담아서 뒤에 인덱스명을 붙이면

간단히 아래와 같이 제목과 내용을 출력할 수 있다.

 

반복문으로 실행한 모습이다. mysqli_fetch_array는 호출될 때마다 계속해서 다음 값을 꺼내오는데,

더 꺼내올 값이 없으면 널 값을 가져온다. 이 점을 이용해 while문을 짜면 깔끔하게 테이블의 모든 값을 확인할 수 있다.


9. 글읽기

https://youtu.be/6u55XwoUYtM

 

 

 

1. index.php에서 db 연결을 취한다.

2. 쿼리문 전달과 배열 출력으로 db 안의 글 제목들을 리스트화한다.

3. 반복문으로 이를 리스트에 담은 뒤 변수화해 하단에서 출력한다.

변수 하나의 출력은 <?=(변수명)?>으로 간단하게 가능하다.

4. 아이디를 매개로 제목과 글내용을 뽑아온 뒤 변수화한다.

5. 하단에서 변수 출력한다.

 

create.php에도 같은 내용을 복사 후 붙여넣기한다.


10. 보안 - filtering, sql injection의 원리, escaping

https://youtu.be/GdRZhWjTDnE

 

filtering = 입력 단계에서 문제가 될 소지가 있는 정보를 거르는 것

escaping = 출력 단계에서 문제가 될 소지가 있는 정보를 거르는 것

 

보안의 기본은 사용자가 입력하는 정보를 불신하는 것이다. (그 이유는 웹해킹 게시물을 살펴보면 알 수 있다.)

입력단에서는 사용자가 입력하는 정보를 걸러야 하고, 출력단에서는 사용자에게 약점을 노출하지 않게 주의해야 한다.

 

1. 입력에서의 보안인 필터링 기법 중 가장 보편적인 것은 이 코드이다.

mysqli_real_escaping_string()

이 함수는 인자로 받아들여진 스트링이 코드로 사용되지 못하도록 막는다.

db와 연동되는 웹에서 사용자가 sql 인젝션 공격을 하려고 한다면 이를 막을 장치가 필요하기 때문에

위와 같은 스트링 검열 함수를 통해 한 번 거르는 것이다.

보통 입력값을 위 함수로 한 번 감싼 뒤 변수에 담아

다른 코드 부분에서 입력값을 사용하려 할 때는 그 한번 거른 변수를 날것의 입력값 대신 사용한다.

 

 

2. sql 인젝션 공격에서는 --(주석 기호), ;(쿼리 분리 기호) 등을 이용해

기존의 쿼리에서 필요없는 문자를 지우고 뒤에 자신이 원하는 쿼리를 덧붙여 여러 개의 쿼리가 실행되게끔 하는 식으로 공격방식을 취한다. (3주차 웹해킹 게시물 참고)

이때 위 1번의 방식을 사용하면 이러한 인젝션 공격을 막을 수 있고

mysqli_multi_query 대신 mysqli_query 함수를 사용하면 다중 쿼리를 방지할 수 있다.

 

3. 여러 번 웹해킹 게시글에서 언급되었듯

유명한 이스케이핑 함수로는 htmlspecialchars()가 있다.

이 함수를 사용하면 인젝션에 사용될 수 있는 html 기호(<, /, > 등)가 모두 단순한 스트링으로 변환되어

인젝션 공격이 쉽게 무효화된다.


 

1. 수업소개 ~ 3. MySQL 설치

https://youtu.be/h_XDmyz--0w

 

데이터베이스(DB)의 목적 = 정보의 정리.

: 데이터베이스 또한 파일에 정보를 정리하는 것이지만, 테이블(표)의 형태로 정보를 정리하여 파일에 수납함으로써

방대한 정보의 관리를 더욱 용이하게 할 수 있다.

 

 

스프레드시트(엑셀 등)와 DB의 차이

: 스프레드시트는 기본적으로 GUI형의 응용 프로그램이며, 테이블의 형태를 띠는 점에 있어서는 DB와 유사하나

기본적으로 클릭 조작을 통해 정보를 다루는 명령을 사용한다.

반면 DB는 이러한 조작을 명령어를 통해 처리할 수 있다.

프로그래밍 언어가 어떻게 쓰이는지 생각한다면 이러한 언어형 조작법의 이점을 쉽게 깨달을 수 있을 것이다.

 

 

MySQL은 따로 MySQL 사이트에서 설치할 필요 없이, 비트나미를 깔면 같이 동봉되어서 온다.

(MySQL 사이트에서 깔고 싶어도 비주얼 스튜디오의 낮은 버전(2015, 17, 19년 버전)이 없으면 깔리지 않는다. 내가 가진 버전은 2022년 버전이라 설치가 되지 않았다.)

 

최근 버전의 비트나미에는 mysql이 아닌 mariadb가 동봉되지만 기능은 같다.

컴퓨터의 cmd에서 아래 스크린샷과 같은 경로로 디렉터리를 열고,

 

 

 

아래와 같은 명령어를 입력하여 초기 설치 시에 입력했던 패스워드를 넣으면 데이터베이스 프로그램이 실행된다.

이렇게 프로그램을 실행시켜서 실습을 진행하면 된다.


4. MySQL의 구조

https://youtu.be/IWEa4DN_1Yk

표(table) : 기본이 되는 단위. 하나의 표 그 자체를 의미한다.

데이터베이스(database) 또는 스키마(schema) : 표의 집합. 관계가 있거나 구조가 같은 표들을 모아놓은 것.

데이터베이스 서버(database server) : 데이터베이스의 집합.


5. MySQL 서버접속

https://youtu.be/x06B6UkitcM

 

 

MySQL에 접속할 때 치게 되는 커맨드 > mysql -uroot -p

-uroot : root 권한으로 db에 접속하는 것을 의미한다. 루트 권한은 가장 강력한 권한이므로 공식적으로 중요한 db 서비스를 하게 되었을 때는 평상시 접속하는 계정을 달리 만들고, 중요한 수정 작업을 할 때만 root로 접속하도록 한다.

-p : 비밀번호를 입력한다. -p111111 처럼 뒤에 바로 비밀번호를 붙여 입력해도 되지만, 이 경우 비밀번호가 가려지지 않고 드러나 위험하므로 -p를 친 후에 문자가 *로 마스킹이 되는 창에서 비번을 치도록 한다.

 


6. 스키마의 사용

https://youtu.be/9stHa3mRbNI

 

 

데이터베이스(스키마)를 만드는 법을 알아보자. 프롬프트에서 다음과 같은 명령어를 입력한다.

> CREATE DATABASE (생성할 데이터베이스 이름);

 

세미콜론은 필수이다. 모든 쿼리는 ;로 끝나야 하고 그렇지 않으면 아래 스크린샷에서처럼 다음 행에 -> 마크가 뜨며

연속되는 명령어가 더 있는 것으로 간주, 프롬프트가 대기하게 된다.

성공적으로 데이터베이스가 만들어졌다면 Query OK라는 메시지가 뜰 것이다.

만든 데이터베이스를 확인하기 위해서는 > SHOW DATABASES; 명령어를 사용한다. (끝에 S가 붙어야 한다.)

opentutorials라는 데이터베이스가 성공적으로 만들어진 것이 보인다.

이 데이터베이스를 사용하고(표를 조작하고) 싶다면 다음과 같이 입력한다.

 

> USE (데이터베이스 이름)

하단과 같은 메시지가 떴다면 성공이다.


7. SQL과 테이블의 구조

https://youtu.be/f_m-RcdISxk

SQL = Structured Query Language

: 데이터를 정리하고 구조화하는 것에 특화된 언어.

데이터를 처리하기 위해서는 SQL을 통해 데이터베이스 서버에 요청을 전달해야 한다.

서버는 이 SQL로 된 요청을 받아들이고 그에 맞게 테이블을 조작해 사용자에게 내놓는다.

 

테이블의 구조는 위와 같다. 격자로 된 하나의 표를 테이블이라고 하고,

가로줄 하나를 행(row, record)이라고 한다. 보통 하나의 개체와 그 개체가 가진 feature를 저장하고 있다.

세로줄은 열(column)이라고 한다. 하나의 feature에 대한 그 테이블에 저장된 모든 개체의 정보를 담고 있다.4


8. 테이블의 생성(1~2)

https://youtu.be/fPULu-Q-OlQ

 

위 명령어는 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로 설정

 

 


9. CRUD

https://youtu.be/0pU6_5BQ2Dk

데이터베이스에 있어서 가장 중요한 네 가지는 CRUD로 요약된다.

 

Create : 자료의 생성.

Read : 자료의 열람.

Update : 자료의 수정.

Delete : 자료의 삭제.

 

이 중에서도 생성과 열람은 특히나 자료의 본질이 되며 빠질 수 없다.

수정과 삭제는 비교적 부차적인 요소이며 어떠한 분야에서는 금지되거나 죄악시되기도 한다.

(수정/삭제되어서는 안 되는 사실 기록이나 회계 장부 등. 조작이 금지되는 분야가 분명히 있다.)


10. INSERT

https://youtu.be/75LHpeOQiOs

 

 

그러면 가장 중요한 create를 하는 방법을 알아보자. 요컨대 테이블에 자료를 '넣는' 방법에 대한 이야기이다.

 

 

SHOW TABLES를 입력하면 그 데이터베이스 안에 있는 테이블들의 리스트를 뽑아 준다.

여기서 DESC topic을 입력하면 (DESC는 describe의 약어이다) topic이라는 테이블에 어떤 필드(칼럼명)이 있는지,

거기에 들어가야 할 자료명은 어떤지, 입력하지 않고 비워놓을 수 있는지, 프라이머리 키는 무엇인지 등의

테이블을 만들 때 입력했던 정보들을 테이블 형태로 보여준다.

이것을 참고하여 insert문을 쓰면 된다.

 

row를 만드는, 즉 정보를 집어넣는 쿼리는 INSERT로 시작한다.

> INSERT INTO 테이블명(필드명1, 필드명2, 필드명3...) VALUES(필드값1, 필드값2, 필드값3...);

이런 식으로 적는다. 잘못 적었다면 프롬프트에서 위 키를 눌러서 썼던 명령어를 불러와서 수정하여 다시 적으면 된다. 

만든 테이블을 보려면

> SELECT * FROM 테이블명;

을 적으면 된다. 테이블에서 모든(*) 정보를 열람하겠다는 뜻이다.

이 정도만 알면 나머지는 간단하다. 위 키를 눌러서 INSERT문을 불러오고, 몇 부분을 수정해서(주로 VALUES 부분이 될 것이다) 엔터를 치고 하는 작업을 반복하면 쉽게 여러 개의 row를 생성할 수 있다.


11. SELECT

https://youtu.be/FCnJH6fLc64

 

 

SELECT문은 테이블에서 원하는 부분을 골라(SELECT) 보여주도록 하는 쿼리문이다.

 

> SELECT 필드명1, 필드명2, 필드명3 FROM 테이블명;

: 선택한 테이블에서 선택한 필드(열) 부분만 잘라 보여준다.

 

셀렉트문은 FROM을 생략하는 것도 가능하다. 리터럴 값만으로 컬럼을 출력할 수도 있고,

식을 입력하면 컬럼을 통해 그 값을 출력해 주기도 한다.

WHERE 옵션을 사용하면 출력 결과를 더 한정해 준다. 특정 필드 값으로 어떠한 값을 지니는 행만 출력하고 싶다면

WHERE 필드명=목적 값; 옵션을 덧붙이면 된다.

WHERE 옵션은 반드시 FROM 옵션 뒤에 와야 한다. (부가적인 요소일수록 뒤에 온다고 외워두자.)

 

옵션은 원하는 만큼 (그리고 출력이 가능한 만큼) 계속 덧붙일 수 있다. 위에서 뽑았던 결과 테이블을 id 기준으로 하여 내림차순으로(descending) 정렬한 것을 보고 싶다면 이 옵션을 붙이면 된다.

ORDER BY id DESC;

 

위의 테이블에서 출력하고 싶은 행 갯수도 제한할 수 있다. 최대 n개까지의 행만 보고 싶다면 이 옵션을 적자.

LIMIT n;


12. UPDATE

https://youtu.be/pNINXzXaWWM

 

이번에는 테이블에 이미 들어간 행의 내용을 수정하는 방법을 배워보자.

수정하는 쿼리는 UPDATE로 시작한다. 이렇게 적어주면 된다.

> UPDATE 테이블명 SET 수정할 필드1='수정할 값1', 수정할 필드2='수정할 값2' WHERE 조건식;

이렇게 하면 조건식에 맞는 행의 필드값이 입력한 값대로 수정된다.

조건식의 내용은 아무거나 좋지만 수정하고 싶지 않은 행의 내용까지 수정되는 사태를 막으려면

그 행만을 식별할 수 있는 조건으로 하는 것이 좋을 것이고, 보통은 식별자로 프라이머리 키 값을 입력한다.


13. DELETE

https://youtu.be/GDY2_t-9l-s

 

수정까지 배웠다면 이제는 삭제를 배울 차례이다. 행을 삭제하는 방법을 알아보자.

삭제 쿼리는 DELETE로 시작하고, 대상이 될 테이블이 필요하므로 반드시 FROM 옵션이 들어가야 한다.

아무 옵션도 입력하지 않고 FROM 테이블명까지만 쓰면 해당 테이블 전체가 삭제되어 버린다.

그 테이블의 그 행만 삭제하고 싶다면 이렇게 갖춰서 적어주자. 삭제는 항상 신중해야 한다.

> DELETE FROM 테이블명 WHERE 조건식;

수정에서와 마찬가지로 조건식은 그 행에만 해당하는 식을 넣어줄 필요가 있다.

해당하는 행이 없어도 에러가 뜨지는 않는다. 아무 행도 삭제되지 않을 뿐이다.

삭제는 문제가 발생하기 정말 쉬운 부분이므로 항상 주의하여 사용하도록 한다.

 


14. 수업의 정상 ~ 15. 관계형 데이터베이스의 필요성

https://youtu.be/-w1vJgslUG0

 

 

관계형 데이터베이스의 장점은 1) 유지보수의 용이성과 2) 데이터의 가독성을 모두 챙길 수 있다는 것에 있다.

예시를 보자. 스프레드시트로 나타낸 표이다. 위의 표에서 중복되는 데이터를(작가, 작가 프로필)

별도의 테이블로 빼고 작가에 아이디를 부여한다. 그리고 우하단의 테이블에는 작가의 아이디만을 기재한다.

작가에 대한 세부정보가 필요할 때는 좌하단의 테이블을 참고한다.

이렇게 테이블을 분리함으로써 중복을 최대한 줄이고, 용량을 줄이며 유지보수나 변경을 편하게 할 수 있다.

하지만 매번 이렇게 따로 보면 불편한 것이 당연하다. 어떨 때는 상단의 표처럼 합쳐진 형태의 테이블을 보며

데이터를 한눈에 확인하고 싶을 것이다.

이 기능을 관계형 데이터베이스는 둘 다 수행할 수 있다.

 

이미 테이블을 분리해 둔 상태의 DB이다. author이라는 표와 topic이라는 표로 테이블이 나뉘었다.

여기서 JOIN 기능을 사용하고 적절한 조건을 입력해 주면 DB가 알아서 표를 합쳐 보여준다.

실제로 표가 합쳐진 것은 아니나, SELECT문으로 열람할 때만큼은 마치 하나의 표처럼 볼 수 있다.

이런 면에서 관계형 데이터베이스는 효율적인 것이다.


16. 테이블 분리하기 ~ 17. JOIN

https://youtu.be/q0UHWaDRwlk

 

강의 자료 사이트에서 제공하는 코드대로 각각의 분리된 테이블을 준비해 두었다.

 

테이블을 조인(결합) 하는 쿼리문은 본질적으로 SELECT문을 사용한다. 

> SELECT * FROM 테이블명1 LEFT JOIN 테이블명2 ON 조인 조건;

위 조인은 topic.author_id=author.id,

그러니까 topic 테이블의 author_id 필드가 author 테이블의 id 필드와 같다는 조건을 이용하여 시행한 것이다.

 

 

위 표에서 중복되는 author_id와 id 항목을 제외하고 보고 싶으면 해당 항목을 제외한 필드명을 * 자리에 모두 넣고 다시 한 번 셀렉트문을 돌리면 된다.

이때 id라는 필드가 중복되어 필드 리스트가 모호하다는 메시지가 뜰 수 있으므로

이 경우에는 topic.id 등과 같이 표기하여 어느 테이블의 아이디인지 명시해 주도록 한다.

 

AS topic_id와 같이 입력하면 표시되는 필드명을 바꿀 수도 있다.


18. 인터넷과 데이터베이스

https://youtu.be/hjgaxlTQMXk

데이터베이스도 기본적으로 웹과 동일하게 서버와 클라이언트가 존재한다.

데이터를 저장해 놓고 있는 서버 컴퓨터가 웹을 통해 클라이언트에게 데이터를 전달하면

클라이언트 프로그램은 그것을 받아 사용자에게 보여주는 것이다.

 

mysql의 경우 클라이언트에 크게 두 가지가 있다.

하나는 우리가 실습에 사용했던 것과 같은 프롬프트 형식의 mysql 모니터이고,

다른 하나는 mysql 워크벤치라고 해서 GUI 형식의 클라이언트 프로그램이 따로 있다.

이러한 클라이언트들을 사용해 보면서 천천히 데이터베이스가 웹과 결합하는 형태에 대해 배워볼 것이다.


19. MySQL Client

https://youtu.be/yWy1PlkMMIw

 

 

앞서 말했던 것처럼 mysql 모니터와 mysql 워크벤치에는 각각의 장단점이 있다.

 

모니터: 프롬프트 형식이기 때문에 어디에서나 적용될 수 있고 쉽게 사용할 수 있다. GUI를 지원하지 않는 환경에서도 사용이 가능하다 / 모든 것을 명령어로 제어해야 하기 때문에 직관성이 떨어진다. 명령어를 외워야 한다

워크벤치: 직관적이다. 명령어를 외울 필요가 없으며 보이는 대로 손쉽게 제어할 수 있다 / 지원하지 않는 환경도 있을 수 있다. 명령어로는 한 줄로 처리할 수 있는 작업을 여러 번의 클릭으로 처리해야 하는 경우도 생기기 때문에 더 번거로워지는 경우도 생길 수 있다

 

상황에 맞게 사용하여 장점만을 취하는 것이 중요하다. 클라이언트 프로그램은 검색을 통해 쉽게 찾고 얻을 수 있다.


20. MySQL Workbench

https://youtu.be/JWB6sUd1R-Q

 

 

 

마리아디비도 기본적으로 mysql을 기반으로 하기 때문에 같은 워크벤치를 쓸 수 있다.

모니터에서 작성했던 스키마와 테이블들이 그대로 표시되고 있는 것이 보인다.

셀렉트문 쿼리를 친 다음 번개모양을 누르면 결과값이 하단에 표시된다.

 

새 스키마를 만들 수도 있다. 워크벤치라는 이름의 스키마를 만들었다.

 

GUI에서 작업을 하면 해당되는 쿼리문이 확인차 나타나는데, 읽어보고 Apply를 누르면 적용된다.

 

테이블을 새로 만들 수도 있다. Column Name에서 필드명을 작성하고, Datatype을 기입한 뒤

옵션에 맞게 우측에 체크를 해 주면 된다.

기본적인 사용법은 모니터에서 하던 것과 같거나 더 쉽다.


21. 수업을 마치며

https://youtu.be/ySH4-hEdiTs

수업을 마치며, 데이터베이스를 사용할 때 알아두면 좋을 몇 가지 포인트들을 짚고 넘어간다.

 

인덱스 : 데이터베이스의 양이 방대해지면 정리에 문제가 생길 수 있다. 이런 경우에는 인덱스라는 키워드를 서치해서 적용하면 좋다. 

모델링 : 데이터베이스를 사용할수록 정규화라는 키워드가 눈에 들어올 것이다. 더 효율적인 테이블 구조에 대해서 고민하고자 한다면 이쪽으로도 정보를 찾아보는 것이 좋다.

백업 : 굳이 데이터베이스가 아니더라도 자료를 관리하는 입장에서는 무시할 수 없는 키워드이다. 하드 장치는 언제 고장날지 알 수 없고 어떤 사고가 생길지도 알 수 없으므로 미리미리 백업에 대해서 배워두는 것이 좋을 것이다.

클라우드 : 방대한 데이터를 기업체의 서버에 위탁하는 것이다. 내 컴퓨터에 그만큼의 용량이 없더라도 저장공간을 빌리거나 사면 데이터가 유실될 걱정 없이 데이터베이스를 사용할 수 있다.

18. 함수 만들기 예고 ~ 19.3. 함수의 형식(3)

 

php에서도 마찬가지로 함수가 존재한다.

  • 타 언어에서와 동일하게 함수는 입출력 없이 단순히 기능만을 수행할 수도, 매개변수 값을 가질 수도, 리턴값을 내보낼 수도 있다.
  • 리턴의 사용 방법은 타 언어와 같다.
  • 매개변수 또한 타 언어와 동일하게 소괄호 내에 나열하되, 변수의 자료형은 필요하지 않으며 변수 앞에는 $를 붙인다.
  • 아래는 file_put_contents(결과파일명, 출력할 내용) 함수를 사용하여 sum2 함수의 리턴값을 파일에 담은 것이다.


20. 함수의 활용

https://youtu.be/P6tQrxmLkhY

 

 

실제 웹에서 함수는 기능을 함축하여 직관적인 이름으로 나타내고, 코드를 간결화하여 가독성을 높이는 데 사용한다.

 

예제 웹페이지의 기존 코드를 부분별로 함수화하여 php로 모아 코드 상단으로 올린 것이다.

 

html 본체 코드에는 이렇게 되도록 간결하게 함수 이름만 남는 것이 가독성 향상에 좋다.

 

 


21. 웹앱 완성하기 예고 ~ 22. form과 POST

 

예제 웹페이지에 추가하고 싶은 기능이 생겼다. 위키백과 페이지처럼, 방문자가 직접 항목을 작성하고 작성된 항목이 페이지 중 하나로 반영될 수 있도록 하려고 한다.

이러한 기능을 구현하는 데에는 form 태그가 적절하다.

 

간단하게 따로 예제 파일을 만들어 form 태그의 기능을 알아보고자 한다.

form 태그를 만들어 위와 같은 입력창이 나타나도록 했다. 위는 제목, 가운데 textarea는 내용이 된다. 제출 버튼을 누르면 내용이 전송될 것이다. 제출되었을 때의 동작은 form.php라는 파일이 담당한다.

placeholder 요소는 미리보기 텍스트를 제공한다. 사용자가 해당 칸에 무엇을 입력해야 하는지 알려주며, 입력을 시작하기 위해 입력 칸을 누르면 사라진다.

 

제출 버튼을 눌렀을 때의 화면이다. form.php 페이지로 이동했다.

이 페이지에는 표시되는 내용이 없지만, 대신 사용자가 제출한 폼을 별도의 파일로 만들도록 되어 있다.

 

제출한 내용으로 생성된 파일이다.

 

그런데 이 방식에는 문제가 있다. 웹해킹 정리 때 인젝션(GET)을 풀어보았다면 알겠지만,

정보를 보내는 방식으로 GET을 선택한 탓에 스크린샷의 상단 링크에 사용자가 보낸 값이 그대로 파라미터가 되어 들어가 있다.

이 방식은 보안상으로도 문제가 있지만 편의상으로도 좋지 않다. 링크를 공유할 때 이 문제점은 주로 발생한다.

항목을 생성할 마음이 없는 사용자도 링크를 공유받아 그 링크에 들어간 것만으로도 '항목을 생성하는' 동작을 실행시키게 되고

이것은 원치 않는 결과를 야기한다.

 

때문에 우리는 GET 방식을 POST 방식으로 바꿔줄 필요가 있다.

post 방식에서는 웹페이지가 주고받는 정보와 링크가 서로 관계가 없어진다.

주고받는 정보를 외부에 숨기는 것과 원치 않는 정보 전달을 막는 것을 동시에 충족할 수 있다.

method 요소를 통해 get과 post를 전환할 수 있는데, 디폴트값은 get이기 때문에 post를 원한다면 따로 수정해 주어야 한다.


23. 글생성

https://youtu.be/ExLCGW51mk0

 

 

 

그러면 이 기능을 구현에 활용해 보자.

 

기본 화면이다. 여기에서 a태그로 된 create를 누르면 create.php로 연결된다.

 

create.php는 글 생성 화면이다. 구성은 index.php와 유사하나 글을 작성할 수 있는 폼이 있다.

post 방식으로 사용자 입력값을 전달하는 폼을 만들었다.

 

제출 버튼을 누른 뒤 이전 페이지로 돌아와서 새로고침을 해준 모습이다.

data 폴더에는 입력값으로 된 새로운 파일이 생겼고, 이에 따라 php로 생성된 새 웹페이지도 만들어졌다.

성공적으로 글이 작성되었다.

 

하지만 매번 글을 작성한 뒤 빈 화면에서 이전 페이지로 돌아오고, 새로고침을 누르는 작업은 번거롭다.

글을 작성하면 바로 작성한 글이 있는 페이지로 이동하게 하고 싶다.

이때 사용하는 것이 리다이렉션 기능이다.

위 스크린샷 우측의 header 함수는 해당 php 파일이 실행되면 사용자를 지정된 웹페이지로 보낸다.

'입력값으로 만들어진 페이지로 사용자를 자동으로 보내는 것'이 목표이므로, 그렇게 해 준다.

 

글 '리다이렉션'을 작성하고 제출 버튼을 누른 모습이다. 별도 조작 없이도 작성한 글이 담긴 페이지로 바로 연결된다.


24. 글수정

https://youtu.be/ExLCGW51mk0

 

 

이번에는 작성한 글을 수정할 수 있게 기능을 추가해볼 것이다. 방식은 작성 기능 구현 때와 유사하다.

작성 때 글을 작성하는 페이지 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로,

글 작성 시와 동일하게 수정한 글이 있는 페이지로 바로 리다이렉트된다.

 


25. 글 삭제

https://youtu.be/jGWumB5EZ1o

 

 

수정에 이어 삭제 기능까지 구현해 보자.

 

다른 기능과 마찬가지로 a태그를 누르면 해당 페이지의 글이 삭제된다.

글이 있는 페이지에서만 삭제가 진행되어야 하므로 isset 조건식을 건 if문으로 해당 페이지가 url 파라미터를 가진 항목 페이지인지 확인하고, 맞을 경우에만 update와 delete 버튼이 노출되도록 한다.

 

글 PHP2를 삭제한 모습이다. data 디렉토리에서도, 웹페이지에서도 해당 내용이 말끔히 사라졌다.

삭제는 unlink 함수에 삭제할 항목의 경로를 입력하는 것으로 가능하며

돌아올 글이 사라졌으므로 리다이렉트는 홈 화면인 index.php로 이어지도록 한다.

 

 

그러나 위 방식은 문제가 있다. if문에 사용된 변수가 GET을 통해 전달된다는 점이다.

링크만 전달해도 글이 삭제되는 불상사를 막기 위해 우리는 이것을 POST로 바꿔줄 필요가 있다.

전달 method를 post로 바꾸고 전달받는 측에서도 POST 방식으로 전달받도록 수정한 뒤에 다른 글을 삭제해본 모습이다.

링크에도 전달 정보들이 나타나지 않으며, 삭제도 정상적으로 진행된다.

 


26. 파일로 모듈화 - require

https://youtu.be/jGWumB5EZ1o

 

 

 

이번 시간에 진행하는 것은 리팩토링이다. 중복을 제거하고 코드가 더 효용성을 갖도록 하는 방향으로 진행할 것이다.

먼저 index, create, update 상단에 있는 함수 모음 php 코드를 별도 파일로 뺀다.

기능적으로 중요한 모듈은 보통 lib 디렉토리에 보관하는 것이 관행이므로, lib 디렉토리를 만들어 이 php 파일을 넣는다.

원래 파일이 있던 자리에는 require(요구 대상의 경로명) 함수를 집어넣어 코드가 해당 파일을 요청할 수 있게 한다.

 

 

코드의 아래와 위에 중복되는 부분도 별도의 파일로 뺀다. 이것은 바깥으로 보여지는 부분이므로 view라는 디렉토리에 집어넣는다.

마찬가지로 require 함수를 집어넣어 없어진 부분을 외부에서 가져오도록 한다.

 

하지만 require 함수보다는 require_once 함수를 사용하는 것이 좋은 방법이다.

이렇게 require를 여러 번 사용하다 보면 한 문서 내에서 이미 선언된 함수에 대해 또 require하여 중복선언이 발생하는 경우도 생길 수 있기 때문이다. 이때 require_once를 사용해 이러한 사태를 방지할 수 있다.


27.1. 보안 XSS ~ 27.2. 보안 파일 경로 보호

 

웹을 만들어서 공개적인 장소에 내놓고 싶다면 항상 보안에 신경써야 한다.

웹해킹에서도 배웠듯 허술한 보안은 페이지에 인젝션 공격을 허용할 수 있기 때문이다.

가령 create 기능으로 위와 같은 문서를 만들면서, 일부러 자바스크립트 태그를 집어넣어 위와 같이 특정 페이지로 리다이렉션하는 기능을 넣어버린다고 가정하자.

 

폼을 제출하자마자 그 페이지로 강제이동되어버린다. 앞으로 저 항목을 클릭할 때마다 저 리다이렉션 코드가 발동되어 계속 이러한 강제이동 문제가 발생할 것이다.

그러면 이러한 문제를 개발자가 어떻게 예방할 수 있을까?

웹해킹 때도 배웠듯이, 입력에 있어 태그가 작동하지 못하도록 막으면 된다.

htmlspecialchars() 함수를 사용하는 것이다.

 

 

사용자가 줄 수 있는 모든 입력값을 해당 함수로 감싼 모습이다.

스크립트 태그가 제대로 동작하지 못하게 되고 단순한 문자열이 되면서 문제가 해결된다.

하지만 이 방법은 조심해서 써야 한다. 오만 군데 이 특수문자 함수를 사용하다간

제대로 태그를 사용해 출력해야 할 부분까지 스트링으로 돌아가 버릴 수가 있다.

 

이런 문제도 있다. 가령 패스워드 등 중요한 정보를 담은 파일이 프로젝트 폴더 내에 있다고 하자.

그러면 이 파일이 data 폴더 내에 들어있지는 않더라도, data 폴더 내의 자료를 요구할 때 경로를 입력하도록 하는 부분에서

이 패스워드 파일로 가는 경로를 입력하면? 시스템이 알아서 패스워드 파일을 갖다바쳐버린다.

이럴 때 해결책이 될 수 있는 것은 basename 함수이다.

 

basename은 경로가 주어지면 그 경로를 떼고 경로 끝에 있는 파일 자체의 이름만을 리턴한다.

좌측 세 줄은 원래 경로, basename으로 이름만 남긴 파일명, 파일의 내용이다.

위 케이스에서 문제가 되었던 것은 '파일의 경로'를 파라미터로 입력함으로써 시스템이 스스로 그 경로를 따라가 파일의 내용을 갖다바치게 하는 것이었으므로

경로를 따라가지 못하도록 이름만 남기면 쉽게 해결된다.

 

경로가 들어갈 수 있는 부분을 basename으로 감싸 처리한 모습.

이렇게 하면 타 경로가 아닌, data 안에 직접 들어있는 파일들만 파라미터가 될 수 있게 되어 문제가 해결된다.


29. UI API 그리고 공부방법

https://youtu.be/c4zbebEazs0

  • UI = User Interface. 사용자 입장에서 웹페이지를 봤을 때의 외적인 구성을 뜻한다.
  • API = Application Programming Interface. 웹페이지 내적으로 움직이는 기능 하나하나를 말한다. 함수, 태그 등이 포함된다.

 


30. 수업을 마치며

https://youtu.be/uMv5KpczgRg

 

아래는 앞으로 웹 개발을 진행할 때 알아두면 도움이 될 만한 것들이다.

 

  • PHP - Function Reference : PHP 공식 사이트에서 제공하는 가이드라인. php의 주요 API를 함수 위주로 알아볼 수 있다.
  • php Composer : 다른 사람들이 만들어둔 패키지를 공유받을 수 있는 사이트. 로그를 찍어주는 psr/log 패키지 등 유용한 기능이 패키지로 올라와 있다.
  • 데이터베이스 : 현대의 웹은 대부분 데이터베이스를 활용한다. 방대한 데이터를 파일로 저장했을 때보다 그 탐색과 관리에 있어 비교가 되지 않을 정도의 이점을 가진다.
  • PHP - php cookie, session : 사용자 관리와 인증에 사용하는 기능들.
  • federation authentication (검색어) : 타 사이트 연동 로그인 기능. 사용자의 인증을 타 거대 사이트에 위탁함으로써 안전성과 편리성을 얻는다.

1. 수업소개 ~ 2. 수업의 목적

https://youtu.be/Qh_6JheU_gY

https://youtu.be/w1CT7vlR-JI

 

 

PHP의 등장배경 : HTML에서의 불만족에서 비롯

- HTML로 된 페이지를 수동으로 하나하나 만들기보단 기계에게 관리하게 시킬 수 없을까?

 

-> PHP의 등장, 사람이 웹 페이지의 내용을 써서 기계에게 넘기면 기계가 알아서 그것을 HTML로 변환.

운영자는 컨텐츠에 전념할 수 있게 됨

 

 

PHP로는 무엇을 할 수 있는가?

: 단 하나의 파일로 여러 개의 웹페이지를 표시할 수 있음

: 일정한 양식에 따라 복수 개의 웹페이지를 찍어냄

: 사용자는 오직 페이지의 '내용'만을 입력, 양식에 맞추어 생성하는 것은 프로그램이 수행

 


3. PHP 설치 & 환경 설정

https://youtu.be/fNdKHF0tL9I

https://youtu.be/WboIThLXOGg

https://youtu.be/ruraZy625Ak

  1. bitnami 페이지에서 bitnami wamp 시리즈를 다운로드받기
  2. 로컬 디스크 > Bitnami > wampstack (버전명) > manager-windows 실행 :: 비트나미 매니저 프로그램.
  3. Manage Servers 탭에서 사용을 원하는 서비스를 눌러 Start 버튼 누르기 (초록색이 활성화 상태)
  4. 실습을 진행할 때는 위 경로에서 apache2 > htdocs 디렉토리에 파일 생성. 기존에 있던 파일은 모두 삭제해도 무방.

 

에디터는 저번 실습과 마찬가지로 Atom 사용.

 

위 내용대로 간단한 php 코드를 입력하고,

브라우저에서 127.0.0.1/(파일이름).php 주소를 치면

 

이런 정보 페이지가 나온다. 여기까지 왔다면 php 설치가 성공적으로 이루어진 것이라고 볼 수 있다.

 

다음으로는 php의 설정을 만지는 법을 알아보자.

wampstack(버전명) > php > php(구성 설정) 파일을 마우스 우클릭해 '편집'을 누르면

메모장에 다음과 같은 내용이 뜬다.

 

여기서 Ctrl + F를 눌러서 display_errors를 검색해보자.

첫 검색결과는 앞에 세미콜론이 붙어 있을 것이다. 그 다음 검색결과로 넘겨서 세미콜론이 없는 줄을 찾는다.

 

Off로 되어 있는 것이 보이는가? 저것은 웹페이지의 에러를 표시해 주느냐/주지 않느냐를 결정하는 옵션이다.

기본이 Off로 되어 있는 것은 에러가 밖으로 드러나면 취약점이 외부에 훤히 드러나 있는 것이나 마찬가지이기 때문이다.

공격자들에게는 좋은 먹잇감이라고 할 수 있다. php를 이용해서 정식으로 서비스를 하는 사람이라면 저 옵션을 꺼야 한다.

하지만 우리는 학습 중이기 때문에 우리가 만든 페이지의 에러를 파악할 수 있어야 한다.

Off로 되어 있는 부분을 On으로 바꾼다.

 

다음은 opcache.enable 로 검색해 보자.

1로 되어 있다. 값을 0으로 바꿔주어야 한다.

저 옵션은 웹 서비스의 성능에 관여한다.

저 옵션이 1로 켜져 있으면 같은 시간 내에 서버가 더 많은 페이지를 만들어낼 수 있다.

그러나 그만큼 우리가 에디터에서 페이지를 수정한 사항이 한참 더 느리게 (30초~1분 소요) 반영되기 때문에

바로바로 변경사항을 보아야 하는 학습자 입장에서는 끄는 편이 좋다.

 

다 수정했으면 저장을 누르고 끄자. 그리고 다시 manager-windows를 열어준다.

그리고 위에서 보았던 Manager services 탭에서 Apache Web Server를 Restart해준다.

잠시 노란 불이 들어왔다가 다시 초록불이 들어올 것이다.

 

php는 끄는 방법이 없다. 때문에 php 설정을 변경하려면 php가 의존하고 있는 웹 서버인 아파치를 껐다 켜야 한다.

아파치는 켜질 때만 설정 파일인 php.ini를 한 번 읽어오기 때문에 변경된 설정을 적용하려면 Restart할 필요가 있다.

(이유는... 성능 때문이다. 사용자가 들어올 때마다 일일이 설정 파일을 확인한다면 얼마나 느려지겠는가?)

 

 

 

아파치를 재부팅했다면 이제 그대로 Restart 버튼 밑의 Configure을 누른다.

작은 창이 하나 뜰 것이다. 거기서 Open Access Log를 누른다.

 

 

이런 창이 뜰 것이다.

이것은 말 그대로 접속 로그다. 이 php로 서비스하는 사이트에 사용자들이 접속하면 그 기록이 여기에 남는다.

마찬가지로 Open Error Log를 누르면 에러 기록이 나타난다. 사이트에 문제가 발생하면 그 사항이 여기에 기록된다.

 


4. PHP의 원리

 

https://youtu.be/ObrMbYq9DC4

  • 웹 브라우저(클라이언트)가 웹 페이지 파일 요청 -> 웹 서버가 컴퓨터에 저장 중인 웹페이지 파일을 서비스
  • .html 파일을 요청했을 경우 : 위의 과정대로 통상적으로 서비스
  • .php 파일을 요청했을 경우 : 서버 혼자서는 처리할 수 없는(읽을 수 없는) 파일
  • -> php 프로그램에 인계 -> php 프로그램에서 해독해 html 소스로 변환 -> 웹서버가 서비스
  • => 클라이언트가 웹페이지를 서비스받아 코드를 보면 (해독 결과인) html 파일만이 나타남

ex) php 코드에서는 '현재 시각을 표시해주는 함수' 임에도

클라이언트가 받은 html 코드에서는 현재 시각을 나타낸 스트링 자체만이 표시됨

= php는 동적, html은 정적. html로 나타나는 것은 php의 결과값 뿐

 

 


5. PHP의 데이터 타입 ~ 5-2. PHP와 문자열

 

https://youtu.be/-0LAb1Yvdq4

https://youtu.be/O-sfI80mdbo

 

 

1. php에서 숫자를 표현하는 방법

  • 정수형(Integer)과 실수형(Float)이 존재함
  • 작동 원리는 자바스크립트와 유사함 (<? ?> 안에 코드를 삽입, 동적으로 결과값만 표시)
  • 출력할 때는 echo를 사용
  • 문장 끝에는 세미콜론

 

 

2. php에서 스트링을 표현하는 방법

 

  • 스트링은 큰따옴표(" ")나 작은따옴표(' ') 안에 표현
  • 문장에 따옴표가 나타나게 하고 싶으면 다른 종류의 따옴표로 스트링을 감싸거나 이스케이프(\") 활용
  • 문장을 접합하는 연산자로 온점(.) 사용
  • strlen() 함수 사용 가능 (스트링 길이 리턴)

6. PHP의 변수

https://youtu.be/2EIH5Lbfavc

 

php에서의 변수 = $(변수명)

  • 변수를 선언할 때는 $ 기호 뒤에 변수명만 적어주면 된다
  • 선언할 때 이외에도 php 코드 어디에서든 $를 붙이고 나타나는 이름은 변수명이 된다
  • 변수명은 그 자체로 . 기호를 이용하여 스트링과 접합될 수 있다

 

예시 )

(Atom은 lorem 키워드를 입력하면 예시 스트링 문단을 생성해 준다)

 

예시 문단 사이사이 동일한 단어를 삽입해야 할 때 변수를 이용하면 수정과 관리가 편안하다.

 

삽입되는 단어가 변수 $name이라는 이름으로 관리되고 있는 모습.

$name의 값이 다른 스트링으로 변경되었지만

별도의 예시 스트링 수정 없이 변경된 값이 페이지에 적용된다.

 


7. php의 url 파라미터

https://youtu.be/73RCtVNZM4E

 

 

 

 

php에는 url 파라미터라는 것이 있다. 특정 요소의 값을 url에서 지정하는 것으로,

$_GET['(요소 이름)']; 과 같은 양식을 이용한다.

직접 한 번 보자.

위 스크린샷에서는 사람의 이름을 변수 $name을 선언해서 받지 않고,

url에서 지정해 주는 파라미터 값을 받아와 출력했다. 물론 php이기 때문에 검사 도구를 이용해서 보면

단순히 html로 된 문장처럼 보인다.

url 파라미터를 이용할 때는 아래와 같은 양식을 따른다.

 

(링크 주소) ? (파라미터 이름) = 파라미터 값

 

복수의 파라미터를 이용하고자 할 때는 & 기호로 접합해주면 된다.

 

(링크 주소) ? (파라미터 이름) = 파라미터 값 & (파라미터2 이름) = (파라미터2 값)

 

 

아래는 이미 html로 한 번 구축했던 페이지에 파라미터를 적용한 예시이다.

다른 부분은 html 수업에서 다뤘던 예제와 동일하나, (사이트명).html이 아닌

(사이트명).php?(파라미터명)=(파라미터값) 형식의 링크를 지니고 있다.

또한 a 태그에 들어간 링크가 php로 생산되는 페이지로 바뀌어 있고

h2 태그의 내용이 파라미터값에 따라 바뀌도록 되어 있다.

이처럼 파라미터는 php의 기능인 '양식에 따라 내용이 바뀌어 생산되는 페이지'를 만드는 데 매우 요긴한 기능이므로

잘 숙지해둘 필요가 있다.


8. 함수의 사용

https://youtu.be/IIU4mypKLlw

 

 

php에서도 여타 프로그래밍 언어에서와 마찬가지로 함수를 쓸 수 있다. 아래는 그 예이다.

 

(특정 예시 문장을 $str 변수로 지정해놓은 상태)

  • strlen($str) = 예시 문장의 길이를 출력한다.
  • nl2br($str) = 예시 문장의 개행을 html의 <br> 태그로 바꾼다. (html은 문장에 단순히 개행을 한다고 해서 페이지에도 개행으로 나타나는 것은 아니기 때문에 이 함수는 요긴하다.)

 

적용 사례를 보자.

파라미터를 적용해 놓은 페이지에 함수를 도입한 모습이다.

h2 태그의 내용뿐만 아니라 밑에 있는 스트링까지도 id 파라미터에 따라 다르게 나타나도록 만들기 위해서

프로젝트 폴더에 'data'라는 이름의 디렉토리를 만들었고,

그 디렉토리에 id가 가질 수 있는 값들(html, css, javascript)을 각각 파일명으로 하여 스트링 데이터를 넣어두었다.

여기서 data/(id값)을 인수로 갖는 file_get_contents 함수를 사용하면

인수인 디렉토리 경로에 있는 파일의 내용을 가져올 수 있다. 출력은 마찬가지로 echo로 수행한다.


11. Boolean과 비교 연산자

https://youtu.be/510Wp9CjtTk

 

php에도 마찬가지로 불리언과 비교 연산자가 있다.

(&amp는 '&' 기호를 나타내는 표현법이다.)

(var_dump()는 입력값을 출력해 주되, 그 자료형까지 함께 출력해 주는 함수이다.)

 

JS나 여타 프로그램 언어에서와 마찬가지로 php에서도 참/거짓을 나타내는 불리언이 존재하고

비교연산자가 포함된 표현식은 그 불리언을 값으로 갖는다.

 


12. 조건문의 형식

https://youtu.be/ZvhFgNsufHg

 

 

php에도 if와 같은 조건문이 존재한다. 쓰는 방식은 여타 프로그래밍 언어에서의 if와 다르지 않다.

 

하단은 코드, 상단은 결과이다. 조건식인 true에 따라 앞쪽의 코드인 2-1이 출력되고 있다.

 

적용 예시를 보자.

'id' 파라미터의 값이 설정되어 있다면 그 값에 따른 내용을, 설정되어 있지 않다면 별도의 메시지를 출력하고 싶으므로

특정 값이 설정되어 있는지 여부를 불리언으로 리턴하는 isset() 함수를 사용했다.

위의 경우는 url 파라미터에 값이 들어가 있는 경우이며, 따라서 h2 태그와 하단 스트링에 id값에 따른 내용을 출력한다.

 

파라미터 값이 들어가지 않은 경우이다. else문이 작동하여 별도 메시지가 출력된다.


15. 반복문의 형식 ~ 16. 배열의 형식

https://youtu.be/Nlz04vYZtcI

https://youtu.be/5jl6ajMrCW8

 

반복문과 배열 또한 마찬가지로 php에 존재한다.

 

반복문 형식은 동일하게 while을 사용하면 된다. 1~3까지의 수를 출력하며 2를 3번 반복하여 출력하도록 설정한 모습이다.

echo에는 자동 개행 기능이 없으므로 출력할 스트링에 br 태그를 별도로 넣어줘야 한다는 점에 유념한다.

 

  • php의 배열도 js에서의 배열과 마찬가지로 선언 시 좌항에 별도의 조치가 필요하지 않다.
  • 변수를 선언할 때 우항에 array라는 키워드와 함께 소괄호()를 사용하고, 소괄호 안에 자료들을 나열해 주면 된다.
  • 배열의 원소에 접근할 때는 마찬가지로 대괄호[]와 인덱스를 사용한다. 인덱스는 0부터 시작한다.
  • count() 함수를 사용하면 배열 원소의 개수를 리턴받을 수 있다.
  • 배열에 원소를 추가하는 것이 가능하다. array_push() 함수를 사용한다.
  • var_dump 함수로 배열을 출력하면 인덱스 => 자료형(자료내용) 의 양식으로 모든 원소의 정보가 출력된다.

 


17. 반복문과 조건문의 활용 (.1~.3)

https://youtu.be/dOWhji4PY2k

 

 

 

 

디렉토리 data에 몇 개의 데이터들이 더 추가되었다고 가정하자. 이것들은 앞으로 더 늘어날 수도 있다.

이렇게 되면 아까까지 하던 방법으로는 품이 너무 많이 들어갈 것이다.

우리는 '디렉토리에 있는 파일들의 이름을 모두 가져오는' 함수가 필요하다.

이와 같은 경우 scandir와 같은 함수가 좋은 해법이 될 수 있다.

인수로 넣는 디렉토리 경로는 디렉토리명의 규칙(.은 현재 디렉토리, ..는 부모 디렉토리)을 따른다.

scandir 함수로 가져온 값을 list 변수에 넣어 출력해보니 위와 같은 형태의 배열이 출력되었다.

scandir 함수의 리턴값은 배열이다. 이 사실을 잘 활용해 보자.

 

while 반복문을 통해 list의 값을 0부터 6까지 순서대로 출력하게 만들었다.

인덱스 0은 현재 디렉토리, 1은 부모 디렉토리이고 그 다음부터 디렉토리 내의 파일명을 나열하기 때문에

조건식을 약간 수정할 필요가 있겠다. 더불어 출력할 li 태그 안에 원래처럼 a 태그도 함께 출력하도록 해 보자.

 

 

배열의 원소 수를 세어주는 count 변수를 조건식에 넣었다.

이제 배열의 원소 수가 바뀌어도 바로바로 페이지에 반영될 것이다.

a 태그에 넣는 링크도 list 배열의 인덱스에서 파라미터 값을 가져오도록 설정해 주었다.

이제 위에 표시되는 . 과 ..만 표시되지 않게 해 주면 될 것이다.

 

 

다시 수정을 가미한 모습이다. 이번에는 조건문을 사용했다.

시험해본 결과 php의 if문에서는 ||나 && 등 조건을 결합해 주는 기호들이 작동하지 않는 듯 하므로

부득이하게 강의 영상과 같이 이중 if문을 사용해 조건곱을 나타내 주었다.

인덱스를 통해 가져온 배열의 원소가 .나 ..일 때는 표시하지 않게 하여

깔끔한 목차를 구현해낼 수 있었다.

30. 객체 쓰기와 읽기

https://youtu.be/2j04s1erzTs

 

 

저번 시간에서 예고한 바와 같이 이번 시간에는 객체의 구체적인 사용법을 배운다.

JS의 객체는 C에서의 구조체나 자바의 객체와 비슷한 점이 많지만, 더 간단하고 직관적인 면이 있다.

배열을 선언할 때 따로 좌항에 대괄호나 배열 크기 같은 정보를 넣지 않고 일반 변수를 선언할 때와 같게 변수 이름만을 적었던 것을 기억할 것이다. 객체도 같다.

 

var (객체이름) = {

(멤버 이름)(멤버 내용),

(멤버 이름) : (멤버 내용)

};

 

각 멤버변수의 선언은 콤마로 구분한다.

 

선언한 객체의 멤버변수에 접근할 때는? 타 언어의 구조체나 객체를 쓸 때와 같다.

객체 이름을 쓰고, 점(.)을 찍고, 멤버변수 이름을 쓴다.

 

위 스크린샷과 같은 식이다.

이미 선언된 객체에 멤버변수를 추가하고 싶을 때는? 뻔뻔해지면 된다. 평범한 대입문처럼 쓴다.

 

(객체이름).(추가할 멤버변수 이름) = (추가할 멤버변수 내용);

 

이렇게 적으면 바로 추가가 된다. 다른 언어에서는 이렇게 썼다간 에러가 나기 쉽지만 JS는 이게 된다.

 

멤버변수명으로 삼을 스트링에 띄어쓰기를 넣어도 될까? 된다.

다만 접근이나 추가할 때 점 대신 대괄호를 사용해줘야 한다.

 

(객체이름)["멤버변수 이름"] = (멤버변수 내용);

 

이런 식이다. JS가 웹 문서, 즉 문자열이 주 표현 방식이 되는 매체를 다루는 언어임을 생각해 보면 매우 편리한 방식이다.

 


31. 객체와 반복문

https://youtu.be/GIB8O6R3wko

 

 

이번에는 객체에 반복문을 적용하는 방법을 알아보자.

아까 객체 안에 멤버변수를 선언할 때 멤버변수의 이름이 되었던 것을 key라고 한다. 이 키는 우항에 있는 값을 끌어내는 라벨 역할을 한다. 때문에 객체에 반복문을 도입할 때는 이런 식으로 적을 수 있다.

 

for (var key in (객체이름)) {

     (반복할 내용)

}

 

이렇게 하면 객체 안에 있는 key의 수만큼 for문 안의 내용을 반복해서 수행할 수 있다.

위의 스크린샷은 key의 수만큼 반복 / 모든 key의 내용을 한 줄에 하나씩 출력 한 결과다.

 

그럼 key값 말고, key값에 대응되는 모든 내용들을 출력하려면?

이 역시도 간단하다. key가 배열의 인덱스처럼 작용한다고 생각해 보자.

배열의 i번 인덱스에 든 내용을 꺼내기 위해서 우리는 [i]라는 기호를 썼었다.

객체도 마찬가지다. 객체 이름을 쓴 뒤 대괄호 안에 키값을 넣으면 그에 해당되는 값이 나온다.

 

coworkes[key] 부분이 보이는가? 인덱스가 값을 이끌어낼 수 있는 것처럼 키도 같은 원리로 값을 이끌어낼 수 있다.

 


32. 객체프로퍼티와 메소드

https://youtu.be/mjzx1qbyPwU

 

 

객체 안에도 함수를 선언할 수 있다. 양식은 이런 식이다.

 

(객체이름).(함수이름) = function() {

     (함수 내용)

}

위에 썼던 반복문을 그대로 객체 내의 함수로 표현한 것이다. 출력 결과가 조금 이상하다 싶지만 이게 맞다.

이 함수 내의 모든 변수 및 함수를 키와 함께 출력하는 것이기 때문에 당연히 이 함수의 내용도 같이 출력되는 것이다.

 

하지만 이대로는 번거로운 점이 있다. 함수 안에 객체의 이름이 언급되어 있다는 점이다.

만약 이 객체의 이름을 변경한다고 치면 그때마다 이 함수에서 언급된 객체의 이름도 변경해야 한다.

그것을 막기 위해 사용하는 것이 this이다.

 

 

위와 같이 함수에서 객체의 이름을 언급할 때마다 this로 대체하여 언급하면

객체 이름이 변경되더라도, this는 이 함수가 소속된 객체를 가리키는 말이므로 지칭되는 대상은 바뀌지 않는다.

 

이렇게 객체 안에 소속된 함수는 메소드,

객체 안에 소속된 변수는 프로퍼티라고 한다.

 

 


34. 객체의 활용

https://youtu.be/JNaX6EG9-FI

 

 

그러면 위에서 배운 메소드와 프로퍼티 기능을 데이/나이트 모드 예제에 적용해 보자.

아래 스크린샷은 글씨의 색을 바꾸는 기능과 배경의 색을 바꾸는 기능을 함수에 집어넣어

그것을 객체에 적용한 예시이다.

 

 

훨씬 코드가 깔끔해진 것을 느낄 수 있다.

 

이 스크린샷은 기존 코드에 존재했던 모든 기능을 메소드로 만들어 객체 안에 집어넣은 것이다. 왼쪽 페이지를 구현하기 위해 필요한 코드는 오른쪽 페이지에 나타나 있는 것이 전부이다. 그 정도로 이 코드는 축약되었고, 필요한 부분만이 남았으며 잘 정리된 코드가 되었다.

 


34. 파일로 쪼개서 정리정돈하기

https://youtu.be/1f7Svm6ivDY

 

 

이렇게 만든 JS 코드를 모든 웹페이지에 적용하고 싶다고 해 보자.

그러면 우리는 저 script 태그로 감싸진 내용을 모든 페이지에 복사 및 붙여넣기해야 할까?

적용해야 할 웹페이지가 수십 개 되어도? 그건 너무 비효율적인 일이다.

다행히도 JS는 따로 파일로 분리하는 것이 가능하다. 이렇게.

 

우측 상단을 보면 colors.js라는 파일이 보일 것이다.

그 파일에 script 태그를 제외한 모든 js 코드를 옮겨두고, script 태그에는 src = "js 코드 파일명" 만 적어두었다.

여는태그와 닫는태그 사이는 전부 비워둔 채로 말이다. 그럼에도 불구하고 위와 같이 멀쩡하게 작동한다.

 

그러면 이제 우리는 수고를 덜었다. 어떤 웹페이지에든 겉으로 보이는 버튼을 표현할 html 코드, 그리고 내부적인 기능을 담당할 script 태그와 src만 적어두면 같은 기능을 적용할 수 있으며, 변경사항이 생겨도 그때그때 모든 페이지에 적용시키는 것이 가능하다.

 

이렇게 하면 편리한 점이 한 가지 더 있다. 브라우저는 서버로부터 다운로드해야 할 파일이 하나 더 늘어나기는 하지만,

한번 다운로드한 파일은 캐시에 저장되므로 다른 웹페이지를 다운받을 때에도 이미 다운받아둔 js 파일이 있으므로

js가 들어가는 공통된 부분은 여러 번 다운로드받을 필요가 없어진다.

 


35. 라이브러리와 프레임워크

https://youtu.be/pJTpl3umvE8

 

오늘날 우리는 소프트웨어를 처음부터 끝까지 혼자 만들지 않는다.

다른 사람들이 이미 만들어 둔 기능의 부품들이 넷상에 즐비하고,

우리는 그것을 이용하여 또다른 소프트웨어를 만들 수 있다.

 

이에 대해서는 두 가지 개념이 있다. 라이브러리프레임워크라고 하는 것인데,

 

먼저 라이브러리는 다른 사람이 만들어 둔 기능의 집합이다. 말하자면 부품, 또는 모듈이라고 할 수 있다.

필요한 기능을 가진 라이브러리를 끌어 와서 내 소프트웨어에 접목하면

우리는 그것을 내가 만든 소프트웨어의 일부로 기능하게끔 할 수 있는 것이다.

 

반면 프레임워크는 틀, 양식, 혹은 템플릿에 비견된다.

파워포인트를 만들 때도 처음부터 끝까지 모든 것을 배치하기보단 템플릿을 사용하는 편이 편리하듯이 

프로그래밍도 그렇게 할 수 있다. 게임이면 게임, 채팅이면 채팅 등 수많은 프로그램 개발을 위한 프레임워크가 있고

우리는 그 틀에 내부적으로 조금씩의 변형을 주어 그 프레임워크의 특성에 맞는 프로그램을 개발할 수 있다.

 

 

유명한 라이브러리로는 jQuery라는 것이 있다. 상당히 오래되었고, 생산성이 좋다.

 

검색하면 쉽게 찾을 수 있으며, 이것을 다운로드받아 프로젝트 폴더에 탑재하면 사용할 수 있다.

그러나 이것을 그냥 다운받아 사용한 프로그램을 배포 및 서비스하려면 따로 사용료를 내야 하므로,

우리는 CDN에 대해서도 알아둘 필요가 있다.

 

CDN은 Contents Delivery Network의 약자이다.

jQuery 등 라이브러리 배포 페이지를 잘 찾아보면 CDN 코드가 있다.

script src에 이 코드를 붙여넣으면 본 프로그램을 다운받지 않아도 프로그램에서 라이브러리를 사용할 수 있다.

다운로드받는 것보다 쉬운 것은 코드 한 줄 쓰는 것이다. 돈 내는 것보다 좋은 것은 무료로 쓰는 것이다.

어찌 보면 당연한 이 원칙을 라이브러리 제작사들이 모를 리 없고, 때문에 CDN을 구축하게 된 것이다.

 

우리는 계속해서 중복을 줄이며 코드를 효율성 있게 짜는 방법을 배워왔고,

그 단위를 배열, 함수, 객체, 파일까지 확대하며, 이제는 내가 짜지 않은 프로그램을 빌려와 이용함으로써

프로그램을 짤 때마다 방대한 기능을 일일이 손으로 구현해야 할 수고가 크게 줄어들게 되었다.

 

 

22. 배열과 반복문

 

https://youtu.be/BjkfkKdlvLo

 

JS에서 배열을 활용하는 방법은 간단하다. 만약 아래 스크린샷과 같은 스트링 배열이 있다고 가정하자.

이 배열에 든 스트링을 한 줄씩 li 태그로 감싸 기입하고 싶다.

한 줄씩 일일이 쓸 수도 있겠으나, 그렇게 하면 배열의 원소가 많아질수록 쓸데없는 노동을 반복하게 될 것이고

유지보수도 쉽지 않을 것이다.

이 부분을 JS가 해결해 줄 수 있다.

 

우선은 위와 같이 간단한 반복문을 만든다. <script> 태그를 먼저 쓰고,

여타 프로그래밍 언어에서 했던 대로 반복에 사용할 i 변수를 선언한 뒤 while문을 적는다.

i를 하나씩 증가시켜 가며 li 태그를 출력하는 document.write문을 적는다.

세이브 후 실행하면 내용이 없는 ul이 4개 만들어져 있을 것이다.

 

그런 다음엔 li 태그 사이로 + 기호로 감싼 coworkers 변수를 넣어 준다.

변수 배열이므로 대괄호를 적고, 안에 i 변수를 넣어 인덱스를 표시하게 한다.

세이브 후 실행하면 배열의 원소들이 차례로 리스트에 들어가 있는 것을 확인할 수 있다.

 

하지만 이 방식은 번거로운 점이 있다. 만약 저 배열의 원소 수가 늘어나거나 줄어든다면?

원소가 사라지거나 추가된다면 어떻게 되겠는가? 그때마다 (i<4) 라는 조건식을 수정해야 할까?

데이터가 바뀌었다고 해서 그때마다 로직을 바꿔야 하는 것은 프로그래머에게 있어 부끄러운 일이다...

 

조건식을 다르게 표현해 보자. i는 '배열의 길이만큼' while문의 내용을 반복되게 하는 변수이다.

그렇게 생각하면 넣어야 할 것은 명확해진다.

 

어렵지 않게, 바뀐 데이터 전부가 표현되는 로직이 만들어졌다.

 

반복문과 배열이라는 요소의 중요성은 프로그래밍에 있어서는 굳이 말할 필요도 없을 정도이다.

우리는 이제 반복할 데이터가 얼마나 많든 간에, 그 반복에 무엇을 넣어 몇 번 수정하고자 하든 간에

훨씬 적은 수의 조작으로 이를 충분히 구현할 수 있을 것이다.

 


23. 배열과 반복문의 활용

https://youtu.be/hZdBDoYHd7E

 

 

 

위에서 배운 배열과 반복문을 앞선 주차 정리에서 사용했던 데이모드/나이트모드 예제에 활용해 보자.

데이/나이트 모드를 전환할 때 하이퍼링크가 있는 부분의 색이 짙은 파랑/옅은 파랑으로 바뀌게 해 보려고 한다.

이 모든 태그들을 하나하나 타겟밸류로 해서 전환 기능을 달아주는 것은 당연히 비효율적이다.

어떻게 해야 할까?

 

 

우리에게 필요한 것은 'a 태그가 달린 모든 부분을 선택하는 기능' 이다.

페이지에서 콘솔을 열고 querySelector로 a 태그를 선택해 보면 a 태그를 달고 있는 라인이 나오지만,

querySelector로 선택되는 것은 수많은 a 태그 요소 중 하나, 그것도 가장 첫 번째 것뿐이다.

 

 

a 태그를 달고 있는 요소 전부를 선택하려면 querySelectorAll을 쓰면 된다.

위 콘솔의 내용처럼, a 태그를 달고 있는 모든 엘리먼트가 NodeList로 반환되는 것을 볼 수 있다.

 

이 querySelectorAll이 반환하는 값을 변수에 담아준다. 리스트를 담은 변수이므로 이는 자동으로 배열이 된다.

이 배열을 console.log에 넣어 인덱스와 함께 사용하면 리스트의 n번째 변수를 쉽게 추출할 수 있게 된다.

 

 

alist.length를 사용하면 해당 태그를 가진 엘리먼트 전체의 갯수를 구하는 것도 쉽다.

 

 

이 변수를 반복문에 넣어 인덱스별로 하나씩 출력해 보았다. 정상적으로 네 개의 엘리먼트가 모두 출력된다.

이제 우리는 a 태그를 단 모든 엘리먼트를 골라내는 방법을 알아냈고,

남은 것은 이것들의 style 속성을 변화시키는 것뿐이다.

 

 

출력문 아래에 style.color 속성을 변화시키는 코드를 한 줄 써 주었다.

옅은 파랑으로 색을 변화시키는 코드를 사용하자 해당되는 모든 엘리먼트들의 색이 변화한 것을 볼 수 있다.

잘 작동한다는 것을 알았으니, 이제 Atom의 본 코드에 이를 옮겨적어 주자.

else문 안에도 붙여넣어 색을 blue로 변경시켜 주도록 한다.

day 모드에는 blue, night 모드에는 powderblue가 적용되도록 바꿔주면 된다.

 

 


24. 함수 예고 ~ 25. 함수

https://youtu.be/IOuePUzLdnQ

 

 

웹페이지는 코드가 길어지면 자연히 무거워지고 가독성도 떨어지기 때문에 축약할 수 있는 것은 최대한 축약해야 하며

그 수단 중 하나가 함수이다.

 

예를 들어 위와 같은 코드가 있다고 가정해 보자. 위 강의까지에서 우리는 반복을 처리할 때는 반복문을 사용했다.

그러나 규칙적이지 않은 반복은 반복문으로 처리하기 힘들고,

자연히 반복되는 어떤 '특정한 부분'을 함축할 코드가 필요해진다.

여기서 등장하는 것이 함수이다.

 

JS에서 함수를 사용하는 것은 간단하다.

변수를 선언할 때 자료형 대신 var이라는 키워드를 사용했던 것처럼

자료형 대신 function이라는 머릿말을 달고, 파라미터가 들어갈 소괄호를 적어준 뒤에(없다면 비워두면 된다)

중괄호 안에 함수로 축약할 코드를 적어주면 된다.

 

반복되는 부분을 함수로 축약하고, 해당 코드가 들어갈 부분마다 코드 대신 함수를 호출했다.

함수를 사용하기 이전의 코드와 결과값은 완전히 똑같지만 내부적으로는 전혀 다른 코드가 된 것이다.


26. 함수 : 매개변수와 인자

https://youtu.be/MXf9UqMXuGM

 

함수가 '입력을 받아 출력을 뱉는 기계' 라고 한다면

'입력'은 Argument, '출력'은 Return 값이라고 할 수 있다.

 

위 스크린샷의 sum 함수를 보면 소괄호 안에 left, right라는 것이 들어있다.

이것이 이 함수의 parameter(매개변수)가 된다. (JS에서는 늘 그렇듯이 자료형을 써줄 필요가 없다.)

 

sum이라는 함수는 호출될 때 이 left와 right라는 매개변수를 통해 자료를 받아

함수 내에서 두 값을 더하고, <br> 태그를 덧붙여 개행하는 기능을 수행하는 것이다.

 

그리고 함수가 실제로 사용(호출)될 때 sum 옆에 들어가는 2, 3 등의 숫자는 argument(인자)가 되며

이것이 매개변수를 통해 함수 내로 전달되는 자료가 된다.

 

 


27. 함수(리턴)

https://youtu.be/6MzCHO8M3Uc

 

 

리턴 개념을 보기 전에 먼저 expression(표현식)이라는 개념에 대해 짚고 넘어가자.

1은 1이라는 값을 내는 표현식, 2+2는 4라는 값을 내는 표현식, 3==3은 true라는 값을 내는 표현식이다.

 

여태까지 작성했던 함수들은 어떠한 기능을 보여주기는 했으나 기능 그 자체에서 그쳤다.

이제 함수가 어떠한 표현식으로 '결과값'을 만들어 어딘가로 돌려주도록 만들 것이고, 그것이 리턴이라는 개념이다.

 

사용하는 방법은 간단하다. 일반 프로그래밍 언어에서의 함수처럼 return문을 적고

뒤에 리턴할 값에 대한 표현식을 적어주면 된다.

위는 사용 예시이다.

같은 함수와 같은 인자를 다양한 문장에 집어넣어 각각의 문장에 맞는 다양한 결과값이 나오는 것을 볼 수 있다.

 

리턴은 함수가 어떤 '값'을 대치할 수 있게 만든다. 축약할 수 있는 대상을 문장뿐만 아니라 값으로도 확장함으로써

코드는 더욱 융통성과 유연성, 편리함을 지니게 된다.

 


28. 함수의 활용

https://youtu.be/WsPJ8FsoMcU

 

위에서 배운 함수 개념을 사용해 데이/나이트 모드 예제를 리팩토링해 보도록 하자.

 

기존에 태그 안에 속성값으로 들어 있던 코드를 함수로 옮기고 nightDayHandler()라는 이름을 부여했다.

그리고 원래 코드가 있던 자리에는 코드 대신 함수 이름을 적어준 뒤 세이브+실행해 보았다.

 

잘 작동하는 것처럼 보이기도 하지만 무언가 이상하다.

나이트 모드에서는 버튼에 적힌 이름이 Day로 바뀌어야 하는데 바뀌지 않는 것이 보인다.

문제는 this라는 키워드에 있다. 함수를 태그 밖으로 옮겼으니 이 함수에서 말하는 this는 더 이상 해당 태그가 아닌,

전역 객체인 웹페이지 전체를 가리키게 된다.

 

이 현상을 해결하려면 어떻게 해야 할까?

태그 밖으로 나간 함수가 가진 this 키워드가 함수 전체가 아니라 원래 그 코드가 있던 태그를 가리키도록 하면 된다.

이를 위해서는 매개변수와 인자를 이용한다. 함수를 호출할 때 호출한 태그를 지칭하는 this를 인자로 넘겨주고,

함수에서는 self라는(이름은 임의 지정됨) 매개변수를 만들어 이 this를 받도록 한다.

그리고 함수 내의 코드에 있던 기존의 this들은 모두 self라는 키워드로 대체한다.

 

정상적으로 작동한다. JS에서 함수란 대략 이런 식으로 사용된다.

 


29. 객체 예고

https://youtu.be/6lJEbSYA4B4

 

여태까지 우리는 코드를 담아 정리하는 도구로 함수를 사용해 왔다. 그러나 이 함수도 많아지면 역시 너저분해 보일 수 있고, 다시 가독성을 저해하게 된다. 그러면 자연히 이를 담아 정리할 더 큰 개념이 필요해지게 되는데,

이때 등장하는 것이 '객체(object)'이다.

 

앞서 만들었던 nightDayHandler 함수에서 반복되었던 부분을 다시 별도의 함수인 setColor로 정리했다.

바꾸고 싶은 색상을 인자로 넣고, 모든 a태그의 색상을 바꾸고 싶을 때마다 setColor 함수만 부르면 되게끔 했다.

 

그런데 리팩토링 과정에서 코드를 정리해 가다 보면 위와 같이 링크의 색을 바꾸는 것뿐만 아니라

글씨의 색, 배경의 색 등 다양한 요소의 색을 바꾸고 싶어질 수도 있다. 이 함수들도 setColor라고 하면 되나?

 

당연하지만 안 된다. JS에서 이름 중복은 에러는 아니지만, 앞에 적혀 있는 함수를 뒤에 적힌 동명의 함수가 덮어쓰도록 되어 있고-그러면 당연히 앞의 함수는 무용지물이 된다.

그러면 프로그래머는 당연히 이와 같은 중복을 피해야 할 것인데, 모든 setColor 함수를 이름만으로 구분지을 건가?

코드가 짧고 요소가 적은 초기에야 이와 같은 방법이 통하겠지만, 요소가 늘어남에 따라 점점 이 방식에도 한계가 올 것이다. (A 엘리먼트의 글씨의 색을 바꾸는 함수와 B 엘리먼트의 글씨의 색을 바꾸는 함수... 이런 것들을 전부 이름에 적어서 구분한다면 함수 이름만으로 코드가 꽉 찰 것이다!)

 

그러나 그럴 필요는 없다. 함수를 분류하는 객체라는 도구가 이미 마련되어 있다. 우리는 객체를 배우면 그 객체를 생성한 뒤, 객체 이름을 적고 .을 적은 뒤 함수 이름을 적으면 된다. 객체 이름만 다르다면 그 뒤에 오는 함수 이름은 얼마든지 중복되어도 상관없다.

 

객체에 대해서는 다음 주차에 알아보도록 하겠다.

15. 비교 연산자와 불리언

https://youtu.be/A2qp-jpk_XA

 

 

비교 연산자 : 좌항과 우항의 값을 비교해서 Boolean(true or false)값을 만든다

 

'===' : 좌항과 우항의 값이 '같은지' 를 판단한다

(구글링해 보니 정확히는 값과 타입이 모두 완전히 일치하는지를 판단하는 연산자라고 한다.)

 

'<' (&lt;), '>'(&gt;) : 두 자료의 대소를 비교한다

 

(html에서 <나 >는 꺽쇠기호라는 문법을 나타내기 때문에 특수문자로서의 <와 >를 나타낼 때는

&lt; (less than)&gt; (greater than)으로 나타내야 한다.)

 


16. 조건문

https://youtu.be/wjlbT3hvDMc

 

 

위 코드를 보면 프로그램이 순차적으로 실행되었다고 가정했을 때 모두 출력되었어야 할 1-2-3-4가

if(true)문의 영향으로 3이 생략되어 출력된 것을 볼 수 있다.

즉, 조건문은 프로그램의 실행 순서에 영향을 준다.

 

조건이 들어가는 소괄호 () 안에 false를 입력하면 else 안의 코드가 실행되는 것을 볼 수 있다.

 

JS에서의 조건문은 이와 같은 형식으로 실행된다.

 


17. 조건문의 활용

https://youtu.be/Gt2iGEEKXww

 

 

앞선 주차 정리에서 사용되었던 day-night 전환 버튼 예제를 조건문을 통해 개선해 보려고 한다.

목표는 분리되어 있는 두 개의 버튼을 하나로 줄이고, 토글 기능이 추가되도록 하는 것이다.

토글 기능이 들어갈 세 번째 버튼을 만들었다. onclick 속성에 JS로 if문을 작성하여 (조건 부분은 비워둔 채로) night와 day에 해당하는 실행문들을 넣었다. 두 케이스는 night와 day라는 value를 통해 대표될 것이다.

 

그러면 현재 버튼이 night와 day 중 어떤 value를 띠고 있는지는 무엇을 통해 알 수 있을까?

개발자 도구에서 콘솔을 통해 알아보자면,

document.querySelector('#night-day').value

와 같은 문장을 사용하면 된다. 아이디가 #night-day인 요소의 value를 알아내자는 것이다.

콘솔에서 실행하면 night라고 뜬다. 현재 버튼의 value가 night라는 뜻이다.

 

이 점에 착안해서, 위의 if문의 조건에 무엇이 들어가야 할지 알 수 있다.

document.querySelector('#night-day').value === 'night'

와 같이 설정하여, true인 경우에는 night 모드가, false인 경우에는 day 모드가 발동되게 해 주면 된다.

 

 

그런데 문제가 있다. 만든 버튼을 눌러 나이트 모드가 되게 하는 것까지는 정상적으로 작동하지만,

이를 한 번 더 눌러서 데이 모드가 되는 기능까지는 아직 작동하지 않는다.

그러면 어떻게 하면 될까? value가 night일 때 실행되는 문장에

버튼의 value를 day로 바꾸는 문장을 넣어주면 된다.

반대쪽 케이스에는 day를 다시 night로 바꾸는 문장을 넣어주면 토글이 구현된다.

 

나이트 모드일 때는 버튼이 day가 된다. 데이 모드일 때는 그 반대.


18. 리팩토링 중복의 제거

 

https://youtu.be/vwRkFRke7ls

 

리팩토링: 코딩이 완료된 후 기존의 코드와 기능은 같게 두되 코드를 조금 더 효율적으로 만들어 유지보수하는 작업

 

소프트웨어가 커지고 복잡해지면 틈틈이 리팩토링을 해 주어야 좋은 프로그램을 만들 수 있다

 

리팩토링의 예로는 어떤 것들이 있는지 보자.

위에 만들었던 나이트/데이 버튼이 밑에서도 보이게끔 하고 싶으면 위의 코드를 그대로 아래에 복사 및 붙여넣기하면 된다. 하지만 이렇게 해서 만든 버튼은 올바르게 작동하지는 않는다. 토글 기능 자체는 작동되지만, 버튼에 표시되는 이름도 나이트/데이로 바뀌어야 하는데 그러지 않고 있기 때문이다.

 

원인은 같은 아이디를 가진 버튼이 두 개 있기 때문이다. (선택자를 배울 때 같은 아이디를 가진 개체가 두 개 이상 있으면 안 된다고 했던 이유도 이러한 맥락일 것이다.) 때문에 value를 바꾸면 바뀌는 것은 위에 있는 버튼의 value이다.

해결을 위해서는 아래쪽 버튼의 id를 다르게 해주면 된다.

 

아래쪽 버튼의 id를 night-day2로 바꾸었다. 버튼의 이름이 정상적으로 바뀌는 것을 확인할 수 있다.

 

개선할 점은 더 있다. 코드가 너무 길다. 자기 자신의 아이디를 가리키는 데 일일이 document.querySelector('#night-day2') 라는 표현을 사용하고 있으니 코드가 쓸데없이 길어질 수밖에 없다.

태그 안에서 객체가 자기 자신을 지칭할 때는 쓸 수 있는 1인칭 대명사가 따로 있다.

this이다.

 

코드를 우측처럼 바꾸었지만 여전히 잘 작동한다.

훨씬 보기가 낫다. 이렇게 하면 사실상 id도 필요가 없어진다. (외부에서 해당 태그를 지칭하는 일이 현재로선 없기 때문에)

자기 이름이 무엇이 됐든 사람들에게 자신을 소개할 때는 누구든 '나'나 '저'라고 하지 않던가.

 

개선한 코드를 위쪽 버튼이 있는 자리에도 똑같이 복붙해 주었다.

그런데 이 코드에는 아직도 중복이 남아 있다. document.querySelector('body') 이다.

이건 어떻게 제거하면 될까?

 

간단하다. 우리가 평소에 C 등의 언어를 가지고 코딩할 때는 특정 값을 변수로 지정하여, 그 값을 불러낼 때마다 변수의 이름을 사용했다.

여기에서도 마찬가지이다. var target = document.querySelector('body'); 와 같이 해당 값을 아예 변수로 지정해 버리고,

원래 그 값이 들어 있던 자리를 모두 변수 이름으로 대체하면 아래와 같이 된다.

 

훨씬 간결하고 좋은 코드가 되었다. 기능은 기존과 동일하게 동작하므로,

개선 후의 코드가 명백히 더 좋은 코드임은 이견의 여지가 없을 것이다.

 


19. 반복문 예고 ~ (20. 배열) ~ 21. 반복문

https://youtu.be/ANDqF-NlWqQ

https://youtu.be/aBJzzhQ6y-o

https://youtu.be/ZupPmuWPSdE

 

 

배열

JS에서의 배열도 여타 언어에서의 배열과 유사하나, 몇 가지 익혀두어야 할 점이 있다.

  • 변수를 배열로 만들기 위해 변수명 뒤에 대괄호를 붙여 주지 않아도 된다.
  • (대신 초기화 시에 원소들을 중괄호 대신 대괄호 안에 넣어 주어야 한다.)
  • 배열 인덱스는 여타 언어와 마찬가지로 0번부터 시작한다.
  • 별도의 라이브러리를 가져오지 않아도 .length를 통해 배열 원소의 갯수를 알 수 있다.

 

배열에 원소를 더할 때는 (배열이름).push('넣을 데이터'); 와 같은 양식으로 추가한다.

이는 스택에서와 같이 배열의 끝부분에 데이터를 하나씩 추가하는 기능이다.

 

+ JS도 여타 언어와 마찬가지로 어떤 명령문의 결과는 그 명령문이 프로그램 내에서 나타난 시점에 따라 결정되므로

위의 예시에서 만약 add하기 전에 count했다면 add가 성공적으로 이루어졌더라도 .length가 4가 아닌 2로 나온다.

 

 

 

반복문

JS에서의 반복문도 여타 언어에서의 반복문과 같다. 반복문, 조건, 반복할 실행문이 있으면 된다.

위의 예시는 i라는 변수를 통해 특정 문장을 3번 반복하도록 코딩한 결과이다.

배열과 반복문을 결합하는 JS 코드에 대해서는 다음 주차에서부터 알아보도록 하겠다.

9~11. CSS 기초 : style 속성 ~ 선택자

https://youtu.be/HQgNj50Xt9g

https://youtu.be/H2eMtredsK4

https://youtu.be/GCtWMXc-rtw

 

CSS 문법에 대해서는 이전 주차 정리에서 학습한 바 있다.

때문에 JS 파트에서는 (강사님 말씀대로, 요지가 CSS가 아니기 때문에)

복습 차원에서 중요한 개념들만 요약 정리해 보려 한다.

 

 

1. CSS는 태그에 style 속성을 넣고 거기에 값을 부여하여 삽입할 수 있다.

style 태그와 CSS는 html에 디자인 요소를 부여할 때 사용한다.

 

2. <div> 태그는 어떠한 의미도 기능도 없으나, JS나 CSS 속성을 부여하고 싶을 때

그러한 속성값을 부여하는 단위로써 html 코드를 분할해 주는 역할을 수행할 수 있다.

(JS나 CSS가 기본적으로 '태그'라는 매개체를 통해 부여된다는 사실을 생각하면

<div> 태그는 굉장히 유용하고 범용성 있는 것이다.)

 

2-1. <div> 태그는 display: block 속성이 기본적으로 있는 태그이기 때문에 (CSS 정리 참고)

태그 안에 있는 요소가 한 줄을 통째로 차지하게 하며, 자동 줄바꿈을 만든다.

이러한 변동을 원하지 않는다면 <span> 태그를 div 대신 사용할 수도 있다.

 

3. 모든 태그에 일일이 <style> 속성을 부여하는 것보다는

속성을 부여하고 싶은 부분들에 span이나 div 등의 태그를 준 다음

head에서 <style> 태그를 써서 CSS 코드를 쓰는 것이 편하다.

 

4. CSS는 태그 단위/클래스 단위/아이디 단위로 부여할 수 있다.

이렇게 CSS를 부여하는 단위를 선택자라고 한다.

선택자는 종류에 따라 우선순위가 있으며,

종류가 같으면 코드 상에서 아래쪽에 적을수록 더 높은 우선순위가 주어진다.

 

4-1. 태그 선택자는 단순히 태그 이름만을 선택자로 사용하면 되며, 

모든 선택자 중 가장 우선순위가 낮다.

 

4-2. 클래스 선택자.(클래스 이름) 과 같은 형식으로 적는다.

태그 선택자보다 우선순위가 높으며, 여러 태그에 부여하는 것이 가능

'그룹핑' 목적으로 보통 사용한다.

 

4-3. 아이디 선택자#(아이디 이름) 과 같은 형식으로 적는다.

클래스 선택자보다도 우선순위가 높으나,

코드 내에서 해당 아이디를 가진 태그는 단 하나뿐이어야 한다.

(문법적 오류는 나지 않지만 암묵적 사용 규칙이 그러하다.)

태그에 달아줌으로써 그 태그를 '식별' 하는 데 그 목적이 있다.


12. 제어할 태그 선택하기

https://youtu.be/5tqfbgfA1LY

 

 

배웠던 것을 이용해서 데이 모드/나이트 모드를 전환할 수 있는 버튼을 구현해 보자.

 

먼저 input 태그의 버튼을 이용해서 value가 나이트인 버튼과 데이인 버튼을 만들어 주었다.

이 버튼들이 실제로 화면의 디자인 요소를 바꿀 수 있도록 하려면

바꿀 디자인 요소를 웹브라우저가 선택할 수 있도록 만들어야 한다.

 

검색어: javascript select tag by css selector

 

검색해 보면 document.querySelector(' ')라는 속성을 찾을 수 있다.

이 값을 onclick 속성을 이용해서 넣어 주면 클릭했을 때 해당 값이 적용이 될 것이다.

속성 변경의 대상이 될 요소(태그)는 body, 바꿔줄 속성은 style 태그(css)의 backgroundColor, 값은 black이다.

양식에 맞게 입력해 주면 night 버튼을 눌렀을 때 배경이 검게 변하는 것을 볼 수 있다.

같은 방법으로 글씨도 희게 해 주자.

 

야간 모드를 선택했을 때 보이는 화면이 완성되었다.

같은 내용을 복사해서 day 버튼에 속성으로 붙여넣기해 주고, 배경은 black, 글씨는 white로 지정해 주면 day 버튼도 구현된다.

 

 

 


13. 프로그램, 프로그래밍, 프로그래머

https://youtu.be/p71PrgY0bbM

  • JS는 컴퓨터 언어이며 컴퓨터 프로그래밍 언어이다
  • HTML은 컴퓨터 언어이지만 컴퓨터 프로그래밍 언어는 아니다.
  • -> 차이점은?

 

프로그램이라는 말에는 '순서'라는 의미가 자리잡고 있다

순서를 만드는 행위 = 프로그래밍, 순서를 만드는 사람 = 프로그래머

 

컴퓨터가 특정한 동작을 시간에 따라 순서대로 실행하게 하도록

행위와 그 순서를 적어 입력하는 것이 '프로그램'

 

때문에 웹페이지를 단순히 '묘사' 할 뿐인 html은 프로그래밍 언어라고는 할 수 없고

시간의 순서에 따른 동작을 지시하는 JS는 프로그래밍 언어라고 할 수 있는 것

이 점이 html와 JS의 차별점.

 

시간이 지남에 따라 사람들은 단순한 순차적 실행뿐만이 아닌

조건에 따라 달라지는 실행, 혹은 반복 등의 실행 제어를 프로그램을 통해서 이뤄내고 싶어하게 됨

-> 조건문, 반복문, 함수 등의 고안으로 이어짐.


14. 조건문 예고

https://youtu.be/UT2oYysmZjE

 

특정 조건에 따라서 다른 순서와 기능이 작동하도록 하고 싶다

-> 조건문을 활용

 

ex) 데이/나이트 모드에 토글을 구현하고 싶다

(같은 버튼이 현재 선택된 모드에 따라서 데이/나이트로 기능을 바꿀 수 있게끔)

-> 조건문을 통해 현재 선택된 모드(데이/나이트)를 인식하고

버튼의 모양과 기능이 바뀌게끔 하기

1. 수업 소개

https://youtu.be/dPRtcRwKo-Y

Javascript 수업 역시도 CSS와 마찬가지로 HTML에 의존하고 있다.

 

CSS와 마찬가지로 JS도 HTML만으로는 만족하지 못한 인간의 욕망에 기인한다

: CSS가 웹페이지를 보기 좋게 꾸미고 싶다는 욕망에서 비롯되었다면

JavaScript는 사용자와 상호작용하는 웹페이지를 만들고 싶다는 욕망에서 왔다

 

HTML은 정적이다. 한번 출력되면 그 모습이 그대로 간다

반면 다른 응용 프로그램들은 사용자의 조작에 반응해 화면이 움직인다.

'웹도 여타 프로그램처럼 사용자와 상호작용할 수 없을까?' -> JavaScript 탄생

 

HTML로 만들어진 웹페이지에 + JavaScript를 결합함으로써

HTML의 정보와 JS의 기능이 양립하는 웹 시스템이 탄생함

(사용자와 상호작용하면서도 + 검색엔진을 통해 공유될 수 있다. 이는 웹만의 특징.)

멈춰 있는 HTML의 정보라는 이미지를 영상처럼 움직이게 한다.

 


2. 수업의 목적

https://youtu.be/q4c69koKcOc

하나의 문법을 쭉 배우기보다는, 필요한 기능을 구현하는 과정에서

그 구현에 필요한 문법을 챙겨 배우는 수업. 실습이 중심이 되고 문법이 부가적으로 따라올 것이다

 

ex) 웹페이지의 나이트/데이 모드 전환.

해당 기능이 구현된 웹사이트를 개발자 도구로 살펴보면 나이트/데이 버튼을 누를 때마다

배경색과 글자색 등을 표현해주는 엘리먼츠(태그) 내용이 바뀌는 것을 볼 수 있다

 

CSS가 <style> 태그, 또는 속성의 값이 되었듯

JavaScript는 onclick 등의 속성에 값이 된다

위의 경우처럼 사용자가 버튼을 클릭한다고 하면 그에 맞는 '동작'이 일어날 것이고

그 동작을 기술하는 언어가 JavaScript인 것.

 

=> 'JavaScript는 HTML을 제어하는 언어다'

JS는 HTML을 제어하여 동적으로 기능하도록 만들고, 그것이 우리가 JS를 사용하는 목적이다

 


3. HTML과 JS의 만남 : script 태그

https://youtu.be/Ru5zGHkOgic

완전히 다른 문법을 가지고 있는 HTML과 JS를 어떻게 접목시킬 것인가?

 

: <script> 태그

JS 코드를 감싸는 태그. body 안에 넣는다. html에서 이 태그 안에 있는 것은 JS 코드로 취급한다.

 

간단한 예를 보자. 위는 똑같은 'hello world' 를 html과 js로 각각 적어놓은 것이다.

이렇게 보면 별 차이가 없어 보이기도 한다. 그러나...

 

이렇게 적으면 차이가 확실히 보인다. 같은 1+1을 적었음에도 html은 문자 그대로 '1+1'을, JS는 2를 출력했다.

즉, html은 정적이며, JS는 동적이다.

 


4. HTML과 JS의 만남 : 이벤트

https://youtu.be/-hdtrReY9Zw

 

이벤트(event) : 웹브라우저 위에서 일어나는 일들.

 

위 js 코드는 hi라는 이름(value)을 가진 버튼을 만들고,

그 버튼을 클릭하면 'hi'라는 내용의 경고(alert)가 뜨도록 하는 코드이다.

 

저 코드는 컴퓨터 혼자 인식하고 임의로 실행 시점을 결정하는 것이 아니다.

코드가 입력되면 기억해 두었다가, 사용자가 코드 실행에 필요한 조건(클릭)을 발생시키면

그때 '경고창을 발생시킨다'는 코드를 실행하는 것이다.

이러한 event가 일어났을 때 필요한 JS 코드를 실행하는 것이 위 코드에서 onclick이 수행하는 기능이다.

 

JS 코드를 발동시킬 수 있는 이벤트 중에서는 이런 것도 있다.

위는 input type="text"로 텍스트를 입력할 수 있는 창을 만든 것으로,

저 입력 창에 텍스트를 입력해 추가하거나 이미 입력된 내용을 삭제하는 등

'기존에 입력된 내용에 변화가 있다면'(event) changed라는 alert를 띄우는 코드이다.

onchange라는 속성을 이용해 만들었다.

 

이런 예시도 있다. 똑같이 텍스트 입력 창을 만든 뒤 거기에 onkeydown 속성을 부여하면

텍스트 창을 선택한 뒤 키보드의 아무 키나 눌렀을 때 key down이라는 alert가 발생한다.

 

이렇듯 on으로 시작되는 속성들은 웹브라우저상의 특정 event를 트리거 삼아

값으로 가지고 있는 코드를 발동시킨다.


5. HTML과 JS의 만남 (콘솔)

https://youtu.be/-VKIqaEdDVU

꼭 웹페이지를 만들어야만 JS 코드를 실행할 수 있는 것은 아니다.

가볍고 짧은 코드를 즉석에서 실행해 보고자 할 때는 콘솔(console)이라는 것을 이용해 볼 수도 있다.

 

웹페이지에서 우클릭 > 검사로 개발자 도구를 연 뒤에 콘솔 탭으로 들어간다.

빈 입력 창에 아무 텍스트나 입력한 뒤 그것을 ' '로 감싸면 문자열이 된다.

뒤에 .length를 붙여주면 해당 문자열의 길이를 구하는 코드가 된다.

그리고 그 코드 전체를 ( )로 감싸준 뒤에 앞에 alert를 입력하면 해당 코드의 결과를 경고창에 띄울 수 있을 것이다.

 

 

문자열의 길이인 106이 경고창에 출력되었다.

 

이 콘솔이란 것은 다른 사람이 만든 기존 웹페이지에서도 열 수 있어서,

코드만 있다면 웹페이지에서 JS를 이용해 필요한 기능을 사용하고 정보를 취할 수 있다.

SNS 페이지에서 댓글을 단 사람 중 n명을 추첨하는 등의 기능이 그 예시이다.

 

이와 같이 간단하고 간이적인 기능을 웹페이지에 적용하고 싶을 때는 콘솔을 이용하는 것이 좋은 선택이 될 수 있다.

 


6. 데이터타입 - 문자열과 숫자

https://youtu.be/P8C8VNiM33A

JS에서 다루는 데이터 타입 중 우리에게 익숙한 것은 문자열(string)숫자로 크게 두 가지가 있다.

 

JS는 정수(음수 포함), 실수 등의 표현이 가능하고 이항 산술 연산자의 사용이 가능하다.

(실험해본 바, 무한대 개념도 지원한다(!) 특정 수를 0으로 나누면 Infinity가 출력되고

Infinity 역시 평범한 수처럼 사칙연산을 할 수 있다.)

 

JS에서 문자열은 " "나 ' '로 둘러싸인 문자 집합을 의미한다. 뒤에 .을 붙이고 여러 가지 함수를 사용할 수 있는데,

.length는 문자열의 길이 출력을, .toUpperCase()는 대문자 변환을, .trim()은 문자열 앞뒤의 공백 제거를 지원한다.

이외에도 대상 문자(열)이 몇 번째 인덱스부터 시작하는지 구해 주는 .indexOf() 등

다양한 함수로 문자열을 다룰 수 있다.


7. 변수와 대입 연산자

https://youtu.be/absJhWQAS40

 

JS에서도 다른 프로그래밍 언어에서와 마찬가지로 변수를 사용할 수 있다.

변수 선언은 var (변수명) = (대입값); 형태로 이루어진다.

 

문자열 속에서 변수를 사용하기 위해서는 변수가 들어갈 부분을 " "로 감싸고,

그 안에 +(변수명)+ 과 같은 형식으로 적어주면 된다.

 


8. 웹브라우저 제어

https://youtu.be/S62m_ddSls4

위에서 봤던 예시대로, 웹에서 night/day 모드가 동작하기 위해서는

버튼을 누르면 -> 거기에 반응하여 시각적인 요소가 바뀌는 원리가 기능해야 한다.

즉, 이 기능을 구현하기 위해 우리가 해내야 할 것은 두 가지다.

 

1. CSS의 기본적인 문법을 안다 (style 태그를 이용해 태그에 특정한 디자인적 요소를 준다)

2. JS를 통해 이를 제어한다 (이벤트에 따라 태그에 들어간 속성값 등의 상태가 변하게끔 한다)

 

구체적인 방안은 다음 시간부터 알아볼 것이다.

'WEB > 정리' 카테고리의 다른 글

WEB 기초 6주차 정리 - JavaScript 15 ~ 21  (0) 2022.05.28
WEB 기초 5주차 정리 - JavaScript 9~14  (0) 2022.05.20
WEB 기초 3주차 정리 - CSS 1~9  (0) 2022.05.07
WEB 기초 2주차 정리  (0) 2022.04.30
WEB 기초 1주차 정리  (0) 2022.04.03

+ Recent posts