본문 바로가기

class "Think"/"PHP On Azure"

[PHP on Azure - 초급 - 10] Azure Storage를 활용한 PHP 웹사이트 (3)


- 윈도우 애저 무료 평가판 다운로드 : http://www.windowsazure.com/ko-kr/pricing/free-trial/?WT.mc_id=A53D57CF7 

- 윈도우 애저 평가판 설치 내용 하기 : http://www.phpschool.com/link/teach/2650


이전 강의 내용(http://hahaheo.com/234)을 이어서 계속 진행됩니다.



여러분은 Azure Storage를 이용한 Task-list 웹 사이트를 만들고 있습니다.

init.php 파일에 이어서 데이터를 담을 수 있는 테이블을 생성하는 createtable.php 파일을 작성해보도록 하겠습니다.

<?php
require_once "init.php";


init.php 파일을 호출합니다. init.php 파일은 Azure Storage Service와 상호작용 하기 위해 필요한 변수선언이 모두 되어있기 때문에, 여러분이 사용하는 모든 페이지에서 호출할 것입니다.



try {

     $tableRestProxy->createTable('tasks');

}

catch(ServiceException $e) {

     $code = $e->getCode();

     $error_message = $e->getMessage();

     echo $code.": ".$error_message."<br />";

}
?>


이하 내용입니다. 예외처리를 하여서 createTable 을 수행하고 있습니다. 여러분이 흔히 아시는 관계형 데이터베이스(MySQL...)은 Table을 생성할때 안에 애트리뷰트 들을 설정해주지만, Azure Storage는 NoSQL과 비슷하게 별도의 필수 스키마를 생성하지 않아도 됩니다.

catch문은 오류발생시 디버깅 메시지를 출력하기 위한 부분입니다. 혹여나 에러메시지가 나타나게 된다면 (1) 참조사이트를 확인하셔서 어떤 오류인지 체크하시면 됩니다.


아래는 createtable.php의 전체 내용 입니다.


/* createtable.php */

<?php
require_once "init.php";
try {

     $tableRestProxy->createTable('tasks');

}

catch(ServiceException $e) {

     $code = $e->getCode();

     $error_message = $e->getMessage();

     echo $code.": ".$error_message."<br />";

}
?>



다음으로 메인페이지인 index.php를 만들어 보도록 하겠습니다. 지금 만드는 웹 사이트는 Task-list입니다. 따라서 Task를 목록형태로 출력해주는 로직이 필요합니다. 위에서 만든 테이블을 조회하여 필요한 내용을 추출(Query)하여 HTML로 출력합니다. 크게 어려운 부분은 없으니 천천히 따라오시면 됩니다.


<html>
<head>

    <title>Index</title>

    <style type="text/css">

        body { background-color: #fff; border-top: solid 10px #000;

            color: #333; font-size: .85em; margin: 20; padding: 20;

            font-family: "Segoe UI", Verdana, Helvetica, Sans-Serif;

        }

        h1, h2, h3,{ color: #000; margin-bottom: 0; padding-bottom: 0; }

        h1 { font-size: 2em; }

        h2 { font-size: 1.75em; }

        h3 { font-size: 1.2em; }

        table { margin-top: 0.75em; }

        th { font-size: 1.2em; text-align: left; border: none; padding-left: 0; }

        td { padding: 0.25em 2em 0.25em 0em; border: 0 none; }

    </style>

</head>

<body>

<h1>My ToDo List <font color="grey" size="5">(powered by PHP and Azure Tables) </font></h1>

<?php       

require_once "init.php";


index 페이지의 헤더부분입니다. html관련해서는 여러분이 저보다 더 잘 아실테니 html, css부분은 설명을 생략하겠습니다. 하단에 굵은글씨로 표시된 스크립트 부분에서 init.php를 호출하고 있습니다. Azure Storage에 Query를 날리기 위해 꼭 필요합니다



try {
    $result = $tableRestProxy->queryEntities('tasks');
}
catch(ServiceException $e){
    $code = $e->getCode();
    $error_message = $e->getMessage();
    echo $code.": ".$error_message."<br />";
}


init에 있던 $tableRestProxy 객체의 QueryEntities라는 메소드를 통해 아까 createtable.php에서 만들었던 'tasks'라는 테이블을 받고 있습니다. 간단하게 쿼리를 날릴 수 있습니다.



$entities = $result->getEntities();


for ($i = 0; $i < count($entities); $i++) {


받아온 결과 변수인 $result에서 엔티티들을 실제로 사용할 수 있게 iterate 형태로 $entities에 받는 과정입니다. for 문을 통해서 하나하나 출력해보도록 하겠습니다.



if ($i == 0) {

        echo "<table border='1'>

        <tr>

            <td>Name</td>

            <td>Category</td>

            <td>Date</td>

            <td>Mark Complete?</td>

            <td>Delete?</td>

        </tr>";

    }

    echo "

        <tr>

            <td>".$entities[$i]->getPropertyValue('name')."</td>

            <td>".$entities[$i]->getPropertyValue('category')."</td>

            <td>".$entities[$i]->getPropertyValue('date')."</td>";

            if ($entities[$i]->getPropertyValue('complete') == false)

                echo "<td><a href='markitem.php?complete=true&pk=".$entities[$i]->getPartitionKey()."&rk=".$entities[$i]->getRowKey()."'>Mark Complete</a></td>";

            else

                echo "<td><a href='markitem.php?complete=false&pk=".$entities[$i]->getPartitionKey()."&rk=".$entities[$i]->getRowKey()."'>Unmark Complete</a></td>";

            echo "

            <td><a href='deleteitem.php?pk=".$entities[$i]->getPartitionKey()."&rk=".$entities[$i]->getRowKey()."'>Delete</a></td>

        </tr>";

}



if ($i > 0)

    echo "</table>";

else

    echo "<h3>No items on list.</h3>";

?>


코드가 길지만 대단한건 없습니다;; Table 형태로 아까 위에서 날린 Query 내용을 출력할 것입니다. 처음에 각 열의 이름을 뿌려주고, 다음 행부터는 Name, Category, Date, Complete라는 속성의 값을 차례대로 출력합니다. 보시면 $entities라는 배열에 getPropertyValue('속성값')으로 저장되어있는 데이터를 뽑아올 수 있습니다. 다음엔 여러분이 올린 Task가 완료되었는지, 다시 취소되었는지, 삭제할건지에 대한 링크를 앵커태그로 나타내고 있습니다.



<hr/>
    <form action="additem.php" method="post">
        <table border="1">
            <tr>
                <td>Item Name: </td>
                <td><input name="itemname" type="textbox"/></td>
            </tr>
            <tr>
                <td>Category: </td>
                <td><input name="category" type="textbox"/></td>
            </tr>
            <tr>
                <td>Date: </td>
                <td><input name="date" type="textbox"/></td>
            </tr>
        </table>
        <input type="submit" value="Add item"/>
    </form>
</body>
</html>


마지막 footer 부분입니다. 새로운 task를 추가할 수 있는 폼을 만들고 있습니다.



지금까지 작성한 index.php의 전체 내용입니다.


<!-- index.php -->

<html>

<head>

    <title>Index</title>

    <style type="text/css">

        body { background-color: #fff; border-top: solid 10px #000;

            color: #333; font-size: .85em; margin: 20; padding: 20;

            font-family: "Segoe UI", Verdana, Helvetica, Sans-Serif;

        }

        h1, h2, h3,{ color: #000; margin-bottom: 0; padding-bottom: 0; }

        h1 { font-size: 2em; }

        h2 { font-size: 1.75em; }

        h3 { font-size: 1.2em; }

        table { margin-top: 0.75em; }

        th { font-size: 1.2em; text-align: left; border: none; padding-left: 0; }

        td { padding: 0.25em 2em 0.25em 0em; border: 0 none; }

    </style>

</head>

<body>

<h1>My ToDo List <font color="grey" size="5">(powered by PHP and Azure Tables) </font></h1>

<?php       

require_once "init.php";

try {
    $result = $tableRestProxy->queryEntities('tasks');
}
catch(ServiceException $e){
    $code = $e->getCode();
    $error_message = $e->getMessage();
    echo $code.": ".$error_message."<br />";
}

$entities = $result->getEntities();


for ($i = 0; $i < count($entities); $i++) {

if ($i == 0) {

        echo "<table border='1'>

        <tr>

            <td>Name</td>

            <td>Category</td>

            <td>Date</td>

            <td>Mark Complete?</td>

            <td>Delete?</td>

        </tr>";

    }

    echo "

        <tr>

            <td>".$entities[$i]->getPropertyValue('name')."</td>

            <td>".$entities[$i]->getPropertyValue('category')."</td>

            <td>".$entities[$i]->getPropertyValue('date')."</td>";

            if ($entities[$i]->getPropertyValue('complete') == false)

                echo "<td><a href='markitem.php?complete=true&pk=".$entities[$i]->getPartitionKey()."&rk=".$entities[$i]->getRowKey()."'>Mark Complete</a></td>";

            else

                echo "<td><a href='markitem.php?complete=false&pk=".$entities[$i]->getPartitionKey()."&rk=".$entities[$i]->getRowKey()."'>Unmark Complete</a></td>";

            echo "

            <td><a href='deleteitem.php?pk=".$entities[$i]->getPartitionKey()."&rk=".$entities[$i]->getRowKey()."'>Delete</a></td>

        </tr>";

}



if ($i > 0)

    echo "</table>";

else

    echo "<h3>No items on list.</h3>";

?>

<hr/>
    <form action="additem.php" method="post">
        <table border="1">
            <tr>
                <td>Item Name: </td>
                <td><input name="itemname" type="textbox"/></td>
            </tr>
            <tr>
                <td>Category: </td>
                <td><input name="category" type="textbox"/></td>
            </tr>
            <tr>
                <td>Date: </td>
                <td><input name="date" type="textbox"/></td>
            </tr>
        </table>
        <input type="submit" value="Add item"/>
    </form>
</body>
</html>


이번에 실습하는 파일중 가장 스케일이 큰 파일입니다. 그러나 하나하나 뜯어보면 그렇게 어렵지 않은 내용입니다.



다음 강의에서 나머지 3개의 파일을 마저 살펴보도록 하겠습니다!






참고사이트


(1) 에러코드 & 메시지 참조 사이트 - http://msdn.microsoft.com/en-us/library/windowsazure/dd179438.aspx