AMFPHP: Сериализация Flash-объектов по HTTP без шлюза - PullRequest
2 голосов
/ 17 января 2010

Flash + AMFPHP - отличная комбинация. Но бывают случаи, когда Flash Remoting с NetConnection не подходит по разным причинам. У Роба был отличный пост на эту тему: 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, для сериализации и десериализации данных. Это намного быстрее, чем php, используемый ZendAMF.

Конечно, я уже играл с AMFPHP и пытался построить необходимые объекты и использовать класс Serializer. Я даже получил действительную строку AMF, но реальные данные всегда были заключены в «пакет методов», который сообщал получателю, что это ответ на вызов «Service.method».

Так есть ли способ сериализации Flash-объектов напрямую, без шлюза и метода-оболочки, в AMFPHP?

Спасибо.

Ответы [ 2 ]

4 голосов
/ 19 января 2010

Хорошо, теперь все заработало.

Это немного сложнее, чем решение 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 голос
/ 13 августа 2011

Это упрощенная версия, не нуждающаяся в 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.

...