从flex到PHP的AMF类型对象



昨天,根据这个问题,我成功地使用Zend_AMF从PHP应用程序发送类型化对象到flex前端。

我现在面临的问题是,我想从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 modulestesting;
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设置为modulestestingCTestmodules.testing.CTest。然后在两个测试中将$_eplicitType设置为相同的值。

结果是,当我使用modules.testing.CTest时,这是Zend_AMF看到的类名。如果我使用名称空间表示法,Zend_AMF会看到modulestestingCTest,因为所有斜杠都被去掉了。

但是我怎么能得到这个工作与php名称空间?

终于解决了问题。以下是为将来可能遇到同样问题的人提供的解决方案。

对于你的PHP类:

<?php
namespace apptesting;
class CTest{
    var $_explicitType = 'apptestingCTest';
    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体的序列化和反序列化。实际上,远程类is有两个斜杠转义,结果是:app\testing\CTest。一旦它被Zend_AMF反序列化,因为有两个斜杠,这意味着反斜杠被转义为:apptestingCTest。当然,这只是一种直觉,但是对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个斜杠。

最新更新