昨天,根据这个问题,我成功地使用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
设置为modulestestingCTest
和modules.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个斜杠。