• [PHP] PHP 맛보기 - 1

    2019. 1. 24.

    by. 나나 (nykim)

    320x100

    이번에는 생활코딩 내 PHP 강의를 기반으로 한 실험(?!)입니다. PHP를 정말 정말 쬐애끔 맛만 보는 정도이지만, JS가 아닌 다른 언어를 알게 됐다는 데 의의를 두겠습니다ㅋㅋㅋㅋ
    생활코딩에게 무한한 감사를 드리며, 실험일지 스타트!


    PHP 설치 (Windows)

    윈도우는 Bitnami가 제공하는 WAMP라는 걸 사용해 PHP를 사용합니다. WAMP는 아마 Window, Apach, MySql, Php의 약자로, 여기에 접속해서 설치합니다.

    PHP는 서버 사이드 언어라 웹 서버 바탕 위에서 돌아가기 때문에 Apache 웹 서버를 돌릴 필요가 있습니다. WAMP Stack Manager Tool을 이용해 서버를 껐다 키는 등 관리를 할 수 있는데, PHP를 재구동하려면 Apache(아파치) 웹 서버를 재구동해야 합니다.

    자... 그럼 웹서버가 잘 돌아가는지 확인하기 위해 브라우저 주소창에 localhost을 땅!하고 쳐줍니다(별다른 설정이 없다면 80 포트겠지만, 저는 8181이란 포트로 지정했어요!) 그럼 bitnami가 웰껌! 하는 페이지가 나오는데, 이 페이지는 어디있는 걸까요?

    예를 들어, 우리가 nykim.net/abc.php 라고 주소창에 땅 쳤다고 합시다. 이건 클라이언트(나) 컴퓨터가 서버(nykim.net) 컴퓨터에게 abc.php를 보여줘라고 요청한 겁니다. 그럼 어느 디렉토리를 root로 설정했는지에 따라 그걸 기반으로 abc.php를 찾아 그 정보를 보여주게 됩니다. 이 아파치 웹서버의 경우에는 bitnami폴더 안에 그게 설정된 파일이 있습니다. 별다른 경로 지정을 하지 않았다면 C:\Bitnami\wampstack\apache2\conf 디렉토리 내 httpd.conf 파일입니다.

    보니까 htdocs란 디렉토리가 루트로 지정되어 있네요! 여길 들어가면 index.html이 있는데, 이걸 로컬에서 열어보면 아까 봤던 페이지랑 똑같은 내용입니다!! 이제 이 디렉토리 내에 php라는 새로운 디렉토리를 만든 다음, 여기서 작업을 진행하겠습니다. 그럼 이제 파일을 요청할 때 경로는 localhost/php/가 되겠죠?



    PHP 설정

    C:\Bitnami\wampstack\php폴더 내 php.ini 파일이 있는데, 이는 php를 설정할 때 사용합니다. 뒤에 -development나 -production이 붙는 파일은 개발 또는 실 서버 환경에서 세팅한 뒤, 파일 이름을 php.ini로 수정해 대체하여 사용합니다.
    개발 시에 권장하는 세팅은 아래와 같습니다.

    display_errors = On
    display_startup_errors = On
    error_reporting = -1
    log_errors = On 

    php.ini-development에 아마 이렇게 설정이 되어있을 거에요. 그럼 기존에 있던 php.ini 뒤에 -original을 붙여주고, -development는 떼버려서 ini 파일로 변경해줍니다. 아파치를 껐다가 켜주면 끝!



    PHP의 기본

    다시 기본적인 얘기를 해보죠! 우리가 웹을 쓴다는 건 클라이언트와 서버가 서로 요청하고 응답하는 과정이라 할 수 있습니다. 클라이언트가 웹 브라우저에다 어떤 url을 치면(아니면 링크를 타고 들어가거나) OS를 지나 인터넷 뭐시기를 거쳐 서버 컴퓨터에게 찾아갑니다. 그럼 서버 컴퓨터의 웹서버는 사용자가 요청한 파일을 찾습니다.
    어, 근데 이게 html이 아니라 php파일이네요? 그 경우 php 엔진(파서, 인터프리터)에게 이 파일을 실행하게끔 합니다. 그럼 엔진이 그걸 해석한 다음 html로 만들어서 웹서버에게 전달합니다. 그리고 그 결과를 다시 돌아돌아 클라이언트 컴퓨터의 웹브라우저에게 전달합니다. 그 다음 웹브라우저가 전달받은 html 코드를 분석해 웹페이지를 사용자에게 보여주게 됩니다 (헉헉 길다)

    즉, PHP는 서버 사이드 언어이며(C언어 기반이래요!), 우리가 PHP 언어를 이용해 어플리케이션을 만들면 엔진(파서)이 그걸 html로 만들어서 웹 브라우저에게 전달해준다는 얘기인 거죠. 달리 말하면 동적인 html 파일 생성이 가능해요.
    좀 더 명료한 정리는 여기를 참고하세요 :)

    PHP코드는 웹 페이지 어느 부분에나 쓰일 수 있는데, 그럼 어디서부터 어디까지가 PHP코드인지 표시를 해놔야겠죠!? 대부분 아래와 같이 작성합니다.

    <html>
        <body>
          <?php
            echo "Hello, world!";
          ?>
        </body>
    </html>

    명령문 뒤에 세미콜론(;) 붙이는 걸 잊지 맙시다!(는 본인에게 하는 소리입니다)



    PHP의 변수

    PHP에서는 달러($) 기호를 사용해 변수를 선언합니다. SASS가 생각나네요! JS와 비슷하게 변수 선언시 타입을 따로 명시하지 않습니다. 문자를 넣으면 문자 타입이고 숫자를 넣으면 숫자 타입이죠. 또 대소문자를 구분하며, 문자열 내에서 사용할 때는 중괄호 {}로 감싸거나 온점 .으로 분리하여 사용합니다.

    $name = "Anne";
    echo "(1) 안녕하세요, {$name}님!";
    echo "(2) 안녕하세요, ".$name."님!";

    필요에 따라 define()을 써서 상수를 정의할 수도 있고, 특이하게 가변변수라는 것도 있습니다.

    $name = "anne";
    $$name = "It's me!";
    echo $anne; //출력값: It's me!

    한편, PHP에는 수퍼 전역변수(superglobal variables)라는 게 있습니다. 말 그대로 슈퍼! 해서 범위에 무관하게 접근할 수 있습니다.
    예를 들면... $GLOBALS는 모든 전역변수를 저장하고 있고, $_SERVER는 헤더나 경로, 스크립트 위치에 대한 정보를 담고 있습니다. $_SERVER['PHP_SELF']는 스크립트가 실행되는 현재 파일 이름을 리턴해주죠. 그밖에 $_GET이나 $_POST는 폼 데이터를 수집할 때 사용합니다. 뭐, 나중에 직접 쓰면 감이 오겠죠?!



    PHP의 함수

    PHP에서 사용자 정의 함수를 만들 때는 아래와 같이 작성합니다.

    function sum ($a, $b) {
        return $a+$b;
    }
    sum(1,2);

    인자 앞에 $가 들어간다는 거 빼면 JS랑 비슷한 느낌이네요!(•̀ᴗ•́)و 함수 이름은 숫자로 시작할 수 없고, 대소문자를 구분하지 않습니다.
    또, 인자의 기본값을 지정하는 것도 가능합니다.

    function sayHello ($name="anne") {
        echo "Hello, ${name}.";
    }
    sayHello(); //출력값: "Hello, anne."


    PHP의 배열

    PHP에서 배열은 요로콤 작성합니다.

    $fruits = ['banana', 'mango', 'blueberry'];
    //또는
    $fruits = array('banna', 'mango', 'blueberry'); //하위 호환

    값을 꺼낼 땐 $fruits[0]과 같이 쓰면 됩니다.
    한편 연관배열이란 것도 있어요!

    $price = array('book'=>13000, 'snack'=>1500, 'diary'=>8000 );

    여기서 'book'은 key가 되고, 13000은 value가 됩니다. 그래서 $price['book']와 같이 쓰면 13000이라는 값을 가져올 수 있어요.

    한편 배열의 크기를 알고 싶다면 count({배열명})를 쓰거나, 배열에 아이템을 추가할 때는 array_push({배열명}, {추가할 아이템})을 쓰면 됩니다. 모든 기능을 여기에 다 적기에는 공간이 부족....하지는 않지만, 필요할 때는 검색해서 찾아 쓰자구요(*・∀-)☆



    폼 데이터 전송

    드디어 본격적으로 코드를 작성할 시간입니다! 자, PHP 에플리케이션은 URL을 통해서 데이터를 입력 받을 수 있습니다.
    localhost/php/test.php?id=123&name=anne이라는 주소가 있을 때, ? 뒤에 붙는 게 입력 데이터입니다. 값과 값은 & 로 구분되며, 이름과 값은 =로 구분됩니다.

    아무 php파일이나 열고 대충 form을 만들어줍니다.

    <form method="get" action="result.php">
        ID :  <input type="text" name="id" />
        EMAIL :  <input type="email" name="email" />
        <input type="submit" />
    </form>

    그리고 result.php는 이렇게 작성해줍니다.

    Your Id: <?php echo $_GET['id'];?>
    Your Email: <?php echo $_GET['email'];?>

    이후 값을 입력하고 버튼을 눌러봅니다. 그럼 폼 데이터가 result.php라는 파일에 처리를 위해 전송이 됩니다. 이제 주소창을 잘 보면 URL이 바뀐 걸 볼 수 있습니다.
    localhost/php/result.php?id=anne&email=nykim%40nykim.net로 URL이 바뀌었습니다. 그리고 이걸 $_GET['id']로 가져다 쓰고 있네요.
    똑같이 POST 방식으로 작성도 가능합니다. 이 경우, 주소창에는 값이 붙지 않으며 $_POST['id']로 값을 가져와야 합니다.

    우선 가볍게 설명만 하자면, GET 방식은 URL에 값이 그대로 표시되며, 문자 양의 제한이 있으나, 페이지 북마크가 가능합니다. 한편 POST 방식은 폼 데이터가 보이지 않고, 문자 양에 제한이 없습니다.아, 그렇다고 POST가 완벽한 보안을 해주진 않으므로 여기에는 별도의 처리가 필요할 듯 합니다.


    한편 이렇게 작성하면 다른 페이지로 이동하지 않고, 페이지 자신에게 폼 데이터를 전송할 수 있습니다.

    <form method="post" action="">
       Comment: 
       <textarea name="comment" placeholder="Enter your comment"></textarea>
       <input type="submit" />
       <hr/>
       <?php
          if (isset($_POST["comment"])){
            echo "Thanks!! Your Comment is...<br/>";
            echo htmlspecialchars($_POST["comment"]);
          }
       ?>
    </form>
    

    헛, 근데 저기 있는 htmlspecialchars는 뭔가요?! 저건 특수 문자를 HTML entities로 변환해 주는데요, 이게 왜 필요할까요?
    예를 들어 htmlspecialchars 처리 없이, 사용자가 이렇게 입력하면 어떻게 되는지 봅시다.


    (이렇게 입력하면...)


    (다른 브라우저는 자체 필터링해주는데 혼자만 스크립트 실행시켜주는 당당한 IE의 모습이다)


    하지만 htmlspecialchars가 있으면 <를 &lt;로 치환해주기 때문에 안전해지죠!


    그밖에 사용자가 입력한 데이터에서 불필요한 문자를 제거하는 trim()이나 백슬래쉬를 제거하는 stripslashes() 함수 등을 고려할 수도 있습니다. 이고잉님 왈, 사용자가 입력한 정보는 불신하랬어요!! ヽ(`⌒´メ)ノ

    그럼, 이걸 응용해서 빈 값이 있을 때는 에러 메시지를 띄운다던가 하는 처리도 할 수 있겠군요. 요런 느낌이 될 거 같습니다!

    <body>
       <?php
          //빈 문자열을 값으로 정의
          $userName = $userEmail = $userGender = $userComment = "";
          $nameErr = $genderErr = $emailErr = "";
          
          function formValue($data){
            $data = trim($data); //trim()은 문자열에서 공백을 제거
            $data = stripslashes($data); //stripslashes()는 백슬래쉬 \를 제거
            $data = htmlspecialchars($data); //htmlspecialchars()는 특수 문자를 엔티티로 치환
            return $data;
          }
          
          function printGenderInfo($data){
            if(isset($data)){
              if($data === "female"){
                $data = "여자";
              }else if($data === "male"){
                $data = "남자";
              }
              return $data;
            }
          }
          
          
          if ( $_SERVER["REQUEST_METHOD"] == "POST" ){
          
            if (empty($_POST["userName"])) {
              $nameErr = "이름은 필수 항목입니다.";
            } else {
              $userName = formValue($_POST["userName"]);
            }
          
            if (empty($_POST["userEmail"])) {
              $emailErr = "이메일은 필수 항목입니다.";
            } else {
              $userEmail = formValue($_POST["userEmail"]);
            }
          
            if (empty($_POST["userGender"])) {
              $genderErr = "성별은 필수 항목입니다.";
            } else {
              $userGender = formValue($_POST["userGender"]);
            }
          
            $userComment = formValue($_POST['userComment']);
          }
          ?>
       <form action="" method="post">
          <div>
             <strong>이름 <span class="accent">(*필수)</span></strong>
             <input type="text" name="userName" placeholder="이름을 입력하세요."/>
             <span class="error"><?=$nameErr?></span>
          </div>
          <div>
             <strong>이메일 <span class="accent">(*필수)</span></strong>
             <input type="email" name="userEmail" placeholder="이메일 주소를 입력하세요."/>
             <span class="error"><?=$emailErr?></span>
          </div>
          <div>
             <strong>성별 <span class="accent">(*필수)</span></strong>
             <input type="radio" id="userGender-M" name="userGender" value="male" />
             <label for="userGender-M">남자</label>
             <input type="radio" id="userGender-F" name="userGender" value="female" />
             <label for="userGender-F">여자</label>
             <span class="error"><?=$genderErr?></span>
          </div>
          <div>
             <strong>자기소개</strong>
             <textarea name="userComment" placeholder="자개소개를 입력하세요."></textarea>
          </div>
          <input type="submit" name="submit" value="작성 완료"/>  
       </form>
       <hr/>
       <strong>사용자 정보</strong>
       <ul>
          <li>
             <strong>이름: </strong>
             <span><?=$userName?></span>
          </li>
          <li>
             <strong>이메일: </strong>
             <span><?=$userEmail?></span>
          </li>
          <li>
             <strong>성별: </strong>
             <span><?=printGenderInfo($userGender)?></span>
          </li>
          <li>
             <strong>자기소개: </strong>
             <span><?=$userComment?></span>
          </li>
       </ul>
    </body>
    


    여기서 더 나아가면 정규식으로 유효성 검사를 하는 등의 활용이 가능하겠네요.

    그럼 오늘은 여기까지하고 20000 뿅!



    728x90

    댓글