AMFPHP:在没有网关的情况下通过HTTP序列化Flash对象

时间:2010-01-17 15:12:26

标签: php flash amf amfphp zend-amf

Flash + AMFPHP是一个很好的组合。但是有些情况下,由于各种原因,使用NetConnection的Flash Remoting不是正确的工具。 Rob不久前发了一篇很棒的帖子:http://www.roboncode.com/articles/144

他还有一个很好的例子,说明如何将AMF传递给http请求,而不使用POST和AMF请求包来调用NetConnection使用Zend_AMF发送的函数。

// Include the Zend Loader
include_once 'Zend/Loader.php';
// Tell the Zend Loader to autoload any classes we need
// from the Zend Framework AMF package
Zend_Loader::registerAutoload();

// Create a simple data structure
$data = array('message' => 'Hello, world!');
// Create an instance of an AMF Output Stream
$out = new Zend_Amf_Parse_OutputStream();
// We will serialize our content into AMF3 for this example
// You could alternatively serialize it as AMF0 for legacy
// Flash applications.
$s = new Zend_Amf_Parse_Amf3_Serializer($out);
$s->writeObject($data);

// Return the content (we have found the newline is needed
// in order to process the data correctly on the client side)
echo "\n" . $out->getStream();

我真的很喜欢这种方法,并且非常习惯用AMFPHP复制它。为什么选择AMFPHP? “最新”版本使用amf-ext(一种C PHP扩展)来序列化和反序列化数据。它比ZendAMF仍在使用的php方式快得多。

当然我已经玩过AMFPHP并尝试构建必要的对象并使用Serializer类。我甚至得到了一个有效的AMF字符串,但实际数据总是被一个'方法包'包裹起来,它告诉接收者这是'Service.method'调用的答案。

那么有没有一种方法可以在AMFPHP中直接序列化Flash对象,而无需网关和方法包装器?

感谢。

2 个答案:

答案 0 :(得分:4)

好的,它现在可以运行了。

它比Zend_AMF解决方案稍微复杂一点,但速度要快得多。这是我的代码:

$data = array('message' => 'Hello, world!');

// Create the gateway and configure it
$amf = new Gateway();
Amf_Server::$encoding = 'amf3';
Amf_Server::$disableDebug = true;

// Construct a body
$body = new MessageBody("...", "/1", array());
$body->setResults($data);
$body->responseURI = $body->responseIndex . "...";

// Create the object and add the body
$out = new AMFObject();
$out->addBody($body);

// Get a serializer and use it
$serializer = new AMFSimpleSerializer();
$result = $serializer->serialize($out);

如您所见,我建立了一个新类AMFSimpleSerializer

class AMFSimpleSerializer extends AMFSerializer
{
    function serialize(&$amfout)
    {
        $encodeCallback = array(&$this,"encodeCallback");

        $body = &$amfout->getBodyAt(0);

        $this->outBuffer = "";
        $this->outBuffer .= amf_encode($body->getResults(), $this->encodeFlags, $encodeCallback);
        $this->outBuffer = substr($this->outBuffer, 1);

        return $this->outBuffer;
    }
}

此类仅在安装amfext时有效,但可以轻松修改为使用php enocding进程。我没有实现它,因为我是在AMFPHP的大量修改版本上构建的。

我希望我用真正的AMFPHP对应代码替换我代码中的所有类。我将在明天尝试测试,并在必要时更新此答案。

在我完成之后,我意识到现在几乎没有任何来自AMFPHP的东西实际上留在了课堂上,它只是调用amf_encode并删除第一个字节,以便客户端能够理解他得到的东西。

简单,快捷。

答案 1 :(得分:1)

这是一个不需要amfext的简化版本:

require_once( 'amfphp/core/amf/app/Gateway.php');
require_once( AMFPHP_BASE . 'amf/io/AMFSerializer.php');

$data = array('message' => 'Hello, world!')

$serializer = new AMFSerializer();
$serializer->writeAmf3Data( $data );

print $serializer->outBuffer;

不需要新行和子字符串。 AMFPHP 1.9,Flex 3.4。