AMF набирает объекты из flex обратно в PHP - PullRequest
1 голос
/ 29 октября 2011

Вчера мне удалось отправить типизированные объекты из приложения PHP на гибкий интерфейс с помощью Zend_AMF согласно этому вопросу .

Проблема, с которой я сейчас сталкиваюсь, заключается в том, что я хотел бы отправить типизированный объект из flex в PHP и на стороне PHP, чтобы иметь возможность получать его как типизированный объект вместо stdClass.

Вот класс в flex:

package com.mysite
{
    [Bindable]
    [RemoteClass(alias="CTest")]
    public class CTest
    {

        public var stuff1:String;

        public var stuff2:String;

        public function CTest()
        {
        }
    }
}

И это соответствующий класс в PHP:

<?php
namespace modules\testing;

class CTest{

    var $_explicitType = 'CTest';

    var $stuff1;

    var $stuff2;
}

В flex я отправляю объект так:

var remoteObject:RemoteObject = new RemoteObject(); 
remoteObject.endpoint = "http://localhost/to/my/amf/endpoint"; 
remoteObject.showBusyCursor = true; 
remoteObject.source = 'testing'; 
var op:AbstractOperation = remoteObject.getOperation(null); 
op.addEventListener(ResultEvent.RESULT, result); 
op.send( new CTest()); 

На стороне PHP объект извлекается в переменную с именем $parameters. Затем я использую print_r для записи результата в файл:

$z = print_r($parameters, true);
$s = fopen('D:\test.txt', 'w+');
fwrite($s, $z);
fclose($s);

И, как видно, результат возвращается нетипизированным и является stdClass объектом:]

Array
(
    [0] => stdClass Object
        (
            [stuff1] => 
            [stuff2] => 
        )

)

После некоторого тестирования я удалил пространство имен из объекта PHP и переместил его в глобальное пространство имен. Это, похоже, решило проблему. Я попытался установить RemoteClass на \modules\testing\CTest, а также modules.testing.CTest. $_eplicitType затем было установлено на одно и то же значение для обоих тестов.

В результате, когда я использую modules.testing.CTest, это имя класса, которое видит Zend_AMF. Если я использую нотацию пространства имен, Zend_AMF видит modulestestingCTest, поскольку все слэши удаляются.

Но как мне заставить это работать с пространствами имен php?

1 Ответ

2 голосов
/ 29 октября 2011

Наконец-то решена проблема. Вот решение для тех, кто может столкнуться с той же проблемой в будущем.

Для вашего класса PHP:

<?php
namespace app\testing;
class CTest{

    var $_explicitType = 'app\testing\CTest';

    var $stuff1;

    var $stuff2;
}

Для вашего класса ActionScript:

package com.mysite
{
    [Bindable]
    [RemoteClass(alias="app\\\\testing\\\\CTest")]
    public class CTest
    {

        public var stuff1:String;

        public var stuff2:String;

        public function CTest()
        {
        }
    }
}

Я думаю, что проблема связана с сериализацией и десериализацией тела AMF. По сути, удаленный класс имеет 2 слэша, в результате чего получается: app\\testing\\CTest. Как только он десериализуется Zend_AMF, так как есть две косые черты, это означает, что обратные косые черты экранированы в это: app\testing\CTest. Это, конечно, догадка, но некоторые тесты с Чарльзом доказали, что это так.

Другим возможным решением является изменение Zend_Amf_Parse_TypeLoader.php. В строке 99 мы можем заменить:

 if(!$class) {
            $class = str_replace('.', '_', $className);
  }

с

if(!$class) {
     $class = str_replace('.', '\\', $className);
}

По сути, тогда мы можем просто использовать точечный синтаксис для отображений классов, который аккуратно будет размещен в ActionScript:

[RemoteClass(alias="app.testing.CTest")]

var $_explicitType = 'app.testing.CTest';

Очевидно, что это довольно приятное решение, но я предпочитаю не вносить изменения в код поставщика, поскольку библиотека Zend_AMF будет обновляться с более новыми версиями в будущем. На данный момент мое решение состоит в том, чтобы просто использовать 4 слеша.

...