سؤال

Yesterday, I succeeded in sending typed objects from a PHP application to a flex front-end using Zend_AMF as per this question.

The problem I am facing now is that I would like to send a typed object from flex to PHP and on the PHP side, be able to recieve it as a typed object instead of stdClass.

Here is the class in flex:

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

        public var stuff1:String;

        public var stuff2:String;

        public function CTest()
        {
        }
    }
}

And this is the corresponding class in PHP:

<?php
namespace modules\testing;

class CTest{

    var $_explicitType = 'CTest';

    var $stuff1;

    var $stuff2;
}

In flex, I am sending the object like so:

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()); 

On the PHP side, the object is retrieved into a variable called $parameters. I then use print_r on it to write the result to a file:

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

And as can be seen, the result comes back untyped and is a stdClass object:]

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

)

After some testing, I removed the namespace from the PHP object and moved it into the global namespace. This seems to have resolved the issue. I have tried setting RemoteClass to \modules\testing\CTest and also modules.testing.CTest. $_eplicitType was then set to the same value for both tests.

The result is that when I use modules.testing.CTest, this is the classname that Zend_AMF sees. If I use namespace notation, Zend_AMF sees modulestestingCTest, as all the slashes get stripped out.

But how can I get this working with php namespaces?

هل كانت مفيدة؟

المحلول

Finally resolved the issue. Here is the solution for those who might come across the same issue in the future.

For your PHP class:

<?php
namespace app\testing;
class CTest{

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

    var $stuff1;

    var $stuff2;
}

For your actionscript class:

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

        public var stuff1:String;

        public var stuff2:String;

        public function CTest()
        {
        }
    }
}

I think the problem is due to the serialization and deserialization of the AMF body. Effectively, the remote class is has 2 slashes escaped, resulting in this: app\\testing\\CTest. Once it is deserialzed by Zend_AMF, since there are 2 slashes, it means that the backslashes are escaped into this: app\testing\CTest. This is just a hunch of course, but some testing with Charles proved that this is the case.

Another possible solution is to modify Zend_Amf_Parse_TypeLoader.php. On line 99, we could replace:

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

with

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

Effectively, we can then just use dot syntax for the class mappings, which actionscript will place nicely with:

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

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

Obviously this will is a pretty nice solution, but I prefer not to modify with vendor code, as the Zend_AMF library will be updated with newer versions in the future. For now, my solution is to just use 4 slashes.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top