-
HTML & FORM
HTML은 화면을 구성하는 태그들과 사용자의 입력을 받아 서버로 전송을 하는 FROM 구성요소로 크게 구분을 할 수 있습니다.
FROM 구성요소들은 서버로 데이터를 전송을 하는데, PHP는 이런 전송된 데이터를 받아서 처리를 할 수 있습니다.
17.1 FORM
HTML의 FORM 태그는 폼요소들을 감싸고 있는 바디 부분과 그 안에 들어가는 요소들의 항목으로 구분을 할 수 있습니다.
17.1.1 FORM 태그
HTML에서 <form></form>으로 마크업이 되어진 코드를 form 테그라고 합니다. 폼테그는 폼요소들을 포함하는 바디와 같습니다.
폼 요소들은 폼 태그로 둘러 쌓여져 있어야 합니다.
폼 태그는 몇개의 속성 설정을 같이 설정할 수 있습니다.
name
폼의 이름을 지정합니다.
method
매소드 속성은 입력된 데이터의 전송방식을 설정합니다. POST 방식 또는 GET 방식으로 지정할 수 있습니다. 만일 POST 방식으로 설정을 하였다면, 서버쪽 PHP에서는 슈퍼변수 $_POST 배열을 통해서 데이터를 가지고 올 수 있습니다.
GET 방식으로 설정을 하였다면 슈퍼변수 $_GET 배열을 통해서 데이터를 읽어 올 수 있습니다.
action
엑션 속성은 해당 폼을 처리하는 PHP 스크립트의 url과 파일명을 지정합니다. 폼이 서브밋 처리가 되면 액션에서 지정한 속성으로 페이지가 이동이 되면서 데이터를 처리합니다.
enctype=”multipart/form-data”
파일 업로드와 같이 바이너리 데이터를 전송할 경우에 추가되는 속성입니다.
17.1.2 Action
폼 태그의 속성중 action 은 서브밋 클릭시 처리되는 스크립트 페이지 입니다. 전형적인 HTML 코딩에서는 직접 url과 스크립트 명을 입력합니다.
"; ?> 화면출력) 다양한 타입속성 HTML5의 input은 좀더 많은 다양한 타입속성을 지원합니다. 타입 속성을 이용하면 데이터 입력시 발생할 수 있는 오류들을 먼저 브라우저 차원에서 필터링 할 수 있습니다. email url search tel number date datetime month week time range color 필수체크 HTML5 에는 폼의 필수 입력을 확인하는 속성인 required 가 입니다. 하지만 이 속성은 브라우저에서만 동작하는 속성입니다. 브라우저 이외의 방식으로 접속을 할경우에는 필수체크를 할 수 없습니다. 이런경우 PHP 소스상에서 다시한번 필수 체크해 주는 것이 중요합니다. 입력값 제한 HTML5는 브라우저에서 입력 문자열의 길이를 제한할 수 있습니다. input 테그의 속성으로 maxlength=”값” 을 추가하시면 됩니다. maxlength의 입력 제한 동작은 브라우저에서만 동작을 합니다. 브라우저를 제외한 방법으로 접속하여 데이터를 전송할때는 maxlength 적용을 받지 않습니다. 입력패턴 HTML5의 입력패턴 속성을 통하여 데이터 형식을 제한할 수 있습니다. 패턴 속성과 정규표현방법을 통하여 입력되는 데이터를 필터링 합니다. <input type="password" name="passwd" pattern=”[0~9A-Za-z]”> 최대, 최소 HTML 5에서는 min 또는 max 속성값을 통하여 입력되는 데이터의 최소치와 최대치를 지정할 수도 있습니다. 초기값지정 input 의 텍스트 속성을 사용시 사용자에게 보여주는 초기값 및 기본값을 미리 출력해서 보여줄 수 있습니다. 초기값은 약간 흐린 회색계열의 문자로 출력함으로서 사용자 입력값과 구분을 합니다. <input type="text" name="username" placeholder=”이름을 입력해 주세요”> 자동완성 추천 검색엔진이나 특정 값을 입력할때 하단에 추천하는 단어들을 나타내는 경우를 보신적이 있을 것입니다. HTML5의 autocomplete 기능을 이용하면 쉽게 구현을 하실 수 있습니다. <input type="text" name="country" placeholder=”국가를 입력 입력해 주세요” autocomplete=”on” list=”local”> <datalist id=”local”> <option value=”대한민국”> <option value=”미국”> <option value=”일본”> </datalist> 17.2.2 hidden ==================== text 속성은 브라우저 화면에 사용자 입력 박스를 출력합니다. 그와 반대로 hidden 속성은 서버로 데이터를 전송을 하는 값 이지만, 화면에는 출력되지 않습니다. 즉, 숨겨진 text 속성과 같습니다. <input type="hidden" name="mode" value=”editup”> 17.2.3 textarea ==================== HTML teatarea 요소는 input 요소와 달리 많은 양의 텍스트를 입력받을 수 있습니다. textarea는 웹페이지에서 글을 작성하는 본문등 많이 이용을 합니다. textarea는 많은 양과 다양한 입력을 고려하여 데이터안에 숨겨진 기호나 패턴등을 복합적으로 판별을 해야 합니다. 예제파일) form_textarea.php "; // 다음줄 nl을로 변환하여 출력함. echo "comment=
" . nl2br($_POST['comment']); echo "
==========
"; } // HTML form을 출력합니다. echo ""; ?> 화면출력) 17.2.4 select ==================== select 요소는 input 요소 다음으로 가장 많이 사용하는 html form 구성입니다. select는 드롭다운 형태로 여러개의 데이터 값중에 한개 또는 다수의 데이터를 선택할 수 있습니다. 예제파일) form_select1.php "; echo "country = " . $_POST['country'] ."
"; echo "==========
"; } // HTML form을 출력합니다. echo ""; ?> 화면출력) select는 기본적으로 선택한 한개의 값을 지정할 수 있습니다. 하지만 여러개의 항목을 선택이 필요한 경우에는 <select multiple name=”이름[]”> 형태로 이름을 배열 형태로, multiple 속성을 사용하면 됩니다. 예제파일) form_select2.php "; $COUNTRY = $_POST['country']; for($i=0;$i
"; } // HTML form을 출력합니다. echo ""; ?> 화면출력) 17.2.5 checkbox ==================== 폼요소중 체크박스는 어떠한 항목에 동의등을 구할때 많이 사용을 하는 구성요소 입니다. 위와 같이 HTML 코드입력하면 form의 데이터는 슈퍼변수 $_GET[] 또는 $_POST[] 배열 변수를 통해서 값을 가지고 올 수 있습니다. 이때 지정한 name=”이름” 값의 배열의 선택 키값으로 사용이 됩니다. 만일 체크박스의 초기값을 “선택된” 으로 하고자 할때는 checked 키워드를 추가해 주면 됩니다. 체크박스가 선택된 값은 on 문자열 값으로 전달됩니다. 예제파일) form_check1.php "; echo "agree = " . $_POST['agree'] ."
"; echo "adult = " . $_POST['adult'] ."
"; echo "==========
"; } // HTML form을 출력합니다. echo ""; ?> 화면출력) 위의 실험1은 체크박스가 하나에 한개의 이름으로 각각의 할당되어 있습니다. 다음 예제는 체크박스 이름을 배열형태로 지정후에 value 속성을 이용하여 값을 할당합니다. 예제파일) form_check2.php "; $TID = $_POST['TID']; for($i=0;$i
"; } // HTML form을 출력합니다. echo ""; ?> 화면출력) 실험2에서 체크박스는 TID라는 이름의 배열로 작성되어 있습니다. 또한 각각의 체크박스는 value 속성을 통하여 고유 값들을 가지고 있습니다. 서브및 을 통하여 PHP로 값이 전달되어진 경우, 배열로 체크박스는 배열 형태로 값을 전달 받게 됩니다. 선택한 체크박스의 값만을 배열화 하여 전달합니다. 이러한 유형은 리스트목록등에서 여러개의 데이터를 선택하여 FORM 으로 전달하는 용도로 많이 사용을 합니다. 17.2.6 radio box ==================== HTML의 라디오 요소는 여러개의 선택값중에 하나만 입력을 받을 수 있는 요소입니다. Female Male 라디오 버튼의 name=”이름” 부분은 동일한 값을 가집니다. 하지만 속성값은 각각의 다른 값을 가지게 됩니다. 예제파일) form_radio.php "; echo "sex = " . $_POST['sex'] ."
"; echo "==========
"; } // HTML form을 출력합니다. echo ""; ?> 화면출력) 17.2.7 file ==================== 메일 작성이나 계시판에 글과 함께 첨부하는 파일등을 지정하여 서버로 전송을 할 수 있습니다. 클라이언트 브라우저에서 서버로 파일을 전송하기 위해서는 form 의 type=”file”을 사용하면 됩니다. HTML에서 파일전송을 위해서는 전송 매소드 타입이 POST로 되어 있어야 합니다. 또한, 바이너리 데이터를 같이 전송하기 위해서 속성 enctype="multipart/form-data" 가 같이 설정되어야 합니다. HTML의 file요소를 선택하시면, 컴퓨터는 서버로 전송할 파일을 선택하는 팝업창을 브라우저가 실행을 시킵니다. 또한 PHP에서 파일을 업로드하여 전송을 하기 위해서는 약간의 php.ini 환경설정이 필요로 힙니다. php.ini 파일에서 file_uploads 부분을 ON 으로 변경을 해주어야 합니다. file_uploads = On 또한 파일 용량도 제한도 가능합니다. 보다 자세한 것은 환경설정 부분을 참조해 주세요. 예제파일) form_upload.php "; print_r($_FILES['upload']); echo "
"; // 업로드 디렉토리 지정 $target_dir = "./uploads"; if(!is_dir($target_dir)){ mkdir($target_dir); } $target_file = $target_dir . "/". basename($_FILES["upload"]["name"]); echo "저장파일명 = ". $target_file ."
"; $uploadOk = true; // 업로드 할 파일이 존재하는지 검사 if (file_exists($target_file)) { echo "이미 존재하는 파일명입니다."; $uploadOk = false; } // 파일 사이즈 제한 if ($_FILES["upload"]["size"] > 500000) { echo "파일 사이즈가 너무 큽니다."; $uploadOk = false; } // 파일 등록 및 복사 if ($uploadOk) { if (move_uploaded_file($_FILES["upload"]["tmp_name"], $target_file)) { echo basename( $_FILES["upload"]["name"]). " 를 업로드 하였습니다."; } else { echo "파일 업로드 오류"; } } else { echo "죄송합니다. 파일등록을 할 수 없습니다."; } echo "
==========
"; } // HTML form을 출력합니다. echo ""; ?> 화면출력) 위의 파일 업로드 실험은 클라이언트의 웹브라우저에서 서버로 파일을 전송합니다. form의 file 요소로 파일을 선택하여 전송합니다. 서버의 PHP에서는 $_FILES 배열 변수로 파일의 정보를 받아 올 수 있습니다. $_FILES 배열에는 파일의 관련된 다양한 값의 정보를 가지고 있습니다. 또한 전송받는 파일은 임시폴더 안에 저장이 됩니다. move_uploaded_file() 함수를 통하여 실제 저장 장소로 이등을 합니다. 파일을 이동시에는 파일의 정보와 저장 디렉토리, 용량등을 사전에 체크하여 필터링할 수 있습니다. 17.3 다운로드 ==================== 서버상에 있는 파일을 사용자 PC에 다운로드 할 수 있도록 링크를 생성할 수 있습니다. 서버상의 파일을 간단하게 다운로드 받는 방법은 header() 함수를 통하여 브라우저에 header 를 설정하여 전송하는 방법입니다. |내부함수| void header ( string $string [, bool $replace = true [, int $http_response_code ]] ) 내부함수 header() 함수는 사용자 브라우저로 데이터를 전송합니다. header() 함수는 다른 HTML 코드보다 우선적으로 실행이 되어야 합니다. 예제) download.php ', '{', '}', ':', ';', '|', '"', '~', '`', '@', '#', '$', '%', '^', '&', '*', '?'); $replace = array('', '', '(', ')', '(', ')', '_', ',', '_', '', '_', '\'', '_', '_', '_', '_', '_', '_', '', ''); $filename = str_replace($illegal, $replace, $filename); $filename = preg_replace('/([\\x00-\\x1f\\x7f\\xff]+)/', '', $filename); // 유니코드 공백 문자를 일반 공백 문자(0x20)로 변경을 합니다. $filename = trim(preg_replace('/[\\pZ\\pC]+/u', ' ', $filename)); // 중복된 점, 대체문자를 정리합니다. $filename = trim($filename, ' .-_'); $filename = preg_replace('/__+/', '_', $filename); if ($filename === '') { die("파일명 이름 변환처리 실패"); } // 브라우저의 User-Agent 값 처리 USER_AGENT = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : ''; $old_ie = (bool)preg_match('#MSIE [3-8]\.#', $USER_AGENT); // 브라우저별 해더 파일명을 정리합니다. if (preg_match('/^[a-zA-Z0-9_.-]+$/', $filename)) { // 파일명에 숫자와 영문으로만 된경우 // 브라우저 상관없이 파일명을 해더로 처리를 합니다. $header = 'filename="' . $filename . '"'; } elseif ($old_ie || preg_match('#Firefox/(\d+)\.#', $USER_AGENT, $matches) && $matches[1] < 5) { // IE 9 미만 , Firefox 5 미만의 경우 처리. $header = 'filename="' . rawurlencode($filename) . '"'; } elseif (preg_match('#Chrome/(\d+)\.#', $USER_AGENT, $matches) && $matches[1] < 11) { // Chrome 11 미만의 경우. $header = 'filename=' . $filename; } elseif (preg_match('#Safari/(\d+)\.#', $USER_AGENT, $matches) && $matches[1] < 6) { // Safari 6 미만의 경우. $header = 'filename=' . $filename; } elseif (preg_match('#Android #', $USER_AGENT, $matches)) { // 안드로이드 브라우저의 경우. $header = 'filename="' . $filename . '"'; } else { // RFC2231/5987 표준 준수 $header = "filename*=UTF-8''" . rawurlencode($filename) . '; filename="' . rawurlencode($filename) . '"'; } // 캐쉬처리 // 캐쉬 처리를 위해서 Cache-Control, Expires 등의 헤더를 적용합니다. if (!$expires) { // 캐싱 금지 if ($old_ie) { // 익스플로러 8 이하 버전 // SSL 사용시 no-cache 및 pragma 헤더 오류를 발생 header('Cache-Control: private, must-revalidate, post-check=0, pre-check=0'); header('Expires: Sat, 01 Jan 2000 00:00:00 GMT'); } else { header('Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0'); header('Expires: Sat, 01 Jan 2000 00:00:00 GMT'); } } else { // 캐싱 허용 header('Cache-Control: max-age=' . (int)$expires); header('Expires: ' . gmdate('D, d M Y H:i:s', time() + (int)$expires) . ' GMT'); } // 다운로드 이어받기 해더처리 // Range 헤더 자동 감지, Accept-Ranges 헤더 자동 생성 if (isset($_SERVER['HTTP_RANGE']) && preg_match('/^bytes=(\d+)-/', $_SERVER['HTTP_RANGE'], $matches)) { $range_start = $matches[1]; if ($range_start < 0 || $range_start > $filesize) { header('HTTP/1.1 416 Requested Range Not Satisfiable'); return false; } header('HTTP/1.1 206 Partial Content'); header('Content-Range: bytes ' . $range_start . '-' . ($filesize - 1) . '/' . $filesize); header('Content-Length: ' . ($filesize - $range_start)); } else { $range_start = 0; header('Content-Length: ' . $filesize); } // 그외 헤더를 전송한다. header('Accept-Ranges: bytes'); header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; ' . $header); // 출력 버퍼를 초기화. // 대용량 파일 다운로드시 메모리 누수를 방지합니다. while (ob_get_level()) { ob_end_clean(); } // 파일을 64KB 단위로 분할 전송 // readfile() 함수의 메모리 누수 방지 $block_size = 16 * 1024; $speed_sleep = $speed_limit > 0 ? round(($block_size / $speed_limit / 1024) * 1000000) : 0; $buffer = ''; if ($range_start > 0) { fseek($fp, $range_start); $alignment = (ceil($range_start / $block_size) * $block_size) - $range_start; if ($alignment > 0) { $buffer = fread($fp, $alignment); echo $buffer; unset($buffer); flush(); } } while (!feof($fp)) { $buffer = fread($fp, $block_size); echo $buffer; unset($buffer); flush(); usleep($speed_sleep); } fclose($fp); ?>