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 (검색어) : 타 사이트 연동 로그인 기능. 사용자의 인증을 타 거대 사이트에 위탁함으로써 안전성과 편리성을 얻는다.

+ Recent posts