Who will save me? Error reading ByteArray from amfphp in Flash

  1. Sending a ByteArray from AMFPHP to Flash fails / AMF can’t send a ByteArray to AS3 / ByteArray can’t be remoted to Flash
  2. TypeError: Error #1034: Type Coercion failed: cannot convert Object@******* to flash.utils.ByteArray. / TypeError: Error #1034: 强制转换类型失败:无法将 Object@*******转换为 flash.utils.ByteArray
  3. It happens with AS3 Flash remoting, not with Flex remoting.

Problem description:

I keep files on the server and want to return them as a ByteArray through amfphp. Something like this:
PHP part AS part package { import flash.net.NetConnection; import flash.display.Sprite; import flash.utils.ByteArray; import flash.net.ObjectEncoding; import flash.events.*; import flash.net.Responder; public class Test extends Sprite{ private var __netConn:NetConnection = new NetConnection(); private var __gateWay:String; public function Test():void { var gw:String=”http://Universe.mousebomb/amf/gateway.php";//修改地址测试 __netConn.objectEncoding=ObjectEncoding.AMF3; __netConn.connect(gw); __netConn.call(“mousebomb.Test.a”, new Responder(onCallResult,onCallFault)); } private function onCallResult(re:ByteArray):void { trace(re);//输出: TypeError: Error #1034: 强制转换类型失败:无法将 Object@3046179 转换为 flash.utils.ByteArray。 } private function onCallFault(re:Object):void { for (var i in re) { trace(i+”=>”+re[i]); } } } } The result returned by AMF shows up in the AMFPHP browser as type ByteArray:

(flash.utils::ByteArray)#0 bytesAvailable = 124118 endian = “bigEndian” length = 124118 objectEncoding = 3 position = 0

But in the Flash I’m testing with it outputs:

TypeError: Error #1034: 强制转换类型失败:无法将 Object@3046179 转换为 flash.utils.ByteArray。

So where’s the problem?

Solutions:

Solution 1:

PHP code: //… $contents = base64_encode(file_get_contents(“$文件路径”)); return $contents; AS code: protected function onCallResult(re:String):void { var fileBytes:ByteArray = Base64.decodeToByteArray(re); //fileBytes已获得. 可以有很多用途,比如,用Loader载入一幅图片… //… } This approach returns the file as a base64 string and decodes it back into a ByteArray in Flash. To pull this off you need the class provided by import [http://dynamicflash.com/goodies/base64/(http://dynamicflash.com/goodies/base64/)
If you can’t be bothered to go there, you can download it here.

Solution 2:

This is the real key, actually. You can’t just assume that setting NetConnection.objectEncoding = ObjectEncoding.AMF3 on the Flash side is enough — what matters more is setting AMFPHP itself to AMF3 encoding. Add $GLOBALS[‘amfphp’][‘encoding’] = ‘amf3’; to the PHP code AS code, for example you can write it like this protected function onCallResult(re:ByteArray):void { //….直接用re喽 } And the problem solves itself… Writing this down, even though it really shouldn’t have been a problem in the first place… I hope this article is useful to you, so that if you run into the same situation you don’t have to take as many detours as I did. This problem had been bugging me since last night. After more than 20 hours of fighting, the search-and-rescue operation finally made progress, and I ended up with two solutions. Even though I got the effect I needed, I’m still puzzled: it seems this problem only exists in Flash, Flex is fine with it. Someone says the same. A lament: there’s way too little technical writing in Chinese, so searches keep coming up empty. I had really bad luck this time — I almost couldn’t find it even in English… Thanks to AuZn, 杜增强, Y-boy, Lonely Volcano for the leads…

References:
http://forum.sephiroth.it/showthread.php?t=10194 A guy on this forum asks “Blob field not casted to ByteArray upon sending to AS3
http://www.astorm.ch/blog/index.php?post/2008/04/01/Remoting-et-ByteArray-avec-Flash-et-AS3 Remoting et ByteArray avec Flash et AS3