Subarrays disappearing in Amfphp, Actionscript 3 data integration

73 Views Asked by At

I recently upgraded to php 5.6 and amfphp 2.2.2 and I'm trying to modify the way the data is handled in an Actionscipt 3 animation that I wrote several years ago (I haven't worked with AS3 for a long time so that may well be part of the problem here).

The amfphp site (Silex Labs) says to simply use PDO for your data and AS3 and amfphp will handle it properly, but that's not working.

The AS3 "Responder" class handles the incoming data from amfphp and it no longer uses "responds.serverInfo.initialData". So AS3 can no longer process the data the way it did with amfphp 1.9.

So I wrote a script to parse the data. I apparently don't understand the structure of the data object that amfphp provides to the AS3, but I was able to extract the data from the object and store in an array.

I can trace the data in the triple loop in the AS3 script, but outside of the loop the subarrays are undefined.

I must be doing something wrong in the AS3. Can anyone see what it is?

The php:

<?php
function getConnection() {
    return new PDO('mysql:host=localhost;dbname=db-name', 'root', '',
    array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));
}

function getData() {
    $pdo = getConnection();
    $tsql = "SELECT col0, col1, col2, col3, col4, col5, col6, col7 
           FROM somedata ORDER BY index_num ASC"; 

    $stmt = $pdo->prepare($tsql);
    $stmt->execute();
    $results = $stmt->fetchAll(PDO::FETCH_ASSOC);
    return $results;
}

?>

The AS3:

        public class GetSomeData extends Sprite {
    private var gw:NetConnection = new NetConnection();
    private var getRes:Responder = new Responder(onResult, onFault);
    private var someData:Array = new Array();
    private var colList:Array = new Array();

    public function GetSomeData() {}

    public function refreshSomeData():void {
        gw.connect("http://localhost/Amfphp/");         
        gw.call("GetSomeData.getData", getRes);
    }


    private function onResult(responds:Object):void {
        /****** THIS IS OUTDATED AS OF amfphp 2.x *******/
        //responds is an arrayCollection which includes .serverInfo.initialData
        //someData = responds.serverInfo.initialData;

        //this is because amfphp returns the columns in the SELECT statement out of order
        colList = ["col0", "col1", "col2", "col3", "col4", "col5", "col6", "col7"];

        for (var j:uint=0; j < colList.length; j++) {
            for (var k:uint=0; k < responds.length; k++) {
                    for(var x in responds[k]){//put columns in correct order
                        if (x.toString() == colList[j]){
                            someData[k] = new Array();
                            someData[k][j] = responds[k][x];
                            //this trace reports all of the data correctly
                            trace(someData[k][j].length);//
                        }
                    }
           }
        }

        trace(someData.length);//49
        trace(someData[0].length);//8
        trace(someData[0][0].length);//undefined

    }
}
1

There are 1 best solutions below

0
lastNerve On

I was able to get all of my AS3 animations working and I want to share what I found out about using PHP 5.6.2 with Amfphp 2.2.2 and AS3. I think my AS3 code looks overdone but after struggling with for 3 days it was the best I could come up with, and it works.

My main aim was to get the structure of the data arrays back to the state that they were when I was using php 5.2, amfphp 1.9 and mysql_query().

Amfphp calls the getData() function in GetSomeData.php, which obviously uses its SELECT statement. But Amfphp returns the data to Actionscript in a disordered state rather than in the order specified in the SELECT statement. This disorderd state is not with the column names in alphabetical order nor is it ordered by smallest field size first. It appears to be random.

However, Amfphp does return the column names SELECTed in getColumns()in SELECT order. So I used the results of getColumns() (in Actionscript) to put the getData() results in the order I needed them to be.

Here's the php that's working now (yes I know there is no error checking, that will have to come later):

<?php
    class GetSomeData{
        public static function getConnection() {
            return new PDO('mysql:host=localhost;dbname=exampleDB', 'root', ''
        }

        function getColumns() {
            $pdo = getConnection();
            $sql = "SELECT COLUMN_NAME 
                    FROM INFORMATION_SCHEMA.COLUMNS 
                    WHERE TABLE_SCHEMA='exampleDB' 
                    AND TABLE_NAME='sometable'"; 

            $stmt = $pdo->prepare($sql);
            $stmt->execute();
            $results = $stmt->fetchAll(PDO::FETCH_ASSOC);
            return $results;
        }

        function getData() {
            $pdo = getConnection();
            $tsql = "SELECT col1, col2, col3, col4, col5, col6, col7
                     FROM sometable"; 
            $stmt = $pdo->prepare($tsql);
            $stmt->execute();
            $results = $stmt->fetchAll(PDO::FETCH_ASSOC);
            return $results;
        }
    }
?>

If you remove "class GetSomeData" and "public static" from this script and use print_r($results) in getColumns() and run it from a web page you'll see the columns in SELECT order: Array ( [0] => Array ( [col1] => 1.01 [col2] => 1.23 [col3] => 2.23 [col4] => 1.31 [col5] => 2.44 [col6] => 1.33 [col7] => 1.76))

And here's the AS3:

package { 
    import flash.display.Sprite; 
    import flash.events.*; 
    import flash.net.*;

    public class GetStrokeData extends Sprite {
        private var gw:NetConnection = new NetConnection();
        private var getRes:Responder = new Responder(onResult, onFault);

        private var someStrings:Array = new Array();
        private var someData:Array = new Array();
        private var colNames:Array = new Array();
        private var arraysLoaded:Boolean = false;

        public function GetSomeData() {}

        public function refreshData():void {
            if(colNames[0] == undefined){
                gw.connect("/Amfphp/");         
                gw.call("GetSomeData.getColumns", getRes);
            } else {
                gw.connect("/Amfphp/");         
                gw.call("GetSomeData.getData", getRes);
            }
        }

        public function loadArrays():void {
            for(var i:uint = 0; i < someData.length; i++){
                someStrings[i] = new Array();

                //in some cases I had to use .toString().split(",") to get my data
                //into the same state that it was in when I was using 
                //mysql_query with amfphp 1.9
                someStrings[i][0] = someData[i][0].toString().split(",");
                someStrings[i][1] = someData[i][1].toString().split(",");
                someStrings[i][2] = someData[i][2].toString().split(",");
                someStrings[i][3] = someData[i][3].toString().split(",");
                someStrings[i][4] = someData[i][4].toString().split(",");
                someStrings[i][5] = someData[i][5].toString().split(",");
                someStrings[i][6] = someData[i][6].toString().split(",");
                someStrings[i][7] = someData[i][7].toString().split(",");

                if(i == someData.length - 1){
                    arraysLoaded = true;
                }
            }
        }

        private function onResult(responds:Object):void {
            //load column names from php getColumns()
            if(colNames[0] == undefined){
                var i:uint=0;
                for (var j:uint=0; j < responds.length; j++) {
                    for(var y in responds[j]){
                        colNames[i++] = responds[j][y];
                    }
                    if(j == responds.length - 1){
                        refreshData();
                    }
                }
            } else {
                //load someData with arrays
                for (var k:uint=0; k < responds.length; k++) {
                    someData[k] = new Array(); 
                }

                //load data from php getData() and
                //turn amfphp disordered associative array into ordered 
                //indexed array
               for (var m:uint=0; m < responds.length; m++) {
                    for (var n:uint=0; n < colNames.length; n++) {
                        for(var x in responds[m]){

                            //ensure that column name in responds is next in colNames
                            if (x.toString() == colNames[n]){
                                someData[m][n] = new Array(responds[m][x]);
                            }
                        }

                    }

                    if(m == responds.length - 1){
                        loadArrays();
                    }
                }
            }
        }

    }
}