Erzsamatory Weblog


웹 프로그래밍 기술과 웹 브라우저가 상당히 발전하면서 동적인 화면 출력이 가능한 대화식 웹 어플리케이션이 많이 늘어났습니다. 이 글에서 소개하는 Ajax는 대화식 웹 어플리케이션을 개발하는 기법 중 하나입니다. 이 블로그에서도 적용하고 있는 웹 개발 기술인 Ajax는 페이지의 이동 없이 데이터베이스나 다른 웹 페이지의 내용을 가져올 수 있습니다. 예를 들어, 페이징 없이 게시판의 모든 글들을 한 페이지에 모두 보여줄 수 있는 것입니다. Ajax를 이용하기 위해서는 서버측 웹 프로그래밍 언어를 사용할 수 있어야 하는데, 사용 가능한 웹 프로그래밍 언어에는 제한이 없습니다. 이 글에서는 가장 많이 사용되는 웹 프로그래밍 언어인 PHP를 이용하여 Ajax를 구현하는 방법에 대하여 알아볼 것입니다.


참고하면 좋은 글
http://api.jquery.com/jQuery.ajax/


Ajax의 작동 방식


기본적으로 AjaxAsynchronous Javascript And XML 기술을 구현하려면 서버측 웹 프로그래밍 언어와 자바스크립트를 사용할 수 있어야 합니다. 물론 다른 페이지에 있는 HTML DOM을 불러오는 단순한 Ajax의 경우에는 자바스크립트만으로도 구현하는 것이 가능합니다. 하지만 데이터베이스에 접속을 하거나 새로운 데이터를 생성하는 등의 본격적인 Ajax 기술은 자바스크립트 하나만으로는 구현할 수 없습니다.

사용할 수 있는 서버측 웹 프로그래밍 언어에 제한이 있는 것은 아닙니다. ASP, JSP, Perl, Python 등 모든 웹 프로그래밍 언어에서 Ajax를 구현할 수 있습니다. 이 글에서는 PHP를 이용하여 Ajax를 구현할 것입니다.

Ajax 기술이 등장하면서 인터넷은 더 편리해졌습니다. 사용자는 다른 페이지로의 이동 없이 새로 등록된 글을 읽을 수 있게 되었으며, 검색포털 네이버에서는 실시간 검색어를 진짜 "실시간"으로 확인할 수 있게 되었습니다.


JSON이란 무엇인가?


JSONJavaScript Object Notation은 인터넷에서 자료를 주고 받을 때 그 자료를 표현하는 방법입니다. 자료의 종류에 큰 제한은 없으며, 특히 컴퓨터 프로그램의 변수값을 표현하는 데 가장 적합합니다. 왜냐하면 JSON은 문자열 뿐만 아니라 배열Array, 오브젝트Object 등 컴퓨터의 모든 변수 형태를 문자열로 표현할 수 있기 때문입니다. JSON에서 표현할 수 있는 데이터 형식으로는 다음과 같은 것들이 있습니다.

  • String (문자열): 큰 따옴표로 묶어 표현, ex) "erzsamatory"
  • Number (숫자): 숫자 표현, ex) 1234
  • Array (배열): 대괄호로 묶어 표현, ex) [ 'a', 'b', 'c', 'd' ]
  • Object (객체): 중괄호로 묶어 표현, ex) { key:'value',key2:'value2' }
  • Boolean (참/거짓): TRUE 또는 FALSE, ex) true, false
  • Null

Ajax 기술은 데이터베이스로부터 배열 값을 가져와야 하는 경우가 많은데, JSON은 가공된 컴퓨터 변수를 표현하는 데 사실상 아무런 제약이 없기 때문에, Ajax 기술에서는 JSON이 가장 널리 사용되고 있습니다.

그런데 서버측 웹 프로그래밍 언어와는 달리 자바스크립트는 배열을 정의할 때 개발자가 임의로 배열의 key를 정의할 수 없습니다. 또한 자바스크립트에서 모든 배열은 객체로 인식됩니다. 배열과 객체의 구분이 없는 것이죠. 따라서 서버측 웹 프로그래밍 언어에서 개발자가 직접 정의한 key를 포함하는 배열을 JSON 스트링으로 파싱하는 경우에는 해당 배열이 자동으로 객체Object로 변환됩니다.

이 글에서 함께 사용하는 jQuery에서는 JSON 문서를 읽은 후 자동으로 배열로 변환해주기 때문에, jQuery를 이용한다면 Ajax 기술을 개발하는 것이 매우 간단합니다. jQuery에서 JSON 문서를 불러오는 특별한 메소드가 있는 것은 아니고, Ajax 함수인 $.ajax()를 호출할 때 dataType 속성에 json 값을 넣어주면 jQuery에서 자동으로 JSON 문서를 배열로 변환합니다.


Ajax 개발, PHP에서 JSON 문서 출력하기


모든 서버측 웹 프로그래밍 언어에서 JSON 문서를 출력할 수 있지만, 이 글에서는 PHP에서 JSON 문서를 출력하는 방법에 대하여 알아보도록 하겠습니다. JSON 문서를 출력하려면 가장 먼저 HTTP의 Header를 수정해야 합니다. PHP는 header() 함수를 이용하여 HTTP의 헤더를 조작할 수 있습니다. HTTP 헤더에는 리퍼러 정보, 클라이언트 정보, 쿠키 정보 등이 포함되어 있는데, 문서의 속성을 변경하려면 Content-Type Header를 변경해야 합니다.

PHP에서는 아래와 같은 방법으로 JSON 문서를 출력할 수 있습니다. 아래와 같이 HTTP Header를 JSON 문서로 설정하는 경우에는 HTML 태그를 사용할 수 없습니다. 즉, 화면에 출력되는 최종 결과물은 반드시 완전한 JSON의 구조를 가진 스트링이어야 합니다. 만약, 완전한 JSON 스트링이 아닌 다른 문자열이 1바이트라도 출력되는 경우에는 jQuery에서 오류가 발생하게 됩니다.

<?php
header("Content-Type:application/json");


PHP에서 일반 데이터를 JSON 스트링으로 변환할 때 사용되는 함수는 json_encode()입니다. json_encode() 함수는 첫 번째 매개변수로 넘겨진 데이터를 JSON 스트링으로 변환합니다. 그런데 놀랍게도 이 함수의 첫 번째 매개변수에 올 수 있는 데이터 형태는 정해져 있지 않고, 개발자는 PHP에서 지원하는 모든 데이터 형태를 이 함수에 매개변수로서 넘겨줄 수 있습니다. 다만, 모든 데이터는 UTF-8로 인코딩되어 있어야 합니다.

JSON 스트링을 만들기에 앞서, 우선적으로는 데이터베이스에 연결하여 테이블 데이터를 불러오거나, POST 또는 GET 값을 이용하여 데이터 처리를 하는 등의 각종 데이터를 가공하는 작업이 필요합니다. 이렇게 가공된 데이터를 json_encode() 함수에 전달하여 최종 결과물을 JSON 스트링으로 변환한 후, echo() 또는 print() 함수를 이용하여 변환된 JSON 스트링을 화면에 출력시키면 됩니다.

아래의 소스코드는 ① 데이터베이스 테이블에서 데이터를 가져온 후, ② 데이터베이스로부터 반환된 데이터를 객체 형태로 가공하고, ③ 이렇게 가공된 객체 데이터를 json_encode() 함수에 매개변수로 넘겨주고, ④ 변환된 JSON 스트링을 화면에 출력하는 예제입니다.

<?php
header("Content-Type:application/json");
 
// 1. 데이터베이스에서 데이터를 가져옴
$link = mysqli_connect($host, $user, $password, $dbname);
if ($result = mysqli_query($link, 'SELECT * FROM `temp`', MYSQLI_USE_RESULT)) {
    // 2. 데이터베이스로부터 반환된 데이터를
    // 객체 형태로 가공함
    $o = array();
    while ($row = mysqli_fetch_object($result)) {
        $t = new stdClass();
        $t->uid = $row->uid;
        $t->name = $row->name;
        $t->desc = $row->desc;
        $o[] = $t;
        unset($t);
    }
} else {
    $o = array( 0 => 'empty');
}
 
// 3, 4 최종 결과 데이터를 JSON 스트링으로 변환 후 출력
echo json_encode($o);


생각보다 간단하게 JSON 스트링이 화면에 출력되는 모습을 보고 깜짝 놀라실 것입니다. 만약, 데이터베이스 테이블에서 데이터를 가져오고, 이 데이터를 화면에 뿌리는 작업을 많이 해보셨던 분이라면 위의 소스코드가 매우 쉽게 느껴질 것입니다. 왜냐하면 원래의 데이터베이스 테이블 처리 소스코드에서 추가된 것은 가장 상단에 있는 Content-Type~ 부분과 가장 하단에 있는 json_encode() 함수뿐이기 때문입니다.

위의 소스코드만 잘 알고 있으면 PHP에서 JSON 문서를 만드는 것은 매우 쉽습니다.

Ajax 개발, jQuery에서 JSON 문서 가져오기


이버에는 jQuery의 ajax() 메소드를 이용하여 Ajax 기술을 구현하는 방법에 대하여 알아볼 것입니다. jQuery는 Ajax 기술을 위한 메소드를 여러 개 지원하고 있는데, 그 중에서도 ajax() 메소드가 가장 많이 사용됩니다.

개발자는 ajax() 메소드에 객체를 전달함으로써 Ajax 기술을 구현할 수 있는데, 그 객체에 포함시킬 수 있는 정보는 다음과 같습니다.

  • type: 데이터 전송 방식, ex) get, post
  • url: 요청하는 URL
  • dataType: 전송받을 데이터의 형식, ex) json, xml, text
  • data: 요청하는 URL에 전달하는 데이터
  • success: 서버로부터 데이터를 성공적으로 받았을 때 실행
  • error: 데이터 전송 및 수신에 문제가 발생하였을 때 실행

모든 정보는 하나의 객체로 만들어진 후 ajax() 메소드에 전달되어야 합니다. 아래의 소스코드는 jQuery의 ajax() 메소드를 이용하여 Ajax 기술을 구현하는 예제입니다. PHP 파일에 변수를 전달한 후 결과 값을 받아오는 매우 간단한 형태의 Ajax입니다.

$.ajax({
    type: 'post',
    dataType: 'json',
    url: '/ajax.php',
    data: {val1:'변수1', val2:'변수2'},
    success: function (data) {
        console.log(data);
    },
    error: function (request, status, error) {
        console.log('code: '+request.status+"\n"+'message: '+request.responseText+"\n"+'error: '+error);
    }
});


Ajax 기술을 구현할 때에는 보안을 위하여 데이터 전송 방식을 POST로 하는 것이 좋습니다.

POST 전송 방식을 사용할 때에는 위의 예제에서와 같이 ajax 객체의 data 값을 통하여 요청 파일에 변수 값을 전달할 수 있습니다. 이때 data 값의 데이터 형식은 객체이어야 합니다. 만약 GET 방식을 사용한다면, url에 변수 파라미터를 입력함으로써 요청 파일에 데이터를 전달할 수 있습니다.


개발 방법론 - 게시판 페이징 기능에 Ajax 기술을 활용하는 방법


페이징 기능이란 한 페이지에서 모든 정보를 보여줄 수 없을 때 그 정보를 여러 개의 페이지로 쪼개어 보여주는 기능입니다. 페이징 기능이 적용되었을 때의 가장 큰 장점은 스크롤을 최소화할 수 있다는 점입니다. 만약 페이징 기능이 없다면 사용자는 엄청난 스크롤 분량을 경험하게 될 것입니다.

이 블로그에서는 글 목록을 출력할 때 페이징 기능이 사용되고 있습니다. 아래의 스크린샷과 같이 한 페이지에 보여줄 수 있는 글의 갯수를 초과하는 경우에는 추가적인 페이지가 자동으로 생성됩니다.

한 페이지에서 출력할 수 있는 글의 갯수를 초과하면 자동으로 추가 페이지가 생성됩니다.

한 페이지에서 출력할 수 있는 글의 갯수를 초과하면 자동으로 추가 페이지가 생성됩니다.



하지만 컴퓨터나 인터넷 속도가 느린 환경에서는 정보를 확인하기 위하여 다른 페이지로 이동하는 것이 조금 불편할 수도 있습니다. 또는 휴대기기와 같이 무선 데이터 사용량을 최소한으로 줄여야 하는 환경에서도 다른 페이지로의 이동은 무선 데이터 사용량을 늘리기만 할 뿐입니다.

그런데 Ajax 기술이 페이징 기능과 합쳐진다면 위의 문제점들을 모두 해결할 수 있습니다. Ajax 기술이 적용된 페이징 기능은 다른 페이지로의 이동을 필요로 하지 않고, 서버로부터 가져오는 데이터는 목록을 만드는데 필요한 최소한의 정보이기 때문에 무선 데이터 사용량 과다 문제도 발생하지 않습니다.

그렇다면 Ajax 기술을 페이징 기능에 접목하기 위해서는 어떻게 해야 할까요? 지금부터 Ajax 기술을 페이징 기능에 접목하는 방법에 대하여 알아보도록 하겠습니다.


Ajax 기술과 페이징 기능


그런데 Ajax 기술이 적용된다고 하여 페이징 기능이 완전히 필요하지 않다는 것은 아닙니다. 기본적인 페이징 기능은 갖추고 있어야만 필요한 데이터를 서버에 요청할 수 있기 때문입니다. 현재 페이지가 어디에서부터 어디까지의 글을 출력하고 있는지 정확히 계산할 수 있어야 Ajax 기술을 통하여 서버에 올바른 목록 데이터를 요청할 수 있는 것입니다.

고전적인 페이징 기능에서는 GET 방식을 이용하여 현재의 페이지 위치를 서버에 전달하였습니다. 그리고 사용자는 GET의 페이지 위치 값을 변경함으로써 현재의 페이지 위치를 변경할 수 있었습니다. 하지만 Ajax 기술이 접목된 페이징 기능(이하 Ajax 페이징 기능)에서는 더 이상 GET 방식을 사용하지 않습니다.

Ajax 페이징 기능에서는 현재의 페이지 위치를 자바스크립트 변수에 저장해둡니다. 이 변수는 현재의 페이지 위치를 말하는 것이며, 서버에서 그 다음 페이지 위치의 데이터를 가져왔을 때 이 변수의 값은 1 증가하게 되는 것입니다.

기존의 고전적인 페이징 기능과 비교해보았을 때 기능상의 큰 차이가 있는 것은 아니기 때문에, 이미 페이징 기능을 사용하고 있는 게시판이라면 Ajax 기술을 접목시키는 것이 그렇게 어렵지 않습니다.

var current_page = 1;


그렇다면 다음 페이지 위치의 목록 데이터는 어떻게 가져올 수 있을까요?

개발자는 다음 페이지 위치를 서버에 전달함으로써 다음 페이지 위치의 목록 데이터를 가져올 수 있습니다. Ajax 기술이 적용되어야 하므로 이 모든 과정은 페이지 이동 없이 이루어져야 합니다. 개발자가 서버에 다음 페이지 위치를 전달하는 방법은 다음과 같은 방식이 될 것입니다.

var next_page = current_page + 1;
$.ajax({
    type: 'post',
    dataType: 'json',
    url: '/ajax.php',
    data: {page:next_page},
    success: function (data) {
        // 목록을 생성하는 스크립트
    },
    error: function () {
         console.log('error');
    }
});


개발자가 ajax.php 에 다음 페이지 위치를 전달하면 서버측에서는 데이터베이스에 연결하여 다음 페이지 위치의 목록 데이터를 불러옵니다. 이것은 고전적인 페이징 기능과 동일한 것으로 페이지 위치 정보를 GET 방식으로 전달하느냐 Ajax + POST 방식으로 전달하느냐의 차이점만 있을 뿐입니다.

아래의 예제는 페이지 당 출력되는 레코드의 수를 10개로 했을 때의 ajax.php 소스코드 일부입니다.

<?php
header("Content-Type:application/json");
 
// 데이터베이스에서 데이터를 가져옴
$link = mysqli_connect($host, $user, $password, $dbname);
$limit = 10;
$offset = ($_POST['page'] - 1) * $limit;
$query = 'SELECT * FROM `temp` ORDER BY `uid` DESC LIMIT '.$offset.', '.$limit;
if ($result = mysqli_query($link, $query, MYSQLI_USE_RESULT)) {
    $o = array();
    while ($row = mysqli_fetch_object($result)) {
        $t = new stdClass();
        $t->uid = $row->uid;
        $t->name = $row->name;
        $t->desc = $row->desc;
        $o[] = $t;
        unset($t);
    }
} else {
    $o = array( 0 => 'empty');
}
 
echo json_encode($o);


위의 소스코드는 데이터베이스 테이블의 내용을 JSON 스트링으로 출력합니다. 자바스크립트에서는 이 내용을 이용하여 새로운 목록을 출력하면 됩니다. jQuery를 이용하여 새로운 목록을 출력하고자 한다면 그 방법은 다음과 같습니다.

실제로 게시판에서 필요로 하는 데이터는 매우 많지만 소스코드의 간결성을 위하여 이 글에서는 HTML 목록 태그와 함께 매우 간단한 정보만으로 스크립트를 구성하였습니다.

success: function (data) {
    if (data != 'empty') {
        $.each(data, function(key, val) {
            $('ul#list').append('<li class="item item-'+val.uid+'">'+val.name+' / '+val.desc+'</li>');
        });
    }
}


스크롤바가 문서의 마지막까지 이동되었을 때 또는 사용자가 문서 하단에서 더 보기 버튼을 눌렀을 때, 위의 스크립트가 실행되어 다음 페이지 위치의 목록을 불러와 화면에 출력해주면 사용자는 페이지의 이동 없이 다음 페이지의 새로운 목록을 곧바로 확인할 수 있는 것입니다.

그러나 실제로 이 글에서 소개하는 스크립트만으로는 Ajax 페이징 기능을 공식적으로 서비스할 수 없습니다. 왜냐하면 실시간으로 목록을 불러오는 기능까지는 구현되었으나, 사용자가 선택한 글을 읽은 후 다시 목록 페이지로 돌아왔을 때 원래의 페이지 위치까지 자동으로 이동하는 기능은 구현되지 않았기 때문입니다.

이 글은 Ajax 기술을 게시판 페이징 기능에 어떻게 접목시킬 수 있는지 그 방법에 대하여 알아보는 것을 목적으로 합니다. 여기에서 더 나아가는 기술은 이 글의 주제와 맞지 않으므로 Ajax 페이징 기능 개발 방법은 여기까지 설명하도록 하겠습니다.


마무리 - 매우 유용한 Ajax 기술


지금까지 Ajax 기술을 PHP와 자바스크립트 jQuery에서 구현하는 방법에 대하여 알아보았습니다. 이 글에서는 매우 간단한 예제만을 살펴보았으나, 이 예제 스크립트를 적절히 활용한다면 매우 유용한 기능을 개발할 수 있을 것입니다.

Ajax 기술은 현대 인터넷에서 꼭 필요한 기술이 되었습니다. 현재 인터넷 환경은 매우 빠르고 편리해졌습니다. 지금처럼 편리한 인터넷 환경이 될 수 있었던 것은 Ajax와 같은 새로운 기술이 지속적으로 개발되었기 때문입니다. Ajax 기술을 활용하여 더욱 편리한 홈페이지, 블로그, 게시판 등을 만들어보시기 바랍니다.
http://www.erzsamatory.net/trackback/220

건전한 댓글 문화를 만들어주시기 바랍니다 ^^
불건전한 댓글이 등록되는 경우 관리자의 임의적 판단으로 삭제될 수 있음을 미리 공지드립니다.

비밀글로 작성하기
  1. song
    song
    2016/08/05 13:26
    <?php
    header("Content-Type:application/json");

    // 1. 데이터베이스에서 데이터를 가져옴
    $link = mysqli_connect($host, $user, $password, $dbname);
    if ($result = mysqli_query($link, 'SELECT * FROM `temp`', MYSQLI_USE_RESULT)) {
    // 2. 데이터베이스로부터 반환된 데이터를
    // 객체 형태로 가공함
    $o = array();
    while ($row = mysqli_fetch_object($result)) {
    $t = new stdClass();
    $t->uid = $row->uid;
    $t->name = $row->name;
    $t->desc = $row->desc;
    $o[] = $t;
    unset($t);
    }
    } else {
    $o = array( 0 => 'empty');
    }

    // 3, 4 최종 결과 데이터를 JSON 스트링으로 변환 후 출력
    echo json_encode($o);
    이 코드를 이용해서 값 넣구
    $.ajax({
    type: 'post',
    dataType: 'json',
    url: '/ajax.php',
    data: {val1:'변수1', val2:'변수2'},
    success: function (data) {
    console.log(data);
    },
    error: function (request, status, error) {
    console.log('code: '+request.status+"\n"+'message: '+request.responseText+"\n"+'error: '+error);
    }
    });
    이 코드를 이용해서 값을가져올때 data: {val1:'변수1', val2:'변수2'}, 여기에 들어가야 하는 변수는 정확하게 뭔가요?
    • Walter Erzsa
      Walter Erzsa
      2016/08/05 22:13
      자바스크립트에서 PHP 스크립트에 전송하는 변수는 PHP 스크립트에서 필요로 하는 변수입니다. 변수를 필요로 하지 않는다면 변수를 넣지 않아도 됩니다.

      일단, 변수는 사용자 아이디, 패스워드, 게시물 번호, 페이지 번호 등을 보냅니다. 이렇게 변수를 보내면 PHP 스크립트에서 데이터 처리 후 결과물을 반환하는 것입니다.
  2. song
    song
    2016/08/05 13:27
    $o를 넣는 건가요? 아니면 $t->uid이거나 $row->uid;를 가져다 써야하는건가요
    • Walter Erzsa
      Walter Erzsa
      2016/08/05 22:17
      $o 변수를 이용하는 이유는 JSON 최종 결과물을 화면에 출력하기 위함입니다. $t 변수는 임시변수로 포인터가 위치한 곳의 데이터를 포함하고 있습니다. 이 데이터를 $o 변수에 모두 저장하는 것이 필요합니다.
  3. gang
    gang
    2016/09/21 15:57
    혹시 json으로 넘어온 data가 배열/ 객체시 어떻게 출력해 줘야하나요
    for문을 돌려도 계속 에러가 나서요
  4. 박상빈
    박상빈
    2016/10/06 17:14
    설명도 너무 잘하시네요 이해가 쏙쏙갑니다~대박입니다. 제가 찾던 자료네요 ㅠㅠㅠ 너무 감사합니다. 복받으시길
  5. 2016/10/21 15:51
    짜릿한 만남~ 오늘밤 만나 볼까요??

    매일 매일 같은 섹.파가 지겨우 세요??
    그럼 지금 바로 새로운 섹.파를 찾아서 떠나볼까요?
    대한민국 섹.파 검색, 스와핑, 초대남, 성. 인 만남을 무료료 할 수 있는곳~!!!

    "코코킹"에서 그 시작을 해보세요.


    주소1: http://q.gs/AN6Sl
    주소2: https://twitter.com/sexking38802406
  6. 2017/01/06 17:46
    와. 말도안될정도로 잘 설명해주셨네요. 너무 감사합니다. 글을 쓸 수 밖에 없네요 ^^