메뉴 바로가기 검색 및 카테고리 바로가기 본문 바로가기

한빛출판네트워크

한빛랩스 - 지식에 가능성을 머지하다 / 강의 콘텐츠 무료로 수강하시고 피드백을 남겨주세요. ▶︎

IT/모바일

PHP와 CSS를 사용하여 유효성 검사하기

한빛미디어

|

2004-05-19

|

by HANBIT

25,707

저자: Jeff Cogswell

원문: http://www.onlamp.com/pub/a/php/2004/04/22/php_css_forms.html

PHP 프로그래머가 겪는 일반적인 문제 중의 한가지가 폼 데이터의 유효성을 체크하는 부분이다. 예를 들어, 이메일 주소를 입력하는 폼이 있다. 정규표현식을 사용하여 이메일 주소가 유효한지 체크하고 유효한 형태가 아니라면 다시 입력하도록 한다.

대부분 사람들은 폼 태그의 action 파라미터에 데이터를 처리하는 다른 페이지를 설정해서 코딩을 한다. 그럼, 어디에서 데이터 유효성을 검사해야 할까? 이러한 경우 PHP 프로그래머들은 자바스크립트를 사용하여 클라이언트측(client-side)에서 유효성을 체크한다. 이메일 주소를 체크하는 경우에 자바스크립트로 이메일이 정규표현식에 부합한지 체크하고 잘못되었을 경우 팝업 메시지창을 출력하고 더 이상 진행하지 못하게 한다.

그러나 이 경우에 문제가 있다(프로그램상 문제가 아니라 사용자가 자바스크립트를 꺼두었을 때). 더욱이 오늘날의 웹사이트들은 보통 사용자가 Submit 버튼을 클릭하면, "유효한 이메일 주소를 입력해 주세요". 같은 오류 메시지를 폼 페이지 자체에 출력하고 있다.

이 오류 메시지는 원래의 폼이 있는 페이지에 나타나며 문제가 있는 폼의 항목에 그림 1처럼 빨간색 레이블을 사용하여 표시한다.

그림 1
그림 1. 유효성 오류가 표시된 폼

만약 유효성 검사가 데이터베이스와 연관이 있다면 어떨까? 이 경우에는 서버측(Server-Side)에서 체크해야 한다. 사용자가 Submit 버튼을 클릭하고 사용자이름이 유효하지 않다는 메시지를 리턴하는 경우에 유용하다.

많은 웹사이트들은 이미 이러한 기능을 제공하고 있다. 하지만 이러한 웹사이트들은 종종 .php가 아닌 .asp 또는 .aspx 같은 확장자를 가지고 있다. ASP만이 이러한 기능들을 구현 가능한가? 이 기사를 통해 PHP 폼에 이러한 기능을 구현하는 방법을 보여줄 것이다(ASP 경헙이 없어도 괜찮다. PHP는 훨씬 쉽거든!).

기본 사항

폼 데이터의 유효성을 체크하기 위해서는 위해서는 기본적으로 페이지 처리 흐름을 이해해야 한다. 서버측의 유효성 체크가 없을 경우에는 폼의 action 파라미터를 폼이 있는 페이지가 아닌 다른 페이지에서 요청을 받고 처리하도록 해야한다. 예를 들어, login.php 페이지에 아래와 같은 라인을 포함할 수 있다.

〈form method="post" action="processlogin.php"〉

이런 시나리오에서는 login 페이지는 사용자가 사용자이름과 비밀번호를 입력하는 폼을 가지고 있다. 입력한 사용자이름과 비밀번호가 processlogin.php에 전달되어 데이터베이스에서 사용자이름과 비밀번호를 확인한다. 만약 로그인 정보가 잘못되었다면 processlogin.php 안에 사용자로 하여금 다시 입력할 수 있도록 또 다른 폼을 출력하는 PHP 코드가 필요하다. 아니면 간단히 header 함수를 사용하여 원래의 processlogin.php 페이지로 되돌리면 된다.

좀더 깔끔하게 하는 방법이 있다. 이 경우에는 login.php 페이지 안에 유효성 검사 코드를 넣을 수 있다. 데이터 유효성은 폼과 관련이 있기 때문에 데이터 코드를 폼과 함께 두는 것이 당연하다. Login.php 파일에 다음과 같은 라인이 있다고 해보자.

〈form method="post" action="login.php"〉

action 파라미터는 사용자가 있는 동일한 페이지를 가리키고 있다. 조금은 흥미롭지 않은가? login.php 페이지의 첫부분에서 서버측에서 하는 유효성 체크 코드를 작성한다(물론 페이지가 처음 로드될때에는 유효성 체크를 하지 않도록 해야 한다). 그리고 나서 유효성 검사가 성공했다면 header 함수를 사용하여 다음과 같이 리다이렉트한다.

header("location: loginsucceeded.php");

약간 복잡하지만 일단 기본적인 흐름을 이해한다면 쉽게 처리할 수 있다. 다음으로 이러한 접근법을 실제로 구현하는 방법을 알아보겠다.

샘플 페이지

여기 기본적인 기술을 구현하는 email.php 라는 샘플 페이지가 있다.

이 페이지에서 사용자는 이메일 주소와 이름을 입력한다.

〈?
      $message = "";
      $emailclass = "basictext";
      $username = "";

      if ($_POST["process"] == 1) {

            $pattern = "/.*@.*\..*/";
            $email = $_POST["email"];
            $urlname = urlencode($$_POST["username"]);

            if (preg_match($pattern, $_POST["email"]) 〉 0) {
                  // Here"s where you would store
                  // the data in a database...
                  header(
                     "location: thankyou.php?&username=$urlname");
            }
            $message = "Please enter a valid email address.";
            $username = $_POST["name"];
            $emailclass = "errortext";
      }
?〉

〈html〉
〈style〉
      .basictext {
            font-family: Arial, Helvetica, sans-serif;
            font-size: 14px; color:#000066;
      }
      .errortext {
            font-family: Arial, Helvetica, sans-serif;
            font-size: 14px; color:#C00000; font-weight: bold;
      }
〈/style〉
〈body〉
〈form action="email.php" method="post"〉
      〈? if ($message != "") {
            print "〈span class="errortext"〉".
                  $message."〈span〉〈br〉\n";
      }
      ?〉
      〈span class="〈?print $emailclass; ?〉"〉
            Email address:〈/span〉
      〈input name="email" type="text"
            class="〈? print $emailclass; ?〉"〉〈br〉
      
      〈span class="basictext"〉Your name:〈/span〉
      〈input name="name" type="text" class="basictext"
            value="〈?print $username; ?〉"〉〈br〉
      〈input type="hidden" name="process" value="1"〉
      〈input type="submit" name="Button1" value="Sign up!"〉
〈/form〉
〈/body〉
〈/html〉

동작하는 방법

처음 부분은 처리를 하기 위한 코드이다. 만약 $_POST 배열이 1값을 가진 키값 process를 가지고 있다면 처리를 시작한다. 그렇지 않다면 if문 다음을 진행한다. 풀어서 얘기하면 사용자가 처음 페이지를 오픈하면 if문 안을 처리하지 않는다. 아래쪽에는 값이 1인 히든변수 process를 가진 폼이 있다. 사용자가 submit 버튼을 클릭하면 페이지는 다시 로드되고, 이번에는 if문이 처리된다(노트, isset 함수를 사용하여 $_POST["process"] 값이 존재하는지 미리 체크해 보는 것도 좋다).

처리 절차는 간단하다. 먼저 정규표현식을 사용하여 이메일을 체크한다. 만약 이메일 주소가 정규표현식과 매치한다면 thankyou.php 페이지로 리다이렉트한다. 그렇지 않다면 페이지가 그대로 있고 $message 변수에 값을 저장한다.

다음으로 스타일시트 부분을 살펴보자. 〈head〉 태그 안에 두개의 스타일이 정의되어있다. 하나는 기본적인 텍스트로 검정색이고, 다른 하나는 에러를 표시하기 위한 굵은 빨간색 텍스트이다. PHP 코드에서 $emailclass 변수에 기본적으로 basictext를 저장했다. 유효성 체크가 실패했을 경우 $emailclass 변수값을 errortext로 변경한다. 이메일 주소를 위한 레이블과 텍스트 박스를 작성할 때 $emailclass 변수에 저장된 클래스를 사용하고 있다.

class="〈?print $emailclass; ?〉"〉

정상적으로 처리되면 HTML은 일반적인 텍스트를 출력하고 문제가 있다면 굵은 빨간색 텍스트를 출력한다.

필드에 디폴트 값을 저장해둔 부분을 보자. 처음에는 $username 변수는 빈 스트링을 가지고 있다. 일단 한번 페이지가 처리되어 유효성 검사가 실패한다면 $username 변수에 $_POST["name"] 값을 저장한다(중요: 세션 변수를 사용하지 않을 경우에는 페이지가 처리된 후 더 이상 변수값은 존재하지 않는다). 그래서 다음과 같이 코드 아래 부분의 폼안에 $username 값을 넣었다.

〈input name="name" type="text" class="basictext" value="〈?print $username; ?〉"〉〈br〉

사용자가 잘못된 이메일 주소를 입력해서 폼이 리턴될 때 username은 이미 채워져 있을 것이다. 이러한 기술은 사용자를 편의를 고려한 폼을 만들 때 매우 중요하다. 왜냐하면 사용자가 이메일 주소에서 @ 표시를 빼먹었을 때 폼에 다시 전부 입력하기를 원하지 않을 것이기 때문이다. 이런 경우를 대비해서 사용자가 이전에 입력한 이메일 주소를 이메일 주소 박스에 채워넣었다. 단지 사용자는 잘못된 부분을 확인하고 수정만 하면 된다.

마지막으로, username 값을 다음 페이지로 전달하는 코드 부분을 살펴보자. 먼저 폼에서 POST 메서드를 사용한다는 사실에 유의하자. Password를 전달할 때 일반적으로 POST 메서드를 사용한다. GET 메서드를 사용할 경우에는 URL에 password 값이 노출된다. 다른 사람이 어깨 너머로 보고 있다면 기분 좋은 일은 아니다. 물론 예제에서는 password는 사용하고 있지 않다. 그러나 다른 곳에서 얼마든지 사용할 수 있다. 여기서는 POST 메서드를 사용했다.

다음 페이지(이 경우에 thankyou.php)는 사용자가 입력한 데이터를 접근해야 한다. 데이터를 전달하는 가장 쉬운 방법은 다음처럼 GET을 사용하는 것이다.

header("location: thankyou.php?&username=$urlname");

(공백이나 다른 불필요 문자들을 제거하기 위해 urlencode를 호출했다). POST 메서드 사용의 중요성을 언급했음에도 불구하고 여기서는 GET 메서드를 사용하고 있다. 그러나 이메일 주소는 전달하지 않았다.
이유는 다음 페이지(여기서는 thankyou.php)로 가는 header를 호출하기 전에 처리 코드 안에서 사용자이름과 비밀전호를 저장 또는 처리하기 때문이다. 이미 모든 검증을 마쳤기 때문에 실제 처리를 할 수 있다. 예를 들어, 폼에서 사용자이름이 이미 존재하는지 하지 않는지를 테스트할 필요가 있다. 이미 존재한다면 사용자에게 사용자이름이 이미 존재한다는 메시지를 출력하고 다른 이름을 입력하도록 해야 한다. 존재하지 않는 사용자이름이라면 데이터베이스에 정보를 저장한 후 thankyou.php 페이지를 처리한다.(thankyou.php 페이지에 어떠한 것도 전달하지 않아도 된다. 이런 경우 header 호출 부분에서 ?&username= 부분이 필요가 없다)

가능성(과제)

지금까지 언급한 기술을 사용하여 할 수 있는 것들이 있다. 직접 구현해 보기 바란다.
  • 사용자로 하여금 이메일 주소를 두번 입력하도록 한다. 처리 과정에서 두 이메일 주소가 일치하는지 체크한다. 일치하지 않는다면 오류 메시지를 출력한다.

  • 사용자가 새로운 계정에 가입할 때 사용자이름과 비밀번호가 데이터베이스에 있는지 테스트한다. 사용자 이름이 이미 존재한다면, 데이터베이스에 존재하지 않는 사용자 이름이 있을 때까지 사용자 이름에 임의의 숫자를 더해서 사용자에게 제안한다.

  • 사용자가 요구되는 필드를 비워두었는지를 체크한다. "비어있는 필드를 채워주세요"라는 메시지를 출력하고 비어있는 필드의 레이블을 빨간색으로 출력한다. 단 이전에 사용자가 입력한 필드들은 그대로 채워두어야 한다.

  • 비밀번호의 길이가 요구되는 크기보다 작은지 체크한다. 예를 들어, 만약 8문자보다 작다면 "적어도 비밀번호는 8문자가 되어야 한다"라는 메시지를 출력한다.
이 외에도 더 많은 것들을 구현해 볼 수 있다. 사용자가 로그아웃할 때 "로그아웃하셨습니다. 다시 로그인을 원하시면 이 폼을 사용하세요"라는 메시지와 함께 login.php 페이지로 되돌려 보낼 수 있다. 어떻게 할 수 있을까? 로그아웃한 후에 login.php?process=2 처럼 URL에 특별한 값(2같은)을 전달하고 login.php 페이지로 리다이렉트를 한다. 그리고 나서 login.php 페이지에서 if문을 사용하여 $_GET["process"] 값이 2인지 체크한다. 비교가 성공했다면 적절한 메시지를 설정한다. 이런 방법을 사용하면 또 다른 메시지를 출력하기 위해 별도의 로그인 페이지가 필요없다(동일한 페이지내에서 $_GET과 $_POST를 섞어서 사용해도 상관없다. PHP가 알아서 잘 처리하니까)

결론

이 기술을 사용하여 자바스크립트나 ASP를 사용하지 않고 PHP만을 사용하여 중복 코드나 불필요한 처리를 요구하지 않는 정교한 웹 사이트를 쉽게 만들 수 있다.
TAG :
댓글 입력
자료실

최근 본 상품0