<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>blog.log2e.com &#187; AMFPHP</title>
	<atom:link href="http://blog.log2e.com/tag/amfphp/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.log2e.com</link>
	<description>Tutorials and Code Snippets</description>
	<lastBuildDate>Tue, 25 May 2010 12:47:32 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.2</generator>
		<item>
		<title>What&#8217;s in the Zend Framework for the Flash/Flex Developer?</title>
		<link>http://blog.log2e.com/2008/11/26/whats-in-the-zend-framework-for-the-flashflex-developer/</link>
		<comments>http://blog.log2e.com/2008/11/26/whats-in-the-zend-framework-for-the-flashflex-developer/#comments</comments>
		<pubDate>Wed, 26 Nov 2008 17:01:39 +0000</pubDate>
		<dc:creator>Stefan Schmalhaus</dc:creator>
				<category><![CDATA[AMFPHP]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Zend Amf]]></category>
		<category><![CDATA[Zend]]></category>

		<guid isPermaLink="false">http://blog.log2e.com/?p=109</guid>
		<description><![CDATA[The 1.7 release of the Zend Framework includes the new Zend_Amf package which provides a gateway server implementation for AMF remoting.  By the time of writing this article, there are not many resources available yet (a good starting point is here), and the few tutorials mostly guide you through the process of setting up the [...]]]></description>
			<content:encoded><![CDATA[<p>The 1.7 release of the <a title="Zend Framework" href="http://framework.zend.com" target="_blank" onclick="pageTracker._trackPageview('/outgoing/framework.zend.com?referer=');">Zend Framework</a> includes the new <a title="Zend_Amf" href="http://framework.zend.com/manual/en/zend.amf.html" target="_blank" onclick="pageTracker._trackPageview('/outgoing/framework.zend.com/manual/en/zend.amf.html?referer=');">Zend_Amf</a> package which provides a gateway server implementation for AMF remoting.  By the time of writing this article, there are not many resources available yet (a good starting point is <a title="Zend_Amf Resources" href="http://diamondtearz.org/blog/zend_amf-collection/" target="_blank" onclick="pageTracker._trackPageview('/outgoing/diamondtearz.org/blog/zend_amf-collection/?referer=');">here</a>), and the few tutorials mostly guide you through the process of setting up the bootstrap file and establishing a MySQL database connection by using <code>mysql_connect()</code> directly in the service classes.</p>
<p><span id="more-109"></span></p>
<p>I would like to introduce a Zend AMF server setup that makes use of some of Zend&#8217;s best practices like configuration files, database adapters and models. If you are a Flash/Flex developer coming from an <a title="AMFPHP" href="http://www.amfphp.org" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.amfphp.org?referer=');">AMFPHP</a> background and have never worked with the Zend framework before, you may easily feel overwhelmed by the framework&#8217;s complexity. This article is not meant to present a thourough overview of all Zend features you could possibly utilize in your Flex/Flash development work, but it might motivate you to dive deeper into the framework&#8217;s features.</p>
<h3>The Folder Structure</h3>
<p>First of all, even if I only need the AMF server from the Zend framework I set up my server directories like I would do with any other Zend/PHP application. If you already have some experience with the Zend framework this folder structure probably looks familiar to you:</p>
<p><a href="http://blog.log2e.com/wp-content/uploads/2008/11/zend_amf_setup.gif"><img class="alignnone size-medium wp-image-120" title="Zend Framework Folder Structure" src="http://blog.log2e.com/wp-content/uploads/2008/11/zend_amf_setup.gif" alt="" width="192" height="266" /></a></p>
<p>This is a rudimentary folder structure, of course, because a typical Zend application with an HTML frontend has additional folders for controllers, views, layouts, forms, plugins, helpers, etc. But the basic setup is the same: We have an <em>application</em> and a <em>library</em> folder that are outside the web server&#8217;s root directory (<em>public</em>). The Zend framework packages are inside the <em>library</em> folder, and below the <em>application</em> folder there are a <em>config</em> and a <em>models</em> folder. For the special purpose of the AMF gateway, I added a <em>services</em> folder which is supposed to contain all service class files.</p>
<h3>The Database and the Configuration File</h3>
<p>Let&#8217;s assume we are working on an application that needs to manage user accounts. A very basic table would look like this:</p>
<div class="geshi no sql">
<div class="head">CREATE TABLE users (</div>
<ol>
<li class="li1">
<div class="de1">&nbsp; id int<span class="br0">&#40;</span><span class="nu0">11</span><span class="br0">&#41;</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span> <span class="kw1">AUTO_INCREMENT</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; username varchar<span class="br0">&#40;</span><span class="nu0">32</span><span class="br0">&#41;</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span> <span class="kw1">DEFAULT</span> <span class="st0">&#39;&#39;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; password varchar<span class="br0">&#40;</span><span class="nu0">32</span><span class="br0">&#41;</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span> <span class="kw1">DEFAULT</span> <span class="st0">&#39;&#39;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; email varchar<span class="br0">&#40;</span><span class="nu0">255</span><span class="br0">&#41;</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span> <span class="kw1">DEFAULT</span> <span class="st0">&#39;&#39;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; firstname varchar<span class="br0">&#40;</span><span class="nu0">50</span><span class="br0">&#41;</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span> <span class="kw1">DEFAULT</span> <span class="st0">&#39;&#39;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; lastname varchar<span class="br0">&#40;</span><span class="nu0">50</span><span class="br0">&#41;</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span> <span class="kw1">DEFAULT</span> <span class="st0">&#39;&#39;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw1">PRIMARY</span> <span class="kw1">KEY</span> <span class="br0">&#40;</span>id<span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#41;</span>;</div>
</li>
</ol>
</div>
<p>The database credentials are stored in an INI file (<em>app.ini</em>). In this example there are configuration data for both a production system and a development system. Because the development system configuration data are very similar to those for production, the development section inherits from the production section:</p>
<div class="geshi no ini">
<ol>
<li class="li1">
<div class="de1"><span class="re0"><span class="br0">&#91;</span>production<span class="br0">&#93;</span></span></div>
</li>
<li class="li1">
<div class="de1">database.<span class="re1">adapter </span><span class="sy0">=</span><span class="re2"> PDO_MYSQL</span></div>
</li>
<li class="li1">
<div class="de1">database.params.<span class="re1">host </span><span class="sy0">=</span><span class="re2"> localhost</span></div>
</li>
<li class="li1">
<div class="de1">database.params.<span class="re1">dbname </span><span class="sy0">=</span><span class="re2"> prod_dbname</span></div>
</li>
<li class="li1">
<div class="de1">database.params.<span class="re1">username </span><span class="sy0">=</span><span class="re2"> dbusername</span></div>
</li>
<li class="li1">
<div class="de1">database.params.<span class="re1">password </span><span class="sy0">=</span><span class="re2"> dbpassword</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="re0"><span class="br0">&#91;</span>development : production<span class="br0">&#93;</span></span></div>
</li>
<li class="li1">
<div class="de1">database.params.<span class="re1">dbname </span><span class="sy0">=</span><span class="re2"> dev_dbname</span></div>
</li>
</ol>
</div>
<p>This configuration file also allows you to easily change the database adapter (if needed).</p>
<h3>The Bootstrap File</h3>
<p>Let&#8217;s take a look at the bootstrap file (<em>index.php</em>):</p>
<div class="geshi php">
<div class="head">&lt;?php</div>
<ol>
<li class="li1">
<div class="de1"><span class="kw3">define</span><span class="br0">&#40;</span><span class="st0">&#39;APPLICATION_PATH&#39;</span><span class="sy0">,</span> <span class="kw3">realpath</span><span class="br0">&#40;</span><span class="kw3">dirname</span><span class="br0">&#40;</span><span class="kw2">__FILE__</span><span class="br0">&#41;</span> <span class="sy0">.</span> <span class="st0">&#39;/../application/&#39;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw3">set_include_path</span><span class="br0">&#40;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="kw3">get_include_path</span><span class="br0">&#40;</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="sy0">.</span> PATH_SEPARATOR <span class="sy0">.</span> APPLICATION_PATH <span class="sy0">.</span> <span class="st0">&#39;/../library/&#39;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="sy0">.</span> PATH_SEPARATOR <span class="sy0">.</span> APPLICATION_PATH <span class="sy0">.</span> <span class="st0">&#39;/services/&#39;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="sy0">.</span> PATH_SEPARATOR <span class="sy0">.</span> APPLICATION_PATH <span class="sy0">.</span> <span class="st0">&#39;/models/&#39;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">require_once</span> <span class="st0">&#39;Zend/Loader.php&#39;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">Zend_Loader<span class="sy0">::</span><span class="me2">registerAutoload</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="re1">$server</span> <span class="sy0">=</span> <span class="kw2">new</span> Zend_Amf_Server<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="re1">$server</span><span class="sy0">-&gt;</span><span class="me1">setClass</span><span class="br0">&#40;</span><span class="st0">&#39;UsersService&#39;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="re1">$server</span><span class="sy0">-&gt;</span><span class="me1">setClassMap</span><span class="br0">&#40;</span><span class="st0">&#39;UserVO&#39;</span><span class="sy0">,</span><span class="st0">&#39;User&#39;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="re1">$server</span><span class="sy0">-&gt;</span><span class="me1">setProduction</span><span class="br0">&#40;</span><span class="kw2">false</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw3">echo</span><span class="br0">&#40;</span><span class="re1">$server</span><span class="sy0">-&gt;</span><span class="me1">handle</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
</ol>
</div>
<p>This bootstrap file is very similar to the standard bootstrap files you find in other tutorials or in the Zend Reference Guide. It adds some include paths, initializes the Zend autoload feature for classes, and sets up the AMF server.  </p>
<h3>The Service Classes</h3>
<p>Utilizing the <em>Zend_Config</em> and <em>Zend_Db</em> packages, we set up the database connection in a base service class that the actual service classes inherit from. In line 7 in the listing below we provide a default database adapter for all subsequent instances of <em>Zend_Db_Table</em> objects in our application (for more information, please refer to the <a title="Zend_Db" href="http://framework.zend.com/manual/en/zend.db.table.html" target="_blank" onclick="pageTracker._trackPageview('/outgoing/framework.zend.com/manual/en/zend.db.table.html?referer=');">Zend_Db chapter</a> in the Reference Guide). This way we keep the logic of creating a database connection in one central place. </p>
<div class="geshi php">
<div class="head">&lt;?php</div>
<ol>
<li class="li1">
<div class="de1"><span class="kw2">class</span> BaseService </div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="kw2">public</span> <span class="kw2">function</span> __construct<span class="br0">&#40;</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="br0">&#123;</span> &nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="re1">$configuration</span> <span class="sy0">=</span> <span class="kw2">new</span> Zend_Config_Ini<span class="br0">&#40;</span>APPLICATION_PATH <span class="sy0">.</span> <span class="st0">&#39;/config/app.ini&#39;</span><span class="sy0">,</span> <span class="st0">&#39;development&#39;</span><span class="br0">&#41;</span><span class="sy0">;</span> &nbsp; &nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="re1">$dbAdapter</span> <span class="sy0">=</span> Zend_Db<span class="sy0">::</span><span class="me2">factory</span><span class="br0">&#40;</span><span class="re1">$configuration</span><span class="sy0">-&gt;</span><span class="me1">database</span><span class="br0">&#41;</span><span class="sy0">;</span> &nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; Zend_Db_Table_Abstract<span class="sy0">::</span><span class="me2">setDefaultAdapter</span><span class="br0">&#40;</span><span class="re1">$dbAdapter</span><span class="br0">&#41;</span><span class="sy0">;</span> </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
<p>The only real service class in our example is <em>UsersService</em> which extends <em>BaseService</em> and invokes the parent class&#8217;s constructor by calling <code>parent::__construct();</code>. For the sake of simplicity it contains only one method (<code>getUsers()</code>):</p>
<div class="geshi php">
<div class="head">&lt;?php</div>
<ol>
<li class="li1">
<div class="de1"><span class="kw2">class</span> UsersService <span class="kw2">extends</span> BaseService</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#123;</span> &nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="kw2">public</span> <span class="kw2">function</span> __construct<span class="br0">&#40;</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; parent<span class="sy0">::</span>__construct<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="kw2">public</span> <span class="kw2">function</span> getUsers<span class="br0">&#40;</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="re1">$usersArray</span> <span class="sy0">=</span> <span class="kw3">array</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="re1">$table</span> <span class="sy0">=</span> <span class="kw2">new</span> Users<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="re1">$result</span> <span class="sy0">=</span> <span class="re1">$table</span><span class="sy0">-&gt;</span><span class="me1">fetchAll</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="kw1">foreach</span><span class="br0">&#40;</span><span class="re1">$result</span> <span class="kw1">as</span> <span class="re1">$row</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span> &nbsp; </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="re1">$user</span> <span class="sy0">=</span> <span class="kw2">new</span> User<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="re1">$user</span><span class="sy0">-&gt;</span><span class="me1">id</span> <span class="sy0">=</span> <span class="re1">$row</span><span class="sy0">-&gt;</span><span class="me1">id</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="re1">$user</span><span class="sy0">-&gt;</span><span class="me1">username</span> <span class="sy0">=</span> <span class="re1">$row</span><span class="sy0">-&gt;</span><span class="me1">username</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="re1">$user</span><span class="sy0">-&gt;</span><span class="me1">email</span> <span class="sy0">=</span> <span class="re1">$row</span><span class="sy0">-&gt;</span><span class="me1">email</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="re1">$user</span><span class="sy0">-&gt;</span><span class="me1">firstname</span> <span class="sy0">=</span> <span class="re1">$row</span><span class="sy0">-&gt;</span><span class="me1">firstname</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="re1">$user</span><span class="sy0">-&gt;</span><span class="me1">lastname</span> <span class="sy0">=</span> <span class="re1">$row</span><span class="sy0">-&gt;</span><span class="me1">lastname</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="kw3">array_push</span><span class="br0">&#40;</span><span class="re1">$usersArray</span><span class="sy0">,</span> <span class="re1">$user</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="re1">$usersArray</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
<p>You may wonder what the <em>Users</em> class does (line 12 in the above code listing). Here&#8217;s the answer: It&#8217;s a model class.</p>
<h3>The Model Class</h3>
<p>Models are another important concept of the Zend framework. Although the classical MVC pattern doesn&#8217;t apply in the context of the Zend AMF server, I stick to this concept here because it may come in handy sometimes. Imagine an application that is supposed to support both a Flash and an HTML interface. By following the framework&#8217;s MVC guidelines, we are able to build an application engine that uses the same model classes for both the AMF server gateway and the MVC-based HTML frontend.</p>
<p>The class <em>Users</em> is located in the <em>models</em> folder. It extends <em>Zend_Db_Table</em> and holds the name of the corresponding database table:</p>
<div class="geshi php">
<div class="head">&lt;?php</div>
<ol>
<li class="li1">
<div class="de1"><span class="kw2">class</span> Users <span class="kw2">extends</span> Zend_Db_Table</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;protected <span class="re1">$_name</span> <span class="sy0">=</span> <span class="st0">&#39;users&#39;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
<p>Remember that we provided an application-wide database adapter for all <em>Zend_Db_Table</em> objects (see line 7 in the <em>BaseService</em> class). By creating an instance of <em>Users</em> (which inherits all methods from <em>Zend_Db_Table</em>) we are able to use <code>fetchAll()</code> to retrieve all rows from the table <em>users</em>.</p>
<h3>The Value Object Class</h3>
<p>The class <em>User</em> (see line 17 in the <em>UsersService</em> code listing) is a helper class that allows us to send an array of typed objects to the Flash player. This is especially useful in Flex-based applications where you want to use value objects for data-binding, for example. By the way, the class <em>User</em> doesn&#8217;t look any different than a VO class in an <a title="AMFPHP" href="http://www.amfphp.org" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.amfphp.org?referer=');">AMFPHP</a> context.</p>
<div class="geshi php">
<div class="head">&lt;?php</div>
<ol>
<li class="li1">
<div class="de1"><span class="kw2">class</span> User <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="kw2">public</span> <span class="re1">$id</span> <span class="sy0">=</span> <span class="nu0">0</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="kw2">public</span> <span class="re1">$username</span> <span class="sy0">=</span> <span class="st0">&#39;&#39;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="kw2">public</span> <span class="re1">$password</span> <span class="sy0">=</span> <span class="st0">&#39;&#39;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="kw2">public</span> <span class="re1">$firstname</span> <span class="sy0">=</span> <span class="st0">&#39;&#39;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="kw2">public</span> <span class="re1">$lastnamne</span> <span class="sy0">=</span> <span class="st0">&#39;&#39;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="kw2">public</span> <span class="re1">$email</span> <span class="sy0">=</span> <span class="st0">&#39;&#39;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
<p>By calling <code>$server->setClassMap('UserVO','User');</code> inside the bootstrap file, the <em>User</em> objects are mapped to <em>UserVO</em>. </p>
<p>I skip the Flex/Flash part here because this topic is well covered in other tutorials. But I hope you caught a glimpse of how you can leverage the power of other components inside the Zend framework &#8211; even if you are only interested in the Zend AMF server. There are more scenarios where the Zend framework may come in handy for a Flash/Flex developer (for example, think of generating PDF files on the fly by using <em>Zend_Pdf</em>).</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.log2e.com/2008/11/26/whats-in-the-zend-framework-for-the-flashflex-developer/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>Using AMFPHP with ADOdb</title>
		<link>http://blog.log2e.com/2008/05/05/using-amfphp-with-adodb/</link>
		<comments>http://blog.log2e.com/2008/05/05/using-amfphp-with-adodb/#comments</comments>
		<pubDate>Mon, 05 May 2008 11:15:09 +0000</pubDate>
		<dc:creator>Stefan Schmalhaus</dc:creator>
				<category><![CDATA[ADOdb]]></category>
		<category><![CDATA[AMFPHP]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[Cairngorm]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Remoting]]></category>

		<guid isPermaLink="false">http://blog.log2e.com/?p=1</guid>
		<description><![CDATA[Very often you want to add functionality from a PHP library to your AMFPHP service classes. This short tutorial shows the use of ADOdb as database abstraction layer and may be especially helpful for beginners with AMFPHP. ADOdb is a widely used database abstraction library that supports a lot of databases. If you want to [...]]]></description>
			<content:encoded><![CDATA[<p>Very often you want to add functionality from a PHP library to your <a title="AMFPHP" href="http://www.amfphp.org" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.amfphp.org?referer=');">AMFPHP</a> service classes. This short tutorial shows the use of <a title="ADOdb" href="http://adodb.sourceforge.net/" target="_blank" onclick="pageTracker._trackPageview('/outgoing/adodb.sourceforge.net/?referer=');">ADOdb</a> as database abstraction layer and may be especially helpful for beginners with AMFPHP.<br />
<span id="more-1"></span><br />
ADOdb is a widely used database abstraction library that supports a lot of databases. If you want to add cross-database support to your Flex application, ADOdb is an excellent choice. But even if you only use MySQL as your bread-and-butter database, ADOdb will greatly help you to simplify your database operations.</p>
<h3>Folder Structure</h3>
<p>First, let&#8217;s take a look at the folder structure on the server. I usually organize my server directories like this:</p>
<p><img style="border: 0pt none; margin: 0px;" src="http://blog.log2e.com/wp-content/uploads/2008/05/amfphp_include_folder.gif" alt="" width="240" height="110" /></p>
<p>There is an <em>includes</em> folder on the same level as the <em>amfphp</em> installation folder. The <em>includes</em> folder contains other folders, one for each PHP library (in this case <a title="ADOdb" href="http://adodb.sourceforge.net/" target="_blank" onclick="pageTracker._trackPageview('/outgoing/adodb.sourceforge.net/?referer=');">ADOdb</a>, <a title="PHPMailer" href="http://phpmailer.codeworxtech.com/" target="_blank" onclick="pageTracker._trackPageview('/outgoing/phpmailer.codeworxtech.com/?referer=');">PHPMailer</a> and <a title="TCPDF" href="http://www.tcpdf.com" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.tcpdf.com?referer=');">TCPDF</a>). Download the ADOdb library <a title="Download ADOdb" href="http://adodb.sourceforge.net/#download" target="_blank" onclick="pageTracker._trackPageview('/outgoing/adodb.sourceforge.net/_download?referer=');">from here</a> and upload the files to the <em>includes/adodb</em> folder.</p>
<h3>globals.php</h3>
<p>It is recommended that you add globally used variables to AMFPHP&#8217;s <em>globals.php</em> file. Since most of your service classes probably need access to the database this file is the best place for configuring your database settings and the path to your external PHP libraries. So let&#8217;s add these lines to the <em>globals.php</em> file:</p>
<div class="geshi no php">
<ol>
<li class="li1">
<div class="de1"><span class="kw3">define</span><span class="br0">&#40;</span><span class="st0">&#39;DB_HOST&#39;</span><span class="sy0">,</span> <span class="st0">&#39;localhost&#39;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw3">define</span><span class="br0">&#40;</span><span class="st0">&#39;DB_USER&#39;</span><span class="sy0">,</span> <span class="st0">&#39;dbuser&#39;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw3">define</span><span class="br0">&#40;</span><span class="st0">&#39;DB_PASSWORD&#39;</span><span class="sy0">,</span> <span class="st0">&#39;dbpassword&#39;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw3">define</span><span class="br0">&#40;</span><span class="st0">&#39;DB_NAME&#39;</span><span class="sy0">,</span> <span class="st0">&#39;dbname&#39;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw3">define</span><span class="br0">&#40;</span><span class="st0">&#39;INCLUDES_PATH&#39;</span><span class="sy0">,</span> <span class="st0">&#39;/base/server/path/includes/&#39;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
</ol>
</div>
<p>Of course, you have to adjust the database and path settings to your needs. The <code>INCLUDES_PATH</code> constant should hold the absolute path to your <em>includes</em> directory on the server.</p>
<h3>Sample Classes</h3>
<p>Let&#8217;s say you have a MySQL database that holds a table with product data. For the sake of simplicity, we assume that there are only two fields in this table, <em>product_id</em> and <em>product_name</em>. </p>
<p>If you use the <a title="Cairngorm" href="http://labs.adobe.com/wiki/index.php/Cairngorm" target="_blank" onclick="pageTracker._trackPageview('/outgoing/labs.adobe.com/wiki/index.php/Cairngorm?referer=');">Cairngorm</a> framework for your Flex application you are familiar with the concept of Value Objects (VOs). Instead of using XML or simple arrays, VOs allow for sending back and forth typed objects between Flex and AMFPHP. We define a simple ProductVO class and place the <em>ProductVO.php</em> file in AMFPHP&#8217;s <em>services</em> folder.</p>
<div class="geshi no php">
<ol>
<li class="li1">
<div class="de1"><span class="kw2">&lt;?php</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">class</span> ProductVO</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="kw2">var</span> <span class="re1">$_explicitType</span> <span class="sy0">=</span> <span class="st0">&#39;ProductVO&#39;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="kw2">var</span> <span class="re1">$productId</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="kw2">var</span> <span class="re1">$productName</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">?&gt;</span></div>
</li>
</ol>
</div>
<p>Now we add a service class (<em>ProductsService.php</em>) to the <em>services</em> folder. The <em>ProductsService.php</em> file includes the ProductVO class and the ADOdb library. The constructor establishes the database connection (for the syntax take a look at the ADOdb documentation), and the <code>getProducts()</code> mehod retrieves all products from the database, wraps them into ProductVO objects and sends them back to your Flex application.</p>
<div class="geshi no php">
<ol>
<li class="li1">
<div class="de1"><span class="kw2">&lt;?php</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">require_once</span><span class="br0">&#40;</span>INCLUDES_PATH<span class="sy0">.</span><span class="st0">&#39;adodb/adodb.inc.php&#39;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">require_once</span><span class="br0">&#40;</span><span class="st0">&#39;ProductVO.php&#39;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">class</span> ProductsService</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="kw2">var</span> <span class="re1">$db</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="coMULTI">/**</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp; &nbsp; * Constructor</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp; &nbsp; */</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="kw2">function</span> ProductsService<span class="br0">&#40;</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="re1">$this</span><span class="sy0">-&gt;</span><span class="me1">db</span> <span class="sy0">=</span> NewADOConnection<span class="br0">&#40;</span><span class="st0">&#39;mysql&#39;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="re1">$this</span><span class="sy0">-&gt;</span><span class="me1">db</span><span class="sy0">-&gt;</span><span class="me1">Connect</span><span class="br0">&#40;</span>DB_HOST<span class="sy0">,</span> DB_USER<span class="sy0">,</span> DB_PASSWORD<span class="sy0">,</span> DB_NAME<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy0">!</span><span class="re1">$this</span><span class="sy0">-&gt;</span><span class="me1">db</span><span class="br0">&#41;</span> <span class="kw3">die</span><span class="br0">&#40;</span><span class="st0">&#39;Connection failed&#39;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="re1">$this</span><span class="sy0">-&gt;</span><span class="me1">db</span><span class="sy0">-&gt;</span><span class="me1">SetFetchMode</span><span class="br0">&#40;</span>ADODB_FETCH_ASSOC<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="coMULTI">/**</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp; &nbsp; * This method retrieves all products from the database</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp; &nbsp; */</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="kw2">function</span> getProducts<span class="br0">&#40;</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="re1">$products</span> <span class="sy0">=</span> <span class="kw3">array</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="re1">$sql</span> <span class="sy0">=</span> <span class="st0">&#39;SELECT product_id, product_name FROM products&#39;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="re1">$result</span> <span class="sy0">=</span> <span class="re1">$this</span><span class="sy0">-&gt;</span><span class="me1">db</span><span class="sy0">-&gt;</span><span class="me1">Execute</span><span class="br0">&#40;</span><span class="re1">$sql</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re1">$result</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="kw1">while</span> <span class="br0">&#40;</span><span class="sy0">!</span><span class="re1">$result</span><span class="sy0">-&gt;</span><span class="me1">EOF</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re1">$productVO</span> <span class="sy0">=</span> <span class="kw2">new</span> ProductVO<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re1">$productVO</span><span class="sy0">-&gt;</span><span class="me1">productId</span> <span class="sy0">=</span> <span class="re1">$result</span><span class="sy0">-&gt;</span><span class="me1">fields</span><span class="br0">&#91;</span><span class="st0">&#39;product_id&#39;</span><span class="br0">&#93;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re1">$productVO</span><span class="sy0">-&gt;</span><span class="me1">productName</span> <span class="sy0">=</span> <span class="re1">$result</span><span class="sy0">-&gt;</span><span class="me1">fields</span><span class="br0">&#91;</span><span class="st0">&#39;product_name&#39;</span><span class="br0">&#93;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">array_push</span><span class="br0">&#40;</span><span class="re1">$products</span><span class="sy0">,</span> <span class="re1">$productVO</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re1">$result</span><span class="sy0">-&gt;</span><span class="me1">MoveNext</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="re1">$products</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">?&gt;</span></div>
</li>
</ol>
</div>
<p>In a similar way you can add other PHP libraries to your AMFPHP classes (like the above mentioned PHPMailer and TCPDF libraries). I hope this example helps you to utilize the power of some of the most popular PHP libraries for your Flex applications. If you have suggestions or requests please comment or get in touch with me.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.log2e.com/2008/05/05/using-amfphp-with-adodb/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

