PHP는 HTTPService말고 방법이 없을까 하고 찾아보니, Zend에서 AMF를 이용하여 개발한게 있군요. Adobe의 공식 지원으로 만들어진거라 빠르리라고 생각합니다^^ (적어도 HTTPService보단 빠르겠죠!)

암튼, BlazeDS를 하셨다면 그리 어렵지 않군요.
이번에도 간단하게 소녀시대예제를 통해...접근해봅시다-_-;

간단히 데이터를 불러오고, 저장도 해보는 그런 애플리케이션을 만들어봅시다.

우선 Eclipse에서 php가 가능하도록 해야하는데요. 뭐 그냥 editplus에서 해도 상관없습니다. Zend홈페이지에 가면 자기네들 IDE깔라고 합니다-_-; Zend Studio라는 게 있네요. 뭐 php단은 netbeans를 이용해서 개발하셔도 되고, 이클립스에 있는 PDT를 추가하셔서 해도 상관없어요~ ^^ 전 NetBeans를 선호합니다. 좋아요!

DB입니다.
DROP TABLE IF EXISTS `sosi`.`sosi`;
CREATE TABLE `sosi`.`sosi` (
`idx` int(10) unsigned NOT NULL AUTO_INCREMENT,
`sosiname` varchar(45) NOT NULL,
`height` int(10) unsigned NOT NULL,
`blood` varchar(45) NOT NULL,
PRIMARY KEY (`idx`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;

INSERT INTO `sosi` (`idx`,`sosiname`,`height`,`blood`) VALUES
(1,'윤아',166,'B'),
(2,'수영',170,'O'),
(3,'효연',160,'AB'),
(4,'유리',167,'AB'),
(5,'태연',162,'O'),
(6,'제시카',163,'B'),
(7,'티파니',162,'O'),
(8,'써니',158,'B'),
(9,'서현',168,'A');

우선 Flex Project를 만듭니다.
여기서 Application server type을 php로 하세요~ php로 하게 되면 설정된 폴더로 swf를 바로 위치시킬 수 있어요!
Project name은 ZendAmfTest -> Web root는 아파치가 돌아가는 폴더를 지정하면 됩니다.
저는 C:\Program Files\Apache Software Foundation\Apache2.2\htdocs여기군요.
Root URL은 http://localhost/ Finish때려주면 ZendAmfTest-debug폴더에 swf가 생기죠.

요 아래 주소에서 ZendAMF를 받을 수 있습니다.
http://framework.zend.com/download/amf
받은 다음에 압축을 풀면 library폴더 안에 Zend라는 폴더가 있는데 통채로 복사해서 src폴더 아래에 놓습니다.

그리고 php파일을 하나 만드세요. ValueObject입니다. Java에서 bean같은..-_-;
SosiVo.php
<?php
class SosiVo {
public $idx;
public $sosiname;
public $height;
public $blood;
}
?>

이제 서비스를 하나 만들어봅시다. SosiService입니다.
SosiService.php
<?php
require_once 'SosiVo.php';

//conection info
define("DATABASE_SERVER", "localhost");
define("DATABASE_USERNAME", "root");
define("DATABASE_PASSWORD", "mudchobo");
define("DATABASE_NAME", "sosi");

class SosiService {
public function getData() {
$mysql = mysql_connect(DATABASE_SERVER, DATABASE_USERNAME,
DATABASE_PASSWORD);
mysql_select_db(DATABASE_NAME);
$query = "SELECT idx, sosiname, height, blood FROM sosi";
$result = mysql_query($query);

$ret = array();
while ($row = mysql_fetch_object($result)) {
$tmp = new SosiVo();
$tmp->idx = $row->idx;
$tmp->sosiname = $row->sosiname;
$tmp->height = $row->height;
$tmp->blood = $row->blood;
$ret[] = $tmp;
}
mysql_free_result($result);
return $ret;
}
}
?>

php의 array는 ActionScript3의 array와 호환됩니다.
서비스를 만들었으니 EndPoint페이지를 만들어줘야합니다.
amf.php
<?php
require_once 'Zend/Amf/Server.php';
require_once 'SosiService.php';

$server = new Zend_Amf_Server();
$server->setClass("SosiService");
$server->setClassMap("SosiVo", "SosiVo");
echo($server -> handle());
?>

이제 이것을 연결시켜줄 service-config.xml파일을 만들어야합니다.
<?xml version="1.0" encoding="UTF-8"?>
<services-config>
<services>
<service id="amfphp-flashremoting-service"
class="flex.messaging.services.RemotingService"
messageTypes="flex.messaging.messages.RemotingMessage">
<default-channels>
<channel ref="my-zend"/>
</default-channels>
<destination id="zend">
<properties>
<source>*</source>
</properties>
</destination>
</service>
</services>
<channels>
<channel-definition id="my-zend"
class="mx.messaging.channels.AMFChannel">
<endpoint uri="http://localhost/ZendAmfTest-debug/amf.php"
class="flex.messaging.endpoints.AMFEndpoint"/>
</channel-definition>
</channels>
</services-config>

우선 default로 my-zend라는 채널을 잡았는데, my-zend는 endpoint uri가 ~~/amf.php입니다. 우리가 좀전에 작성했던 endpoint죠. 새로운 서비스가 추가되어 새로운 endpoint를 작성하게 될 때 endpoint파일을 amf1.php라고 했을 때 이곳에 추가해서 channel에 기입할 수도 있고, <mx:RemoteObject>에서 endpoint를 해당 uri로 바꿔주는 방법 2가지가 있습니다.

그럼 이제 Flex쪽으로 넘어가봅시다.
ZendAmfTest.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="vertical"
creationComplete="creationCompleteHandler()">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.rpc.events.ResultEvent;
import mx.rpc.events.FaultEvent;

private function creationCompleteHandler():void
{
roSosi.getData();
}

private function faultHandler(event:FaultEvent):void
{
Alert.show(event.message.toString());
}

private function resultGetDataHandler(event:ResultEvent):void
{
dgSosi.dataProvider = event.result as Array;
}
]]>
</mx:Script>

<mx:RemoteObject id="roSosi" fault="faultHandler(event)" destination="zend" source="SosiService">
<mx:method name="getData" result="resultGetDataHandler(event)" />
</mx:RemoteObject>

<mx:DataGrid id="dgSosi" width="100%" height="100%">
<mx:columns>
<mx:DataGridColumn headerText="아이디" dataField="idx"/>
<mx:DataGridColumn headerText="소녀시대이름" dataField="sosiname"/>
<mx:DataGridColumn headerText="신장" dataField="height" />
<mx:DataGridColumn headerText="혈액형" dataField="blood" />
</mx:columns>
</mx:DataGrid>

</mx:Application>

만약 다른 서비스를 추가하게 된다면, <mx:RemoteObject>에서 endpoint를 다른 url로 잡아주면 됩니다.
<mx:RemoteObject id="roAnother" fault="faultHandler(event)" 
destination="zend" source="AnothorService"
endpoint="http://localhost/ZendAmfTest-debug/another_amf.php">

아님 service-config.xml에서 channel을 다르게 해서 destination을 다르게 설정해도 되구요.
사용자 삽입 이미지

ps1. 다른 예제에서는 2개의 service를 이용한 예제가 없더라구요. 그래서 사실 저렇게 하는 게 맞는지 잘 모르겠습니다. 다른 방법이 있을 수도 있구요^^ 암튼, 제가 삽질한 바로는 서비스당 1개의 php파일을 만들어야 하더라구요.

ps2. PHP를 시작한지 얼마 안되었는데, DB연동 시 한글이 깨지더라구요. 인코딩을 my.ini과 php.ini에 utf-8로 맞췄는데, ???로 인식해서 나오는 경우가 있더라구요. php파일에서 db정보를 출력하니 이상하게 그냥 로컬에서 쳤을 때에는 utf-8로 나오는데, php파일이 출력한 db정보는 latin으로 나올 때가 있더라구요. 이 경우 my.ini파일에 이 부분을 추가해주면 됩니다.
[mysqld] 아래에
character-set-client-handshake = FALSE
client 인코딩으로 강제 셋팅하는거라고 하더라구요. 저는 처음에 ??? 뜨길래 이걸로 해결봤습니다-_-;
아 또 다른 방법으로 쿼리날리기 전에 set names 'utf8'이라고 먼저 날려줘도 됩니다.
mysql_query("SET NAMES 'utf8'");

ps3. 이런...생각해보니 client에서 VO를 안만들어줬군요-_-;

참고자료
http://corlan.org/2008/11/13/flex-and-php-remoting-with-zend-amf/

덧. 채널 못찾는 에러는 아래 주너니님의 댓글을 참조하세요~ 컴파일옵션을 추가해야합니다^^
주너니님 감사합니다 ^^
  1. 지돌스타

    매우 유용하군요. PHP에서도 AMFPHP는 AMF0만 지원했던걸로 알고 있는데 AMF3까지 지원한다고 하니... 매우 좋은걸요. 개인적으로 php로 할 프로젝트가 있었는데 적절한 시기에 소개해주셔서 참 감사합니다. 이걸 사용해야겠네요.

    • 머드초보

      앗 지돌스타님^^
      저도 php를 배운지 얼마 안되었는데, 데이터연동부분에 관한 자료를 찾다보니 Zend Amf가 있더라구요^^ 방문해주셔서 감사해요~^^

  2. 주너니

    안녕하세요. 좋은정보 감사합니다.
    내용중에 약간 잘못된게 있는것 같아서 저도 꽤 삽질했네요 ^^;;

    amf.php
    <?php
    require_once 'Zend/Amf/Server.php';
    require_once 'SosiService.php';

    $server = new Zend_Amf_Server();
    $server->setClass("SosiService";);
    $server->setClassMap("SosiVo", "SosiVo";);
    ?>
    마지막에 echo($server -> handle()); 가 빠진것 같네요.
    그리고 $mysql_query("SET NAMES 'utf8'";); -> mysql_query("SET NAMES 'utf8'";);
    이렇게 되야될거 같고요~

    마지막으로 channel 을 못찾는 에러가 나시는 분들은
    해당 프로젝트 Properties -> Flex Compiler -> Additional compiler arguments 에
    -services "D:\work\test\service-config.xml"
    식으로 service-config.xml 이 있는 절대경로값을 추가해주셔야 합니다.

    그럼 좋은정보 감사합니다. 수고하세요~

    • 머드초보

      헉 그렇네요 ㅠ
      저도 삽질하면서 글을 그냥 기록한거라 ㅠㅠ
      컴파일 옵션 추가도 제가 뺐군요 ㅠ
      감사합니다 ^^

  3. 햇무리

    좋은 글 정말 잘 봤습니다.
    AMFPHP가 느리다고 해서 망설이고 있었는데 좋은 게 있었네요.
    그런데 zendamf를 http://framework.zend.com/download/amf 에서 받아서 하니까 Minimal이고
    Zend폴더 밑에 Loader 폴더가 없어서 에러가 나더라구요.
    그래서 http://framework.zend.com/download/current/ 에서 Full로 받아서 해보니 되네요.
    물론 3월에 해보신거라 그때는 잘 되었을지도 모르겠네요.
    앞으로 해보시는 분들은 참고하세요.
    감사합니다.

    (그런데 한글깨지는거
    character-set-client-handshake = FALSE 로 하면 된다고 하셨는데 어떻게 하는지 잘 모르겠어요... ㅠㅠ
    mysql_query("SET NAMES 'utf8'";); 를 쓰는 것보다는 이게 더 좋을 것 같은데요.)

    • 머드초보

      아....그거 mysql옵션 수정하셔야합니다.
      mysql.ini파일인가-_- 설정파일이 있는데, 그걸 수정해서 mysql다시 리셋해주면 돼요 ^^
      방문해주셔서 감사해요~ ^^좋은 정보도 감사해요!

  4. 햇무리

    오... 잘 되네요... 감사합니다.
    그런데 또 안되는 것이 있네요... ㅠㅠ
    서비스 여러개 넣는거 해보는데 잘 안되요.
    위에 말씀하신 두가지를 다 해보고 있는데 워낙 zend에 대한 지식도 없고 하니 잘 안되네요.
    service-config.xml와 flex쪽에서 어떻게 바꾸면 될까요?
    -----
    몇시간 후...
    저도 삽질끝에 성공을 했어요... ^^
    이젠 저장하는 것을 해봐야 겠어요. 감사합니다.

    • 머드초보

      와 축하드립니다^^
      저도 이거 삽질했던 때가 생각나는군요.
      저도 조만간 이것을 쓰게 될 듯-_- 뭔가 개발해야하는데 서버가 php거든요^^

  5. 햇무리

    netbeans을 사용하신다고 했는데요.
    zend amf와 사용할때 php debug를 netbeans으로 어떻게 하나요?
    해보려고 하는데 잘 안되서요.
    php 코드쪽 문제 발생할 경우가 많은데 디버깅 없이는 코딩이 어려울 것 같아요.
    부탁드립니다. ^^

    • 머드초보

      디버깅을 하시려면 XDEBUG라는 디버거를 설치해야합니다.
      검색 하시면 셋팅하는 것이 다 나올꺼에요 ^^
      xdebug입니다!

  6. 햇무리

    감사합니다. xdebug라는 것이 있었네요.
    방금 php만 테스트 해봤는데 잘되네요.
    이젠 flex와도 되는지 봐야겠네요. ^^

    • 머드초보

      아네 이클립스에서도 php랑 다 할 수 있는데, ide가 전 따로 있는 게 더 편하더라구요. 그래서 서버는 넷빈즈, 클라이언트는 flex를 ^^
      그럼 둘다 디버깅을 편하게 할 수 있어요^^
      방문해주셔서 감사해요~

  7. 붉은고래

    좋은 정보 감사합니다..^^
    댓글 정보도 너무 유용하네요...
    오류가나서 이것저것 해보다가 댓글에서 해답들을 찾았네요..감사 감사 ^^

    • 머드초보

      아네 도움이 되셔서 다행이네요^^
      제가 몇개 좀 빠뜨린게 있었는데, 댓글에 누군가가 올려주셨어요 ㅠㅠ

  8. naiyumie

    따라해봤습니다. 감사합니다~~^^

  9. 행복한 아침

    환경 : window2003,php5.2,Mysql5.1,Flex builder 3

    위의 절차를 따라 실행을 하면 계속 이런 메시지가 떠는데
    제가 초보자라 무슨 뜻인지 잘 모르겠네요..
    정말 며칠동안 계속 이문제를 풀려고 했지만 도저히 무슨 영문인지 잘 모르겠습니다.
    왜 이러한 현상이 나는지 바쁘시겠지만 알려주시면 감사드립니다.

    (mx.messaging::ChannelSet)#6
    clientId = (null)
    connected = false
    defaultHeaders = (null)
    destination = "zend"
    id = "D0577C34-67E2-48B1-A580-CCFC96CE62A1"
    reconnectAttempts = 0
    reconnectInterval = 0
    requestTimeout = -1
    subtopic = ""
    connected = false
    connectTimeout = -1
    enableSmallMessages = true
    endpoint = "http://localhost:81/ZendAmfTest-debug/amf.php"
    failoverURIs = (Array)#11
    id = "my-zend"
    mpiEnabled = false
    netConnection = (flash.net::NetConnection)#12
    client = (mx.messaging.channels::AMFChannel)#4
    connected = false
    objectEncoding = 3
    proxyType = "none"
    uri = "http://localhost:81/ZendAmfTest-debug/amf.php"

    • 머드초보

      안녕하세요~
      이거 해본지 1년이 다되서....-_-
      죄....죄송합니다 ㅠㅠ
      잘 모르겠어요 ㅠㅠ

[로그인][오픈아이디란?]

submit