What is Good Practice When Getting MySQL Data Using Amfphp As Strongly Typed Objects for Flex -
i in stages of setting out architecture new project. info driven flex ui, sit down within web page, calling amfphp service mysql info populate elements within flex ui.
so many examples of how approach out of date or poorly written looking not understand flow of info set in place clear, robust practice. please review approach , allow me know if sense better.
say want display list of 'subjects', let's follow process have far.
amfphp service
having structured , populated mysql database, named 'atlasdata', have developed initial amfphp service which, using amfphp office service browser, appears returning array of typed 'vosubject' objects. on development mac (mamp installed) within 'amfphp/services/vo folder have next 'vosubject.php' file:
<?php /** * created intellij idea. * user: chris * date: 04/10/2014 * time: 18:31 */ class vosubject { /* * * class models 1 row of mysql table. has 1 field * each row of table , special field. * field $_explicittype, , value qualified * actionscript value object intend utilize in flex application model data. * if don‚t configure field correctly, in flex app * not typed actionscript class, dynamic object. * */ public $subjectid; public $subjectname; // explicit actionscript class var $_explicittype = "vosubject"; }
my amfphp service looks (note have removed of methods brevity):
<?php require_once ('vo/vosubject.php'); include ('dbaccess.php'); class atlasservice { // simple function can used test service. public function helloworld() { homecoming "hello world"; } public function getallsubjects() { // connect database using php info objects (pdo). seek { /* * dbaccess class singleton class. * create instance of class access it's methods. */ $db = dbaccess::getinstance(); // create php info object. $pdo = $db->getpdo(); } grab (pdoexception $e) { print "connection error!: " . $e->getmessage() . "<br/>"; die(); } // retrieve rows atlasdata database 'subjects' table. seek { $tsql = 'select s.`subjectid`, s.`subjectname` subjects s'; $stmt = $pdo->prepare($tsql); $stmt->execute(); // fetch of info , place in variable '$results'. $results = $stmt->fetchall(pdo::fetch_class, 'vosubject'); } grab (pdoexception $e) { print "error when fetching data: " . $e->getmessage() . "<br/>"; die(); } // close database connection. $stmt = null; $pdo = null; // homecoming array. homecoming $results; } }
using amfphp office - service browser phone call 'getallsubjects' function next returned:
it appear using code
$results = $stmt->fetchall(pdo::fetch_class, 'vosubject')
has set $results array of vosubject objects.
flex application
so want flex application phone call amfphp service function 'getallsubjects.
i advocate of view model presenter when developing flex projects know escalate in complexity. in project's infancy have created following:
views - subjectbar_view (mxml file) presenters - subjectbar_presenter (actionscript class) model - model (actionscript class)
my subjectbar_view displays list of subjects:
<s:list id="subjectlist" dataprovider="{presenter.subjects}"> <s:layout> <s:horizontallayout/> </s:layout> <s:itemrenderer> <fx:component> <s:itemrenderer> <s:hgroup paddingleft="2"> <s:label text="{data.subjectname}" width="125"/> </s:hgroup> </s:itemrenderer> </fx:component> </s:itemrenderer> </s:list>
my subjectbar_presenter provides info source list bind , property set calling method in model:
package presenters { import flash.events.event; import models.model; import mx.collections.arraycollection; import mx.events.flexevent; import vo.vosubject; [bindable] public class subjectbar_presenter { private var _model:model = model.getinstance(); private var _subjects:arraycollection; public function subjects():arraycollection { homecoming _subjects; } public function set subjects(value:arraycollection):void { _subjects = value; } // constructor. public function subjectbar_presenter() { // add together eventlistener hear property changes in model. _model.addeventlistener("subjectschanged", onsubjectschanged); } private function onsubjectschanged(event:event):void { // update property. this.subjects = _model.subjects; } public function oncreationcomplete(event:flexevent):void { // subjects mysql database. _model.getallsubjects(); } } }
my model connects server , calls amfphp service function 'getallsubjects':
package models { import flash.events.event; import flash.events.eventdispatcher; import flash.net.netconnection; import flash.net.responder; import mx.collections.arraycollection; // custom events. [event(name="subjectschanged", type="flash.events.event")] public class model extends eventdispatcher { // event names. public static const subjects_changed:string = "subjectschanged"; private static var _model:model; private var _subjects:arraycollection; private var _netconnectionobject:netconnection; private var _responder:responder = new responder(handleallsubjects, null); public function subjects():arraycollection { homecoming _subjects; } public function set subjects(value:arraycollection):void { _subjects = value; // dispatch event allow detail view update. dispatchevent(new event(subjects_changed)); } public function netconnectionobject():netconnection { homecoming _netconnectionobject; } public function set netconnectionobject(value:netconnection):void { _netconnectionobject = value; } // constructor. public function model(pvt:privateclass) { // phone call 'init' function carry out preparatory work. this.init(); } // singleton creator. public static function getinstance():model { if (model._model == null) { model._model = new model(new privateclass()); //trace("singleton instantiated"); } else { //trace("sorry--already have singleton instantiated") } homecoming model._model; } private function init():void { // phone call preparatory functions here. this.createnetconnection(); } private function createnetconnection():void { netconnectionobject = new netconnection(); //netconnection.connect( [server name] / [project folder] /amfphp); netconnectionobject.connect("http://localhost/amfphp-2.2.1/amfphp/index.php"); } private function handleallsubjects(result:object):void{ // trace(result.tostring()); // php method returns array not arraycollection. this.subjects = new arraycollection(result array); } public function getallsubjects():void { // phone call atlasservice. //netconnection.call([service name]/[function name]", [responder], [parameters]); netconnectionobject.call("atlasservice/getallsubjects", new responder(handleallsubjects, null)); } } } class privateclass { public function privateclass() { //trace("private class up"); } }
in flex project 'src' folder have created 'vo' folder , created next 'vosubject' class define subject value object:
package vo { // actionscript value object class. // must match php value object class defined within amfphp/services/vo folder. [remoteclass(alias="vosubject")] [bindable] public class vosubject { public var subjectid:int; public var subjectname:string; // constructor. public function vosubject() { } } }
it utilize of vosubject class on flex side unsure of. line [remoteclass(alias="vosubject")] pointing php class in amfphp/services/vo folder? if relative to. should read [remoteclass(alias="vo/vosubject")] because vosubject.php class within folder named 'vo' within services folder?
if debug application list displayed , populated subjectnames. great. appear subjects info source arraycollection of objects containing subjectid , subjectname not arraycollection of vosubject objects.
can please explain how ensure 'subjects' info source in 'subjectbar_presenter' class arraycollection of typed vosubject objects. additionally if sense improve approach willing learn.
thank getting end! forwards thoughts.
chris
the var $_explicittype = "vosubject"; should point actionscript class, in case 'vo.vosubject'. [remoteclass(alias="vosubject")] should match explicit type. in short, both reference actionscript class.
at first glance code seems follow mvc pattern, good. must admit skimmed through code find actual question.
mysql flex amfphp