티스토리 뷰

Ajax를 사용한amazon검색을PHP로 만들자


상열쇠 츄우시
호라이즌·디지털·엔터프라이즈
2005/10/4

Ajax는 금년 매우 핫인 화제의 기술이다.
@IT(을)를 시작해 다양한 곳에서도Ajax에 대한 기사가 눈에 띄게 되었다.
여기에서는 , 필자가 종사하고 있는PHP근처에서의Ajax의 움직임에 대해 소개해 나가고 싶다.


 

 주목의Ajax

 Aajax(와)과는 「Asynchronous JavaScript + XML」의 약어이다. JavaScript네원않고와 알려진 클라이언트(통상 웹 브라우저) 사이드의 기술이며 , 거기로부터XMLHttpRequest라는 것을 이용해 , 페이지 추이를 하지 않고 서버/클라이언트간에 자꾸자꾸 데이터 교환을 해 나가는 기술이다. 이것과DHTML를 병용 하는 것으로 이른바Ajax가 된다.

 이 근처의 자세한 내용은Ajax추진 위원회에 의한 「낡고 새로운Ajax의 진실을 판별한다」를 참고로 하면 좋을 것이다.

   PHP(와)과Ajax의 관계

 PHP(은)는 서버 사이드 기술 , 전술대로Ajax로 이용되는JavaScript은 클라이언트 사이드 기술이다. 통상의 처리에서는JavaScript에 처리가 추이하면(자) 서버측에서는 다음의 페이지에 추이할 때까지 굳이 할 수 없었다.

 예외적으로 「0픽셀 프레임」이라고 불린다 , 말하자면 「안보이는 프레임」을 이용해 은폐 프레임을 사용해 서버간 통신을 해 , 실제로 사용하는 프레임의 표시에 반영한다고 하는 「는 서버/클라이언트간 동기」등의 수법도 옛부터 있었지만 , 프레임 고 의 문제(URL의 문제등 ) 도 적지 않았다.

도1 0픽셀 프레임의 개요

 Ajax(은)는XMLHttpRequest이라는 것을 이용해 서버와 비동기 통신을 실시한다. 그 때문에 , 쓸데없는 프레임도 필요없게 리로드레스인 컨텐츠를 작성할 수가 있다.

 다만Ajax에 문제점이 없는 것은 아니다. Ajax의 문제는 이하와 같은 점을 들 수 있을 것이다.

·XMLHttpRequest은 브라우저 의존인 (Internet Explorer와Mozilla밖에 대응하고 있지 않는 경우가 많다 )
·DHTML을 사용하지 않으면 화면 내용을 변경할 수 없기 때문에 약간 테크니컬
·XML에서의 데이터 인도가 되므로 처리가 비교적 무겁다

 그러나 상기의 문제는XMLHttpRequest이나DHTML묘화를 랩핑 하는 라이브러리나 체제 , 등의 등장에서 서서히 해결하고 있는 문제이기도 하다.

   Ajax(을)를 사용한 웹 어플리케이션의 예

 Ajax(을)를 사용한 웹 어플리케이션은 벌써 몇개인가 있어 ,@IT그렇지만 소개되고 있지만 , 이제(벌써)1번 , 아래와 같이에 들어 두자.

●gmail

http://gmail.google.com/

 아마Ajax의 달리기가 되는 웹 어플리케이션으로 ,Google가 개발한 것이다. 지금까지는 클릭할 때마다 화면이 바꾸고가 있던 웹 메일이 거의 그대로의 상태로 자꾸자꾸 내용이 바뀌어 가는 참신한 것이었다.

●Google 맵

http://maps.google.co.jp/

 이것도Ajax의 가능성을 나타낸 웹 어플리케이션의1개일 것이다. gmail(와)과 같이Google가 개발한 것이다.

●포토창고

http://photozou.jp/

 이른바 오해를 두려워하지 말고 말하면(자) 「일본의Flickr」이다. 이 웹 어플리케이션에서는 통상 화상의 업 로드에는 파일 선택을 실시하지만 , 파일 선택을 하는 것만으로 프리뷰가 표시되게 되어 있다. 이 기술에는Ajax도 병용 되고 있다.

●ajax ssh

http://ajaxssh.bz2.jp/
http://ajaxssh.bz2.jp/demo

 약간 강행이지만Ajax을 이용해ssh환경을 구축한다. HTTP(은)는 통상1리퀘스트 마다 처리를 종료하지만 ,ssh은ssh으로서 세션을 절단 할 때까지 영속적으로 접속하고 있기 (위해)때문에 , 그 문제 해결 등에 테크닉이 사용되고 있다.


   Ajax(을)를 이용한 어플리케이션의 가능성

●그룹웨어
그룹웨어(정도)만큼 개인 마다 화면을 커스터마이즈 하고 싶어지는 어플리케이션도 적을 것이다. 지금까지의 웹 어플리케이션에서는 곤란했던 개인별의 화면 커스터마이즈가 보다 고도로 할 수 있을 가능성이 있을 것이다.

●웹 메일
gmail을 시작해 벌써 몇개의Ajax웹 메일이 출현하고 있지만 , 향후도 서서히 웹이 아닌 통상의 메일러에 가까운 조작감의 웹 메일이 출현할 것이다.

●웹 채팅·게시판
지금까지의 웹 채팅은 송신할 때마다 화면이 바뀌고 있었다. 혹은Flash이나Java Applet등 을 사용 하지 않을 수 없었다. 이것들이Ajax로 다른 단면을 찾아낼 수가 있을지도 모른다.

●게임
지금까지는Flash에 의지하고 있던 것 같은 게임이나 그것들 보다 더 열중한 게임을 실현될 수 있을지도 모른다.

 그 외 아이디어 나름으로 여러 가지 용도는 있을 것이다.

   Ajax(을)를 취급하기 위한PHP라이브러리들

 현재 , 인터넷상에서 공개되고 있는PHP으로 이용할 수가 있는Ajax라이브러리를 소개하고 싶다. 필자 자신 , 이 라이브러리의 편리함에는 놀라게 해졌으므로 , 아직 손대지 않았다고 하는 경우 , 이 기회에 확인되어 어떻게일까.

●SAJAX http://www.modernmethod.com/sajax/
 비교적 옛부터 있는 라이브러리이다. 클래스화 되지 않고 범용성이 부족하다. 유감스럽지만 「PHP그렇지만 취급할 수 있다」라고 하는 것을 초기의 무렵에 넓힌 시점에서 역할을 끝냈다고 말할 수 있자.

●AjaxAC http://ajax.zervaas.com.au/
 여름경에 처음으로 릴리스 된 라이브러리이다. 비교적 위화감 없게 사용할 수 있는 라이브러리이다. DHTML에 관해서도 몇개인가 생성하기 위한 라이브러리도 준비되어Google Suggest와 같은 사이트를 간단하게 구축할 수 있는 것을 나타내 주었다.

●PEAR::HTML_Ajax http://pear.php.net/package/HTML_AJAX/
 8달이 되어PEAR정식 추가된 패키지. PEAR그래서 인스톨도 용이해 라이브러리로서의 질도 주목도도 높다.

●php-jsons http://www.aurore.net/projects/php-json/
 이것은 정확하게는Ajax라이브러리가 아니고 ,JavaScript의 오브젝트를 취급하기 위한PHP확장 모듈이다. 지금까지의 라이브러리와 달라 ,C언어로 빌드를 하는PHP확장 모듈이다.
 이 라이브러리를 이용하는 것으로JavaScript의 배열과PHP의 배열을 상호 교환할 수가 있어XML는 아니게JavaScript배열로 서버/클라이언트간의 통신을 실시하는 것이 용이하게 할 수 있게 된다. XML에의 변환이 없기 때문에 , 메리트가 약간 고속처리를 실시할 수가 있는 것에 머무르고 있는 것이 유감.

●NAJAX http://najax.sourceforge.net/dev/
 9달이 되어 나온 라이브러리다. 아직 자세한 것은 모르지만 , 공식 페이지에 몇개의 샘플이 게재되고 있다.

●pEcho2 http://www.nextapp.com/products/echo2/
 비교적 일찍부터 존재한Ajax체제로 , 벌써 많은 샘플이 게재되고 있는 것으로부터 많은 가능성을 느끼게 한다. 온라인 데모를 보면(자) 매우 다채로운 일이 생기는 것을 알 것이다.


 AjaxAC(을)를 사용한다

 여기에서는PHP용무의Ajax라이브러리인AjaxAC의 실제의 사용예를 소개하자. AjaxAC(은)는 체제를 자칭하고 있지만 , 주로 실질 시간관리와XMLHttpRequest관리와 리퀘스트시의 이벤트 핸들링을 실시한다. 이것은Ajax을 이용하는데 거의 최저한 필요한 기능이 된다.

·샘플을 사용해 , 개조해 본다

 AjaxAC에는 이하의3개의 샘플이 동고 되고 있다.

ArithmeJax 2개의 정수치를 바탕으로 사칙 연산을Ajax을 이용해 다이나믹하게 실시하는 샘플
CountryRegionCityJax 지역에서 나라 , 도시명등을Ajax을 이용해 다이나믹하게 셀렉트 박스로 설정해 , 선택시키는 샘플
GoogleSuggestCloneJax GoogleSuggest을 닮은 것을Ajax을 이용해 작성하는 샘플

CountryRegionCityJax

 샘플로서 비교적 간단한 구조가 되어 있어 , 개조하기 쉬운 것 같은 「CountryRegionCityJax」을 움직여 보자 (ArithmeJax는 연산할 뿐(만큼)이고 ,GoogleSuggestCloneJax는MySQL을 동작시키지 않으면 안 된다 ).

 우선은AjaxAC을 공식 사이트로부터 취득해 , 어카이브(archive)를 전개한 후 , 「lib」디렉토리를 브라우저로부터 액세스 할 수 있는 장소에 카피한다.

 이번은 「/var/www/html/ajaxac/」에 카피하기로 한다 (집필시 현재AjaxAC의 최신판은0.4.4). CENTER:AjaxAC의 카피예 tar jxvf ajaxac-0.4.4.tar.bz2, 혹은 bzip -dc ajaxac-0.4.4.tar.bz2 | tar xvf -,cp -pr ajax-0.4.4/lib /var/www/html/ajaxac 다음에 「examples/CountryRegionCityJax」의 내용을 브라우저로부터 액세스 할 수 있는 장소에 카피한다.

 카피가 완료하면(자)CountryRegionCityJax.php에 아래와 같이 코드를 추가해 ,include_path에AjaxAC의 코어가 읽히도록(듯이) 한다.

개변했다CountryRegionCityJax.php의 일부
$include_path = ini_get( "include_path"); <= 이 행을 추가
ini_set( "include_path",
    $include_path.":/var/www/html/ajaxac/");
<= 이 행을 추가
require_once(CountryRegionCityJax.class.php');

 후 는 브라우저로index.php에 액세스 하는 것만으로 있다. 화면에는3개의 셀렉트 박스가 나타나 각각Country→State/Region→City선택하게 되어 있다. 이것은 셀렉트 박스1개1개의 선택의 백그라운드에서Ajax가 다음의 데이터를 읽어들이고 있다.

 덧붙여서 읽어들이고 있는 데이터는 동일 디렉토리에 있는 「locations.txt」이다. 파일을 열면(자) 단순한CSV이므로 , 국명에 일본도 추가해 보자.

개변했다locations.txt의 일부
United States,Texas,Houston
United States,Texas,San Antonio
Asia,Japan,Hokkaido
<= 이 행을 추가
Asia,Japan,Tokyo <= 이 행을 추가
Asia,Japan,Osaka <= 이 행을 추가
Asia,Japan,Fukuoka <=이 행을 추가

 이것으로 일본에 관련하는 지역을 선택할 수 있게 된다.

주의:Ajax는 브라우저의 캐쉬의 영향으로 생각했던 대로 동작하지 않는 경우가 많다. 그렇게 말했을 경우는 브라우저의 캐쉬를 한 번 클리어 해 보자.

■GoogleSuggestCloneJax

 마지막에GoogleSuggestCloneJax를 움직여 보자. 이것을 움직이려면MySQL의 준비가 필요하다. 우선은 적당한 테이블을 작성해 ,GoogleSuggestCloneJax의 디렉토리에 존재하는 「data.sql」을mysql커멘드(참조:연재 기사 「쾌속MySQL으로 데이타베이스 어플리! 」) 등으로 실행하자.

MySQL의 데이타베이스를 작성
$ mysqladmin -u root -p create test_ajaxac_google
$ cat data.sql | mysql -u root -p test_ajaxac_google

 덧붙여서 이data.sql는Google이 표시하는 검색 결과와 같은 것을 미리 준비한 데이터이다. 즉 여기서 준비된 것 밖에 결과적으로 나오지 않는 것을 미리 알아 두면 좋다.

 다음에 방금전의CountryRegionCityJax와 같게include_path의 수정을 실시하는 처리를GoogleSuggestCloneJax.class.php에 추가한다. 한층 더 클래스 「GoogleSuggestCloneJax」에 있는 프롭퍼티로부터 데이타베이스의 설정을 실시한다.

설정해야 할 프롭퍼티
프롭퍼티명 의미
$db_hostname localhost MySQL서버의 호스트명
$db_username 접속 어카운트명 MySQL서버에의 접속 유저명
$db_password 접속 패스워드 MySQL서버에의 접속 유저명
$db_database test_ajaxac_google 데이터가 존재하는 데이타베이스명
$db_table google_suggest_clone_data 데이터가 존재하는 테이블명

 후 는index.php에 액세스 해 , 몇개인가 키워드를 넣어 보면 좋을 것이다. data.sql에 존재하는 키워드이면GoogleSuggest같은 표시를 할 것이다.



 Amazon상품 검색 폼에
 GoogleSuggestCloneJax(을)를 개조한다

■AmazonSuggestCloneJax  

 Amazon상품 검색을 ,AjaxAC의 샘플의 것GoogleSuggestCloneJax을 개조해 만들어 보자. 이 개조는GoogleSuggestCloneJax을 베이스로 일본Amazon의 상품을 검색하는 폼이 된다.

 덧붙여AmazonSuggestCloneJax의 이름은 단지GoogleSuggestCloneJax의Google를Amazon로 변경한 것만으로 특히 이유는 없다.

 GoogleSuggestCloneJax(으)로부터 비교하면(자) , 이하의 변경 뿐이다.

·index.php의 거의 전면 재작성
·GoogleSuggestCloneJax::getSuggestions()의 전면 재작성

 덧붙여 문의처는MySQL은 아니게 일본amazon(amazon.co.jp)이 되므로 ,SQL등은 필요없다. 다만 ,PEAR::Services_Amazon을 필요로 하므로 인스톨 해 두자.

 그리고 ,Services_Amazon는 정식판은 커녕 아직alpha판도 아니기 때문에 패키지명에 버젼 번호를 부가하지 않으면 인스톨 할 수 없다. PHP의 버젼이나 인스톨제의 각종PEAR패키지의 버젼에 따라서는 잘 인스톨 할 수 없는 경우가 있을지도 모른다. 필자의 환경(CentOS 4.1) 에서는 아래와 같은 차례PEAR패키지를 인스톨 하는 것으로Services_Amazon를 인스톨 할 수 있었다.

Services_Amazon의 인스톨
# pear upgrade XML_Parser Net_Socket
# pear install XML_Util XML_Serializer-beta
# pear install Net_URL
# pear install HTTP_Request HTTP_Client
# pear install Services_Amazon-0.2.0

 최근의pear커멘드는install에--alldeps서브 옵션을 부가하는 것으로 , 차례로 밝혀짐에 의존관계(dependencies)를 해결해 주지만 ,Services_Amazon에 관해서는 최종적으로 의존 해결을 실시할 수가 없었다. 그리고 , 일본Amazon의Web서비스를 사용하기 위해서(때문에) 아소시에이트ID를 취득해야 하는 (통상 단지 신청하면ID이 발행된다 )

Amazon의 아소시에이트ID를 취득하는

 그러면 우선index.php이다. 이것은 비교적 많이 개변을 하고 있다.

저자가 작성한index.php샘플

 그러나 내용적으로는 매우 간단한 것으로 , 아마 본 채로 있다. 전반이AjaxAC를 이용한 검색 관련의 처리 , 후반이Services_Amazon를 이용했다amazon.co.jp의 검색 결과의 표시이다.

 다음에 연구 최종 단계의 것GoogleSuggestCloneJax.class.php이다. 아래와 같이는GoogleSuggestCloneJax::getSuggestions()의 발췌이다.

GoogleSuggestCloneJax.class.php의 발췌(amazon와의 액세스 부분)
function getSuggestions($prefix, &$arr)
{
  $amazon = &new Services_Amazon('0AW6NMZ572Z4M7VHCRR2',
      'yokukitanaii-  22', 'jp',
      'http://xml.amazon.co.jp/onca/xml2');
  $products = NULL;
  $prefix = ltrim(preg_replace('/[^a-z0-9_. ]/', '',
      strtolower($prefix)));
  $prefix = preg_replace('/\s+/', ' ', $prefix);
  $products = $amazon->searchKeyword($prefix,
      'All Modes', 1);
  if(PEAR::isError($products)) {
     $arr[] = array( $prefix, "Error:".$products->message);
  } else {
    for ( $i = 0; $i < $this->suggestion_limit && empty( $products[ $i]) != TRUE; $i++) {
      if ( empty( $products[ $i][ "name"]) != TRUE) {
        $arr[] = array(
            htmlspecialchars($products[ $i][ "name"]),
            $products[ $i][ "listprice"]);
      }
    }
  }
}

 이것은 단지amazon.co.jp로부터 상품의 정보를 취득해 ,$arr라고 하는 변수에 격납해 가고 있을 뿐이다. 덧붙여 이GoogleSuggestCloneJax특유의 배열의 사용법으로 ,$arr에는array( "좌측의 캐릭터 라인", "우측의 캐릭터 라인")을 넣지 않으면 갈 수 없게 되어 있다. 그리고 , 양요소 모두 반드시 캐릭터 라인이 아니면 안된다.

 GoogleSuggestCloneJax(은)는 이하와 같이 되어 있으면 문제 없을 것이다.

$arr[]의 예
$arr[] = array( "Japanese", "10000");
$arr[] = array( "English", "7000");

 이번은Amazon.co.jp으로부터 의 돌아가 값으로부터 , 상품명과 상품 가격을 각각 격납했다.

그리고 , 도중 에

$prefix = preg_replace_callback( "/%u[0-9A-Za-z]{4}/",
      array( $this, "escapeToUtf8"), $prefix);

라고 하는 코드가 있지만 ,amazon은 일본어등의 멀티 아르바이트는 「%u####」이라고 하는 이스케이프 된 캐릭터 라인을 돌려주어 오므로 ,UTF-8로 변환하는 함수 「escapeToUtf8」을 호출하고 있다.

GoogleSuggestCloneJax.class.php의 발췌(문자 encode의 변환 부분)
// %u####라고 하는 이스케이프 코드를UTF-8encode에 되돌린다
function escapeToUtf8( $codes) {
  $char = &quot;&quot;;
  foreach( $codes as $code){
    $code = intval( substr( $code, 2), 16);
    if( $code &lt; 0x7F) { // 7bit
      $char .= chr( $charcode);
    } else if ( $charcode &lt; 0x800) { // 14bit
      $char .= chr(0xC0 | ($charcode / 64));
      $char .= chr(0x80 | ($charcode % 64));
    } else {
      $char .= chr(0xE0 | (($charcode / 64) / 64));
      $char .= chr(0x80 | (($charcode / 64) % 64));
      $char .= chr(0x80 | ($charcode % 64));
    }
  }
  return $char;
}

 마지막에AjaxAC의 키 핸들링에서는 일본어가 입력되었을 경우에 부적당이 있다. 이것은 영 숫자등의 입력이 전제가 되어 있는 부분이 있기 (위해)때문이다.

 이것은googlesuggestclone.js의7행목 근처의 수정으로 대처할 수 있다.

수정원의 코드
if (q.length == 0) || !gsc_basicmatch.test(q)) {
수정 후의 코드
if (q.length == 0) {

 이것으로 일본어만의 입력에서도amazon에의 검색이 실행된다.

?:itmedia

 유감스럽지만Web서비스에서는 소트등의 기능이 없기도 하고 , 검색 키워드 상태를 지정하거나 (전문 일치나 방향 일치 등 ) 할 수 없기 때문에 , 너무 생각했던 대로의 검색 결과는 되지 않지만 , 잘 하면 재미있는 일이 생길지도 모른다.

   통계

 AjaxAC(은)는 연구 최종 단계는AjaxACApplication이라고 하는 클래스를 기본으로 리퀘스트를 처리한다. 이 클래스는 약간 복잡해서 , 다음번 이후에서의 설명에 돌린다. 프론트엔드는 대개 아래와 같이 처리를 한다.

index.php의 모형예
// AjaxACApplication의 상속 클래스
$ajax = &new GoogleSuggestCloneJax();
$ajax->handleRequest();
// Ajax초기화 코드 출력
$ajax_core = $ajax->loadJsCore(true)
echo <<<EOD
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>amazon검색</title>
<!-- AjaxAC프론트엔드 코어 -->
$ajax_core
<!-- 표시 관련CSS -->
<link rel="StyleSheet" type="text/css" href="googlesuggestclone.css" />
</head>
<body>
<form>...</form>
EOD;
// 폼과 이벤트 요소명이 관련짓고
echo $ajax->attachWidgets( array( ...));
// Ajax열매 처리 코드 출력
echo $ajax->loadJsApp(true);

 이만큼이라면 텍스트 필드가1개의 인크리멘탈 검색과 같은 것 밖에 할 수 없지만 , 자신이 운용하고 있는 브로그나 게시판에 검색 결과를 부가하는 경우에는 충분할 것이다.

 Ajax(은)는 그 기술상 , 그것을 전면에 내세운 컨텐츠를 만드는 것이 모두가 아니고 , 어디까지나 유저 인터페이스의 향상을 위한 기술의1개라고 하는 것을 잊어서는 안된다.

 다음번은AjacAC혹은 다른 라이브러리를 파고 들어보다 적극적으로 복잡한Ajax을 실현해 보고 싶다고 생각한다.

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크