AMF类型的对象从flex回到PHP

时间:2011-10-29 03:12:22

标签: flex object types amfphp zend-amf

昨天,我成功地使用Zend_AMF将类型化的对象从PHP应用程序发送到flex前端question

我现在面临的问题是我想将一个类型化的对象从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 个答案:

答案 0 :(得分:2)

终于解决了这个问题。对于那些可能在将来遇到同一问题的人来说,这是一个解决方案。

对于您的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反序列化,由于有2个斜杠,这意味着反斜杠转义为:app\testing\CTest。这当然是一种预感,但是对Charles的一些测试证明了这种情况。

另一种可能的解决方案是修改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个斜杠。