LogoLogo
  • Home
  • Projects
  • About
  • Contact

Save/Retrieve ByteArrays to/from Database via AMFPHP

Devon O. · May 07, 2009 · Actionscript, Life · 10 comments
3

Probably old hat to many folks, but I had to do a bit of googling yesterday to figure this one out and thought I’d write it down lest I forget it all again.

The first gotcha to watch out for (the one that got me, anyway), is making sure that AMFPHP is encoding in AMF3. This can be set in the constructor of the AMFPHP class.

Your AMFPHP class may look like this, for instance:

PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<?php
class ByteSaver {
 
    function ByteSaver() {
        $GLOBALS['amfphp']['encoding'] = 'amf3';
        mysql_pconnect("SERVER", "NAME", "PASS");
        mysql_select_db("DB");
    }
 
    /**
     * Grabs byte array from database table named 'bytearray' and sends it back to Flash
     * @returns ByteArray
     */
    
    function getData() {
        $result = mysql_query("SELECT * FROM bytearray LIMIT 1");
        $row = mysql_fetch_assoc( $result );
        return new ByteArray($row['byte_array']);
    }
    
    /**
     * Saves ByteArray from Flash to database table 'bytearray' (in this case the 'byte_array' field is a longblob).
     * @returns ArrayCollection of all images
     */
    
    function setData($ba) {
        $result = mysql_query("INSERT INTO bytearray (byte_array) VALUES ('$ba->data')");
        return $result;
    }
    
}
?>

The actionscript is pretty standard AMFPHP/actionscript stuff. The question is: why would you need this? Well, say you have a very complex bit of data containing an indeterminate number of objects in multi dimensional array(s) and you want to save all this as a single object in a single database field. You could manually serialize the mess and write it as one long string – or you could simply write the object to a ByteArray and save it in a ‘blob’ in your database.

Here’s a quick example:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
package {
 
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.net.NetConnection;
    import flash.net.Responder;
    import flash.utils.ByteArray;
    
    /**
     * send then receive bytearray from database example
     * @author Devon O. Wolfgang
     */
    public class Example extends Sprite {
        
        private var resp1:Responder;
        private var resp2:Responder;
        private var nc:NetConnection;
        
        public function Main():void {
            if (stage) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);
        }
        
        private function init(e:Event = null):void {
            removeEventListener(Event.ADDED_TO_STAGE, init);
            // entry point
            
            var author1:Object = {    
                                    firstname : "James",
                                    surname : "Ballard"
            }
            
            var author2:Object = {
                                    firstname : "Hunter",
                                    surname : "Thompson"
            }
            
            var author3:Object = {    
                                    firstname : "Chuck",
                                    surname : "Palahniuk"
            }
            
            var author4:Object = {
                                    firstname : "William",
                                    surname : "Gibson"
            }
            
            var living:Array = [author3, author4];
            var dead:Array = [author1, author2];
            
            var allAuthors:Array = [living, dead];
            
            var ba:ByteArray = new ByteArray();
            ba.writeObject(allAuthors);
            ba.position = 0;
            
            resp1 = new Responder(onGoodSave, onBadReturn);
            resp2 = new Responder(onGoodReturn, onBadReturn);
            nc = new NetConnection();
            nc.connect("http://localhost/amfphp/gateway.php");
            
            // send bytearray to database
            nc.call("ByteSaver.setData", resp1, ba)
        }
        
        // once bytearray has been sent to server
        private function onSave(o:Object):void {
            // if bytearray was inserted into database
            if (String(o) == "true") {
                nc.call("ByteSaver.getData", resp2);
            } else {
                trace ("data not added to database for whatever reason");
            }
        }
        
        // when you retrieve bytearray from server
        private function onGoodReturn(o:Object):void {
            var ba:ByteArray = o as ByteArray;
            ba.position = 0;
            trace (ba.readObject()[0][1].surname); // Gibson
        }
        
        // bad amfphp call
        private function onBadReturn(o:Object):void {
            for (var prop:String in o) trace (prop, o[prop]);
        }
    }
}

Hope that might help someone out. My future self if no one else.


In other news, just saw that my Site GatherAIR thingamabob has now been listed over on Refreshing Apps. Very cool stuff! And thanks to whoever submitted it.

  Facebook   Pinterest   Twitter   Google+
  • MOTION – FLUID – SOUND
    October 22, 2010 · 1 comments
    2186
    7
    Read more
  • Learning AGAL with AGALMacroAssembler and OpenGL Examples
    June 03, 2012 · 16 comments
    7007
    8
    Read more
  • Game Development Tips from the Trenches of PopCap
    August 01, 2011 · 5 comments
    3718
    5
    Read more
10 Comments:
  1. No I found it useful. I have a large project that has been doing this process and also went through the googling phase. I can tell you that this article is one of those that really needs to be indexed on google.

    Danny Miller · May 07, 2009
  2. This is brilliant – thank you. It’s very good of you to share this and I owe you a beer!!!

    When you bring in the bytearray object from the server though, i think you can just cast it to bytearray in flash straight away. So towards the end of the as script it ends up something like this:

    private function onGoodReturn(o:ByteArray):void { …

    No need to cast thereafter. Very picky but emphasises the power and ease of access with amfphp.

    sean · May 29, 2009
  3. Very good tip, Sean. Didn’t think to skip that one extra step of casting the return. Very cool!

    Devon O. · May 29, 2009
  4. whats the field type for “byte_array”? Is the example done in flex?

    Thx for the post, very interesting.

    Dannn · September 22, 2009
  5. When i pull the byte array in from the database and assign it to a byte array var i get the following:

    cannot convert Object@1ecd80d9 to flash.utils.ByteArray.

    In my amfphp browser the object looks like this:

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

    does this look right compared to what you get? Also, have u been going to flash on the beach? if so, i may c u there tomorrow :o

    Dannn · September 22, 2009
  6. Strange that the browser shows it as a ByteArray, but you can’t type it as one. Been so long since I’ve touched this, I forgot about it (needed it for work the day I blogged this and haven’t touched it since).

    I have been at FOTB. Gonna be at the party at Oceania tonight. I’m the Flash Cowboy.. :)

    Devon O. · September 22, 2009
  7. I was getting the dreaded NetConnection.call.badversion occasionally when adding a specific string to my multidimensional array. Specifically, “Lucky Number Slevin” just as a test. It was driving me crazy because it would work all the other times. I finally figured out that I needed to escape the bytearray with mysql_escape_string(). So hopefully this will help others out with intermittent badversion errors.

    Sundev · May 30, 2010
  8. I meant mysql_real_escape_string of course.

    Sundev · May 31, 2010

Leave a Comment! Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Devon O. Wolfgang

AIR | Unity3D | AR/VR

Unity Certified Developer

Technical Reviewer of “The Essential Guide to Flash CS4 AIR Development” and “Starling Game Development Essentials”

Reviewer of “The Starling Handbook”

Unity Engineer at Touch Press.

Categories
  • Actionscript (95)
  • AIR (16)
  • Flash (99)
  • Games (7)
  • Liberty (13)
  • Life (53)
  • Shaders (20)
  • Unity3D (21)
Recent Comments
  • MainDepth on Unity Ripple or Shock Wave Effect
  • Devon O. on Unity Ripple or Shock Wave Effect
  • Feral_Pug on Unity Ripple or Shock Wave Effect
  • bavvireal on Unity3D Endless Runner Part I – Curved Worlds
  • Danielius Vargonas on Custom Post Processing with the LWRP
Archives
  • December 2020 (1)
  • December 2019 (1)
  • September 2019 (1)
  • February 2019 (2)
  • December 2018 (1)
  • July 2018 (1)
  • June 2018 (1)
  • May 2018 (2)
  • January 2018 (1)
  • December 2017 (2)
  • October 2017 (1)
  • September 2017 (2)
  • January 2017 (1)
  • July 2016 (1)
  • December 2015 (2)
  • March 2015 (1)
  • September 2014 (1)
  • January 2014 (1)
  • August 2013 (1)
  • July 2013 (1)
  • May 2013 (1)
  • March 2013 (2)
  • December 2012 (1)
  • November 2012 (1)
  • September 2012 (3)
  • June 2012 (2)
  • May 2012 (1)
  • April 2012 (1)
  • December 2011 (2)
  • October 2011 (3)
  • September 2011 (1)
  • August 2011 (1)
  • July 2011 (1)
  • May 2011 (2)
  • April 2011 (2)
  • March 2011 (1)
  • February 2011 (1)
  • January 2011 (2)
  • December 2010 (3)
  • October 2010 (5)
  • September 2010 (1)
  • July 2010 (2)
  • May 2010 (5)
  • April 2010 (2)
  • March 2010 (7)
  • February 2010 (5)
  • January 2010 (5)
  • December 2009 (3)
  • November 2009 (1)
  • October 2009 (5)
  • September 2009 (5)
  • August 2009 (1)
  • July 2009 (1)
  • June 2009 (2)
  • May 2009 (6)
  • April 2009 (4)
  • March 2009 (2)
  • February 2009 (4)
  • January 2009 (1)
  • December 2008 (5)
  • November 2008 (2)
  • September 2008 (1)
  • August 2008 (6)
  • July 2008 (6)
  • June 2008 (9)
  • May 2008 (4)
  • April 2008 (3)
  • March 2008 (4)
  • February 2008 (9)
  • January 2008 (7)
  • December 2007 (6)
Copyright © 2021 Devon O. Wolfgang