이전



MySQL 강좌 (Ⅳ)

김윤한(spbear@nownuri.net)

 

 

1. 들어가는 말

    APM - Apache, PHP3, MySQL의 환상의 트리오!!

    지난호에서는 MySQL과 C를 연동하는 방법을 살펴 보았다. SQL구문을 사용하는 것보다 C로 작성된 프로그램을 사용하는 것이 데이터를 관리하기 쉬운 것은 자명하다. 하지만 여기서 좀 더 욕심을 내어 이번회에서는 웹과 연동하는 방법을 살펴보도록 하자. C를 이용한 CGI를 작성해서 웹과 연동할 수도 있지만 여기서는 PHP3라는 웹스크립트 언어를 사용해 손쉽게 웹과 DB를 연동하는 방법을 알아보도록 하겠다.

 

2. 설치

    설치는 따로 설치하지 않고 기본적인 패키지를 이용하는 방법, 소스를 이용해서 설치하는 방법에 대해 살펴보도록 하겠다. 기본적으로 MySQL의 설치 방법은 지난회에서 다루었으므로 생략하도록 하겠다.

1) 기본적인 패키지를 이용하기

    이 방법은 가장 쉽게 접근할 수 있는 방법으로 리눅스 레드햇 5.2이상의 배포판을 사용하고 있다면 기본적으로 아파치와 PHP3가 깔려 있고, PHP3 모듈의 경우 PostgreSQL과 MySQL과의 API도 기본으로 연결되어 있기 때문에 단지 /etc/httpd/conf/httpd.conf를 조금 수정해 주는 것으로 PHP3의 강력한 기능들을 접해볼 수 있다. 방법은 아주 간단하여, 몇 부분의 주석을 지워주면 된다.

    ◆ 먼저 모듈을 아파치위에 올려주는 LoadModule 부분중에서 다음의 주석을 지워준다.
    LoadModule php_module          modules/mod_php.so
    LoadModule php3_module        modules/libphp3.so

    ◆ 그리고 MIME TYPE을 설정해주는 부분의 다음의 주석을 지워준다.
    AddType application/x-httpd-php3 .php3
    AddType application/x-httpd-php3-source .phps

    ◆ 위의 주석을 지운 후 다음의 명령을 실행해주어 아파치를 다시 실행 시킨다.
    % killall httpd
    % httpd

    RPM으로 설치하는 방법도 마찬가지여서 패키징된 RPM을 받아서 설치한 후에 위의 주석들만 제거해주면 된다.

2) 소스로 설치하기

    ◆ 우선 http://www.apache.org에서 아파치의 소스를, http://www.php.net에서 PHP3의 소스를 가지고 온다.

    ◆ 다음의 명령들을 실행해줌으로써 컴파일을 해준다.

    % tar xvzf apache_1.3.x.tar.gz
    % tar xvzf php-3.0.x.tar.gz
    %  cd apache_1.3.x
    % ./configure --prefix=/www
    %  cd ../php-3.0.x
    % ./configure --with-mysql --with-apache=../apache_1.3.x --enable-track-vars
    %  make
    % make install
    % cd ../apache_1.3.x
    % ./configure --prefix=/www --activate-module=src/modules/php3/libphp3.a
    % make
    % make install  

    ( 이 과정에서 인스톨을 하지 않고 생성된 바이너리를 httpd를 죽인후에 덮어 씌워도 된다.)

    % cd ../php-3.0.x
    % cp php3.ini-dist /usr/local/lib/php3.ini

    ( /usr/local/lib/php3.ini 파일은 PHP의 설정파일이다. 이 설정파일의 위치를 다르게 하고 싶다면 php의 configure에서 --with-config-file-path=/path를 사용하면 된다.)

    ◆ 컴파일이 모두 끝났다면 httpd.conf나 srm.conf에 다음을 추가해 준다.

    AddType application/x-httpd-php3 .php3

    ( .php3외의 확장자도 php3로 동작이 가능하지만 개발자들은 .php3를 추천하고 있다.)

    ◆ 아파치 서버를 다시 시작하도록 한다.

3) 설치 후 테스트

    패키지로 설치한 경우라면 /home/httpd/html이 초기 디렉토리이고 소스를 컴파일하여 설치하였다면 /www/htdocs가 초기 디렉토리가 된다. 초기 디렉토리에 에디터를 이용해서 test.php3라는 파일을 다음과 같이 작성해준다.

    <?php
    mysql_connect(“localhost”, “root”, “”);
    echo “Hello!”;
    ?>

    브라우저를 띄워서 한번 확인해 보도록 하자. 소스가 그냥 출력이 된다면 잘못 설치된 것이고, 제대로 설치하였다면 에러 메시지 없이 화면에 Hello!라는 글자가 출력될 것이다. 자, 이제 모든 준비가 되었다. 그러면 PHP3의 세계로 들어가보도록 하자.

 

3. 기본적인 PHP3의 문법 - 변수

    PHP3의 문법들은 기본적으로 C에서 따왔고, 자바와 Perl의 영향도 받았다고 한다. C를 익힌 사람이라면 어렵지 않게 접근 가능할 것이다. 여기에서는 지면 관계상 C와 비슷한 부분은 되도록 생략하고 C를 익힌 사람이 접근하도록 하겠다.

1) PHP3 코드의 실행

    PHP3는 HTML문서 내에 들어가는 서버사이드 스크립트(Server-side Script)의 형식을 취하고 있다. 다음의 예제를 보도록 하자.

    <?php echo(“hello?”); ?>
    <? echo(“hello?”); ?>
    <script language=”php”>echo (“hello?”);</script>

    위의 형식 이외에 ASP와 같은 형식을 취하게 할 수도 있지만 주로 맨처음의 <?php 로 시작하는 형식을 많이 취한다. 두 번째의 생략형의 경우 XML과의 충돌 여지가 있으므로 되도록 사용하지 않도록 한다.

2) 변수형 (Variable Types)

    PHP3에서의 변수들은 모두 변수명앞에 $가 붙게 된다. PHP3는 다음 형태의 변수형을 지원한다.

    Scalar types, Integer, Float, String, Array Types, Linear Arrays, Hashes/Associative Arrays , Objects
    C와는 달리 PHP3에서는 미리 변수를 선언해줄 필요가 없다. 대신 PHP3코드 수행중에 변수의 값에 따라서 자동으로 변수형이 바뀌어 지게 된다. 특정한 변수형으로 지정하고 싶으면 캐스트를 하거나 settype()함수를 사용하도록 한다. 이 변수형은 미묘한 관계에 있는데 때로는 변수형 때문에 프로그래머의 의도대로 프로그램이 동작하지 않은 경우가 발생하기도 한다.

3) 배열 초기화 (Initializing Arrays)

    배열에 순차적으로 값을 대입하는 방법은 배열에 첨자 없이 그냥 대입하면 된다. 그러면 새로 대입한 값은 그 배열의 제일 마지막에 첨가된다.

    $names[] = “Jill”;    // $names[0] = “Jill”
    $names[] = “Jack”;    // $names[1] = “Jack”  

    이외에도 array()라는 construct를 사용해서 초기화할 수도 있다.

4) 객체의 초기화 (Initializing objects)

    객체의 초기화는 new 명령을 통해 object를 변수에 인스턴스화 시키는 것이다.

    class foo {
       function do_foo() {
          echo “Doing foo.”;
       }
       }
    $bar = new foo;
    $bar->do_foo();   

5) 변수 가용 범위 (Variable Scope)

    변수가 사용가능한 곳은 변수가 선언된 곳에서만 사용할 수 있다. 이는 PHP3가 single scope를 가지기 때문이다. 만약 전역변수를 사용하고 싶다면 사용하려는 변수를 함수안에서 global선언을 해주어야 한다.

    $a=1;
    $b=2;
    Function Sum() {
        global $a,$b;
        $b = $a + $b;
          }
    Sum();
    echo $b;

    전역변수를 참조하는 방법 중 다른 방법은 위와 같이 global로 선언하지 않고 $GLOBALS라는 특수한 배열을 이용하는 방법이다. 위의 예제중 Sum()함수는 다음과 같이 바뀌어 질 수 있다.
    Function Sum() {
     $GLOBALS[“b”] = $GLOBALS[“a”] + $GLOBALS[“b”];
      }

6) 가변 변수 (Variable variables)

    변수의 이름을 마음대로 변경할 수는 없을까? PHP3에서는 이 방법을 제시하고 있다. 예제를 통해서 살펴보자.

    $a = “hello”;
    $$a = “world”;  

    위와 같이 하면 실제로는 $a라는 함수와 $hello라는 두 개의 변수가 생긴 것과 동일한 결과를 얻을 수 있다. 그러므로 다음의 두 문장은 서로 같은 결과를 나타난다.

    echo “$a ${$a}”;    
    echo “$a $hello”;  

7) PHP3 밖에서 온 변수들

    PHP3가 웹 스크립트 언어로서 쓰일 수 있었던 것은 이러한 PHP3밖에서 변수를 가져올 수 있다는 점이다. 다음을 살펴보도록 하자.

    ◆ HTML Forms (GET and POST)
    폼이 PHP3 스크립트로 submit되면 폼에 있는 모든 내용들이 자동적으로 만들어진 PHP 변수로 들어온다. 다음의 폼을 보자.

    <form action=”foo.php3” method=”post”>
      Name: <input type=”text” name=”name”><br>
      <input type=”submit”>
      </form>

    위의 폼이 submit되면 foo.php3의 내부에는 $name이라는 변수가 만들어지고 이 변수는 폼의 Name: 필드에 입력한 모든 내용을 담고 있게 된다.

    ◆ HTTP Cookies
    PHP3는 HTTP 쿠키를 제공한다. SetCookie() 함수를 이용해서 쿠키를 저장할 수 있고 저장된 쿠키는 POST/GET과 동일한 형식으로 PHP3 변수로 생성되게 된다.

    $Count++;
    SetCookie(“Count”,$Count, time()+3600);
    SetCookie(“Cart[$Count]”,$item, time()+3600);

    SetCookie() 함수의 경우 HTTP헤더에 위치해야 하므로 어떠한 문자보다 먼저와야 한다.

    ◆ 환경 변수 (Environment variables)
    PHP3는 자동적으로 환경 변수들을 변수로 만들어 준다.
    echo $HOME;  /* Shows the HOME environment variable, if set. */    

8) 상수의 정의

    C에서 #define라는 preprocessor를 썼던것과는 달리 define()함수를 통해서 상수를 정의한다.

    <?php
        define(“CONSTANT”, “Hello world.”);
        echo CONSTANT; // outputs “Hello world.”
        undefine (“CONSTANT”);
    ?>

9) 제어문

    PHP3의 제어문은 C와 거의 비슷하다. 단 새로운 형식을 지원해 주는데 다음이 바로 그것이다.

    if    ( [expression1] ) :
               [statement1];
    elseif ( [expression2] ) :
               [statement2];
                     else :
               [statement3];
                     endif;

    위의 예제는 다음과 같이 바뀌어질 수 있다.

    if ( [expression1] ) {
     [statement1];
    } elseif ( [expression2] ) {
     [statement2];
    } else {
     [statement3];
    }

    이는 if문만이 아니라 for문, while문도 마찬가지이다. 콜론(:)을 써서 다음의 제어문이 나오기 전까지의 statement를 모두 한꺼번에 처리해주는 것이다. 이는 HTML내에서 중괄호가 어디에 있는지 파악하기 힘들 때 제어문을 이용함으로써 코드를 더 잘 식별할 수 있게 도와준다.

10) INCLUDE

    INCLUDE문은 지정한 파일을 읽고 실행한다. 이 동작은 실행중 INCLUDE 문을 만날 때 만다 일어난다. 따라서 여러분은 INCLUDE문을 루프 구조 안에 두어 매번 다른 파일을 읽어 들이도록 할 수 있다.

    $files = array(‘first.inc’, ‘second.inc’, ‘third.inc’);
    for ($i = 0; $i < count($files); $i++) {
      include($files[$i]);
                      }

11) FUNCTION

    함수는 다음과 같이 정의한다.

    function foo( $arg_1, $arg_2, ..., $arg_n ) {
       echo “Example function.\n”;
       return $retval;
                    }

    함수 안에는 다른 함수나 class의 선언 등을 포함한 모든 가능한 PHP3 코드가 사용될 수 있다.

12) CLASS

    클래스는 여러 변수와 이 변수를 제어하는 함수를 하나로 묶을 수 있다. 클래스는 다음과 같은 형태로 선언된다.

    class Cart {
      var $items;  // Items in our shopping cart

      function add_item($artnr, $num) {
        $this->items[$artnr] += $num;
        }
        }

    클래스는 하나의 변수형으로써 new 연산자를 사용하여 원하는 변수를 생성해야 한다.

    $cart = new Cart;
    $cart->add_item(“10”, 1);

 

4. MySQL을 위한 PHP3의 API함수들

    PHP3에서는 MySQL을 위해서 많은 API 함수들을 제공하고 있다. (http://www.php.net/manual/ref.mysql.php3) 사용법등은 C에서 살펴봤던 것과 비슷하다.

    ◆ int mysql_connect(string [hostname][:port], string [username], string [password]);
    mysql_connect()는 MySQL서버에 연결한다.
    hostname : 연결하고자 하는 서버의 IP Address또는 호스트 이름을 넣는다.
                     아무것도 넣지 않으면 localhost가 된다.
    username : 접속시의 사용자의 이름이다. NULL이면 서버 프로세서의 사용자로 들어간다.
    password : user의 암호를 나타낸다.
    반환값 : MySQL Link identifier를 반환한다.

    ◆ int mysql_close(int [link_identifier] );
    서버와의 연결을 종료한다.

    ◆ int mysql_select_db(string database_name, int [link_identifier] ); 접속후 사용하고자 하는 데이터베이스를 바꿔준다.
    database_name : 사용하고자 하는 데이터베이스 이름
    link_identifier : mysql_connect()시 반환된 identifier가 들어간다.
    넣어주지 않으면 맨 처음 수행했던 connection에 대해 적용된다.

    ◆ int mysql_query(string query, int [link_identifier] );
    쿼리를 수행한다. UPDATE, INSERT, DELETE의 경우 단지 TRUE/FALSE만을 반환하고 종료하나, SELECT 쿼리의 경우 성공하면 새 result identifier를 반환하므로 나중에 꼭 mysql_free_result()를 사용해서 사용한 자원을 반환하도록 한다.

    ◆ int mysql_db_query(string database, string query, int link_identifier); database명을 명시해준 쿼리를 수행한다.

    ◆ int mysql_affected_rows(int [link_identifier] );
    INSERT, UPDATE, DELETE 등의 query로 영향을 받은 row의 수를 반환한다.

    ◆ array mysql_fetch_row(int result);
       row를 배열의 형태로 가져온다.

    ◆ array mysql_fetch_array(int result);
        row를 배열의 형태로 가져온다.
    다만 mysql_fetch_row()와 다른 점은 associative 배열로 가져온다는 점이다. 이렇게 가지고 온 배열은 필드 이름으로 접근이 가능하다.

    ◆ int mysql_fetch_object(int result);
       row를 객체로 가져온다. (객체로 가져온다는 것을 제외하면 mysql_fetch_row()와 같다.)

    ◆ int mysql_num_rows(string result);
       result에 총 몇 개의 row가 있는지 리턴한다.

    ◆ int mysql_num_fields(int result);
       result에 총 몇 개의 field가 있는지 리턴한다.

    ◆ int mysql_result(int result, int row, mixed field);
       result set에서 하나의 셀의 내용을 반환해준다.

    ◆ int mysql_errno(int [link_identifier] );
       가장 최근에 mysql에 일어난 에러의 번호를 리턴한다.

    ◆ string mysql_error(int [link_identifier] );
       가장 최근에 일어난 에러 메시지를 리턴한다.

 

5. 간단한 예제

    그럼 위에서 살펴본 API를 이용해서 간단한 DB연동 프로그램을 만들어 보도록 하자. 우선 2회때 사용했던 super 라는 데이터베이스를 이용하여 일일이 SQL구문을 쓰지 않고 DB에 구매 내역을 입력하는 페이지를 작성해 보도록 하자.

    preinsertexport.php3
    <html>
    <body>
    <?php
    // 데이터베이스에 접속한다.
     $connect = mysql_connect(“localhost”,”root”) or
     die ( “ SQL Server에 연결할 수 없습니다.” );

    // 우리가 만들어 놓은 super 데이터베이스에 연결한다.
     mysql_select_db( “super”, $connect);

    // 쿼리를 만든다. (Item테이블에서 데이터를 가져오는 쿼리)
     $query = “select * from Item”;

    // 쿼리를 수행한다. 수행된 결과는 result에 보관된다.
     $result = mysql_query($query, $connect);

    // 전체 row의 개수를 판단한다.
     $total = mysql_numrows($result);

    // row의 개수가 0이 아니라면 Item이 존재하는 것이므로 다음을 수행한다.
     if ($total) :
     ?>
     <form action=”insertexport.php3” method=post>
     <select name=”Id”>
     <?php
      // Item테이블에서 row를 하나씩 빼온 뒤 출력한다.
      for ($i = 0; $i < $total; $i++) {
       $row = mysql_fetch_array($result);
        echo(“<option value=\”$row[Id]\”>$row[name]</option>\n”);
        }
       ?>
     </select>
     <input type=”text” name=”how_many”>개
     <input type=”submit” value=”구매”>
     </form>
     <?php
     // Item 테이블에 데이터가 존재하지 않는다면 아래의 문장을 출력한다.
        else:
        ?>
    Item이 입력된 것이 없습니다.
        <?php
        endif;
        ?>
    </body>
    </html>
    insertexport.php3
    <html>
    <body>
    <?php
    // 데이터베이스에 접속한다.
     $

    connect = mysql_connect(“localhost”,”root”) or
       die ( “ SQL Server에 연결할 수 없습니다.” );

    // 우리가 만들어 놓은 super 데이터베이스에 연결한다.
     mysql_select_db( “super”, $connect);

    // Item테이블에서 $Id를 가진 튜플을 가져온다.
    // $Id는 이전 페이지에서 입력받아서 POST Method로 생성되었다.
     $query = “select * from Item where Id=” . $Id;
     $result = mysql_query($query, $connect);
     $row = mysql_fetch_array($result);

    // Item테이블에서 가져온 데이터와 입력받은 데이터를 // 조합하여 export테이블에 넣을 쿼리를 생성한다.
     $query = “insert into export values (NULL , ‘“ .   
     $row[name] . “‘ , “ .
     $how_many . “ , “ . $how_many * $row[cost] .
      “ , CURRENT_DATE) “;
     mysql_query($query, $connect);

    // export테이블의 리스트를 출력한다.
     $query = “select * from export”;
     $result = mysql_query($query, $connect);
     $total = mysql_numrows($result);
     if ($total) :
     ?>
     <table>
     <tr>
     <td>번호</td>
     <td>상품명</td>
     <td>수량</td>
     <td>총가격</td>
     <td>구매일</td>
     </tr>
     <?php
      for ($i = 0; $i < $total; $i++) {
       $row = mysql_fetch_array($result);
       echo(“<tr>”);
       echo(“<td>$row[No]</td>”);
       echo(“<td>$row[name]</td>”);
       echo(“<td>$row[how_many]</td>”);
       echo(“<td>$row[how_much]</td>”);
       echo(“<td>$row[when]</td>”);
       echo(“</tr>”);
       }
      ?>
     </table>
     <?php
        else:
      ?>
    판매된 것이 없습니다.
     <?php

        endif;
      ?>
    </body>
    </html>

    위의 프로그램은 preinsertexport.php3를 읽어들이면 입력폼이 나오게 된다. 입력폼에서 콤보박스에 여러개의 아이템을 출력해 주고 있고 그 아이템을 고른 후 submit버튼을 누름으로써 insertexport.php3에 $Id와 $how_many라는 변수가 넘어가게 된다.

    insertexport.php3에서는 입력받은 $Id를 통해서 Item테이블을 검색하여 그 아이템의 이름과 가격정보를 가져온다. 가져온 정보와 $how_many 변수를 재조합하여 export테이블에 INSERT쿼리를 주게 되는 것이다.

이로써 간단한 입력과 리스트해보는 프로그램을 보았다. 이를 응용하면 간단한 쇼핑몰은 쉽게 구축할 수 있을 것이다. 다음회에는 이를 이용해서 간단한 쇼핑몰을 구축해보도록 하겠다.




▲ top