<?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>Jacob Wright - Flex, AIR, PHP, etc. &#187; PHP</title>
	<atom:link href="http://jacwright.com/blog/category/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://jacwright.com/blog</link>
	<description>Flex, AIR, PHP, etc.</description>
	<lastBuildDate>Thu, 29 Jul 2010 15:05:34 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Simple REST server in PHP &#8211; Supports JSON &amp; AMF</title>
		<link>http://jacwright.com/blog/250/simple-rest-server-in-php-supports-json-amf/</link>
		<comments>http://jacwright.com/blog/250/simple-rest-server-in-php-supports-json-amf/#comments</comments>
		<pubDate>Mon, 16 Nov 2009 17:37:29 +0000</pubDate>
		<dc:creator>Jacob Wright</dc:creator>
				<category><![CDATA[ActionScript 3]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://jacwright.com/blog/?p=250</guid>
		<description><![CDATA[After building a couple of RESTful services using the Zend Framework, I decided to create a dead simple REST server that allowed me to skip all the features I didn't need as well as a tons of classes that came with Zend Framework MVC. There are still useful features to add (XML support for example), [...]]]></description>
			<content:encoded><![CDATA[<p>After building a couple of RESTful services using the <a href="http://framework.zend.com/">Zend Framework</a>, I decided to create a dead simple REST server that allowed me to skip all the features I didn't need as well as a <strong>tons of classes</strong> that came with Zend Framework MVC. There are still useful features to add (XML support for example), but overall I'm quite happy with what I've come up with.</p>
<p>My solution, <code>RestServer</code>, is a JSON REST server, so far. It should be trivial to add support for XML or other formats, but there would have to be assumptions on what your object would look like in XML (XML-RPC style, your own custom XML format, etc). First we'll look at the classes that you write to handle the requests, then we'll look at how to tie it together in your index.php file.</p>
<h3>REST Controllers</h3>
<p>The <code>RestServer</code> class assumes you are using <a href="#url-rewrite" title="Example .htaccess file for Apache">URL rewriting</a> and looks at the URL from the request to map to the necessary actions. The map that gets a request from URL to class method is all in the doc-comments of the classes. Here is an example of a class that would handle some user actions:</p>
<div class="syntax_hilite">
<div id="php-4">
<div class="php"><span style="color:#000000; font-weight:bold;">class</span> TestController<br />
<span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; <span style="color:#008000;">/**<br />
&nbsp; &nbsp;&nbsp; * Returns a JSON string object to the browser when hitting the root of the domain<br />
&nbsp; &nbsp;&nbsp; * <br />
&nbsp; &nbsp;&nbsp; * @url GET /<br />
&nbsp; &nbsp;&nbsp; */</span><br />
&nbsp; &nbsp; public <span style="color:#000000; font-weight:bold;">function</span> test<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#616100;">return</span> <span style="color:#FF0000;">"Hello World"</span>;<br />
&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color:#008000;">/**<br />
&nbsp; &nbsp;&nbsp; * Logs in a user with the given username and password POSTed. Though true<br />
&nbsp; &nbsp;&nbsp; * REST doesn't believe in sessions, it is often desirable for an AJAX server.<br />
&nbsp; &nbsp;&nbsp; * <br />
&nbsp; &nbsp;&nbsp; * @url POST /login<br />
&nbsp; &nbsp;&nbsp; */</span><br />
&nbsp; &nbsp; public <span style="color:#000000; font-weight:bold;">function</span> login<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$username</span> = <span style="color:#0000FF;">$_POST</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#FF0000;">'username'</span><span style="color:#006600; font-weight:bold;">&#93;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$password</span> = <span style="color:#0000FF;">$_POST</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#FF0000;">'password'</span><span style="color:#006600; font-weight:bold;">&#93;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#FF9933; font-style:italic;">// validate input and log the user in</span><br />
&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color:#008000;">/**<br />
&nbsp; &nbsp;&nbsp; * Gets the user by id or current user<br />
&nbsp; &nbsp;&nbsp; * <br />
&nbsp; &nbsp;&nbsp; * @url GET /users/:id<br />
&nbsp; &nbsp;&nbsp; * @url GET /users/current<br />
&nbsp; &nbsp;&nbsp; */</span><br />
&nbsp; &nbsp; public <span style="color:#000000; font-weight:bold;">function</span> getUser<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$id</span> = <span style="color:#000000; font-weight:bold;">null</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#616100;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$id</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$user</span> = User::<span style="color:#006600;">load</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$id</span><span style="color:#006600; font-weight:bold;">&#41;</span>; <span style="color:#FF9933; font-style:italic;">// possible user loading method</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#616100;">else</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$user</span> = <span style="color:#0000FF;">$_SESSION</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#FF0000;">'user'</span><span style="color:#006600; font-weight:bold;">&#93;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#616100;">return</span> <span style="color:#0000FF;">$user</span>; <span style="color:#FF9933; font-style:italic;">// serializes object into JSON</span><br />
&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color:#008000;">/**<br />
&nbsp; &nbsp;&nbsp; * Saves a user to the database<br />
&nbsp; &nbsp;&nbsp; * <br />
&nbsp; &nbsp;&nbsp; * @url POST /users<br />
&nbsp; &nbsp;&nbsp; * @url PUT /users/:id<br />
&nbsp; &nbsp;&nbsp; */</span><br />
&nbsp; &nbsp; public <span style="color:#000000; font-weight:bold;">function</span> saveUser<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$id</span> = <span style="color:#000000; font-weight:bold;">null</span>, <span style="color:#0000FF;">$data</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#FF9933; font-style:italic;">// ... validate $data properties such as $data-&gt;username, $data-&gt;firstName, etc.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$data</span>-&gt;<span style="color:#006600;">id</span> = <span style="color:#0000FF;">$id</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$user</span> = User::<span style="color:#006600;">saveUser</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$data</span><span style="color:#006600; font-weight:bold;">&#41;</span>; <span style="color:#FF9933; font-style:italic;">// saving the user to the database&nbsp; </span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#616100;">return</span> <span style="color:#0000FF;">$user</span>; <span style="color:#FF9933; font-style:italic;">// returning the updated or newly created user object</span><br />
&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><br />
<span style="color:#006600; font-weight:bold;">&#125;</span></div>
</div>
</div>
<p></p>
<p>Let's walk through the above <code>TestController</code> class to talk about the features demonstrated. First we'll look at the <code>test</code> method. You'll notice there is a new kind of doc-comment tag in the docblock. <code>@url</code> maps a URL to the method below it and is in the form:</p>
<p><code>@url &lt;REQUEST_METHOD&gt; &lt;URL&gt;</code></p>
<p>In this particular example, when someone does a GET on http://www.example.com/ (assuming example.com is where our service is located) it will print out:</p>
<p><code>"Hello World"</code></p>
<p>which is a valid representation of a string in JSON.</p>
<p>Moving on to the next method, <code>login</code>, we see the <code>@url</code> maps any POSTs to http://www.example.com/login to the <code>login</code> method. Getting data from a regular web-type POST is the same as any PHP application, allowing you to use your own validation or other framework in conjunction with this REST server. Sessions can also be kept if desired. Though keeping sessions isn't true REST style, often all we want a REST server for is to serve up data to our ajax application, and it can be easier to just use sessions than something more RESTful.</p>
<p>Next we have our <code>getUser</code> method (you'll notice that it doesn't really matter what I name my methods because our <code>@url</code> directives define what URLs map to the method). You can see a couple of things here. First, we have multiple <code>@url</code> mappings for this method. And second, there is an odd "/:id" in that first URL mapping. The RestServer treats any ":keyword" placeholders as wildcards in the URL and will take that section of the URL and pass it into the parameter with the same name in the method. In this example, when hitting http://www.example.com/users/1234, <code>$id</code> will equal <code>1234</code>. When hitting http://www.example.com/users/current, <code>$id</code> will equal <code>null</code>. It doesn't matter what order your parameters are in, so long as they have the same name as the placeholder (<code>:id</code> and <code>$id</code>, <code>:username</code> and <code>$username</code>). You'll also want to be sure to make your parameters optional (<code>$id = null</code>) when you have several URL mappings that don't all require a parameter. Otherwise you'll have an error thrown telling you that you didn't pass in a required parameter.</p>
<p>One last thing to note in <code>getUser</code> is that this method simply returns a User object. This gets serialized into JSON (or potentially XML) and printed out for consumption by the application.</p>
<p>Finally we get to <code>saveUser</code>. You see here we have multiple URL mappings again. This time they also have different HTTP methods (POST and PUT) for creating and updating a user. The new thing here is the <code>$data</code> variable. This is a special keyword parameter that will contain the value of whatever was POSTed or PUT to the server. This is different than your regular web POST in that it doesn't need to only be name-value pairs, but can be as robust as JSON, sending complex objects. For example, the body of a regular web POST, let's say the <code>login</code> request, might look like this:</p>
<p><code>username=bob&#038;password=supersecretpassw0rd</code></p>
<p>but POSTing a new user object for our <code>saveUser</code> method could look like this:</p>
<p><code>{ "username": "bob", "password": "supersecretpassword", "firstName": "Bob", "lastName": "Smith" }</code></p>
<p>So you're able to allow POSTing JSON in addition to regular web style POSTs.</p>
<p>I call these classes that handle the requests Controllers. And they can be completely self-contained with their URL mappings, database configs, etc. so that you could drop them into other RestServer services without any hassle.</p>
<h3>REST index.php</h3>
<p>In order to get the whole server kicked off, you'll want to create an index.php file, have your URL rewriting direct requests to it (another topic which you can learn about elsewhere), and create the RestServer and add controller classes to it for handling. <code>RestServer</code> will cache the URL mappings between requests using APC or a file to speed up requests. You won't have to load every controller file on every request if you use autoload and this cache, only the one needed for the request. The cache only runs in production mode. Here is an example index.php file:</p>
<div class="syntax_hilite">
<div id="php-5">
<div class="php">spl_autoload_register<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>; <span style="color:#FF9933; font-style:italic;">// don't load our classes unless we use them</span></p>
<p><span style="color:#0000FF;">$mode</span> = <span style="color:#FF0000;">'debug'</span>; <span style="color:#FF9933; font-style:italic;">// 'debug' or 'production'</span><br />
<span style="color:#0000FF;">$server</span> = <span style="color:#000000; font-weight:bold;">new</span> RestServer<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$mode</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
<span style="color:#FF9933; font-style:italic;">// $server-&gt;refreshCache(); // uncomment momentarily to clear the cache if classes change in production mode</span></p>
<p><span style="color:#0000FF;">$server</span>-&gt;<span style="color:#006600;">addClass</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'TestController'</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
<span style="color:#0000FF;">$server</span>-&gt;<span style="color:#006600;">addClass</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'ProductsController'</span>, <span style="color:#FF0000;">'/products'</span><span style="color:#006600; font-weight:bold;">&#41;</span>; <span style="color:#FF9933; font-style:italic;">// adds this as a base to all the URLs in this class</span></p>
<p><span style="color:#0000FF;">$server</span>-&gt;<span style="color:#006600;">handle</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</div>
</div>
<p></p>
<p>That's it. You can add as many classes as you like. If there are conflicts, classes added later will overwrite duplicate URL mappings that were added earlier. And the second parameter in <code>addClass</code> can be a base URL which will be prepended to URL mappings in the given class, allowing you to be more modular.</p>
<p>You can <a href="/blog/resources/RestServer.txt">view the RestServer class</a>, copy it and use it for your own purposes. It is under the MIT license. Features to be added include XML support and HTTP Authentication support. If you make this class better please share your updates with everyone by leaving a comment. I will try and keep this class updated with new features as they are shared. I hope you enjoy!</p>
<p>I changed the title of this post to remove the AMF portion but was asked to cover it, so I will quickly talk about the AMF support. <code>RestServer</code> supports the AMF format in addition to the JSON format. This is a binary format used by Adobe Flash in their remoting services, but because their remoting services are not RESTful, you can't use classes such as RemoteObject with REST.</p>
<p>In order to use the AMF format with this service, you'll need to have the Zend Framework in your classpath so that the classes to serialize and deserialize AMF are present (e.g. Zend/Amf/Parse/Amf3/Serializer.php). Then you're ready so server up AMF. The way you consume AMF in Flash is using URLLoader or URLStream to load the data and ByteArray to convert it into an object. To tell the server you want AMF rather than JSON your URLRequest object will need to add an Accept header of "application/x-amf". Below I will show you how this could be done.</p>
<div class="syntax_hilite">
<div id="actionscript-6">
<div class="actionscript"><span style="color: #0066CC;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getUser<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span><br />
<span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> loader:URLLoader = <span style="color: #000000; font-weight: bold;">new</span> URLLoader<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; loader.<span style="color: #006600;">dataFormat</span> = URLLoaderDataFormat.<span style="color: #006600;">BINARY</span>;<br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> request:URLRequest = <span style="color: #000000; font-weight: bold;">new</span> URLRequest<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">"http://www.example.com/users/current"</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; request.<span style="color: #006600;">requestHeaders</span>.<span style="color: #0066CC;">push</span><span style="color: #66cc66;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> URLRequestHeader<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">"Accept"</span>, <span style="color: #ff0000;">"application/x-amf"</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; loader.<span style="color: #006600;">addEventListener</span><span style="color: #66cc66;">&#40;</span>Event.<span style="color: #006600;">COMPLETE</span>, onComplete<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; loader.<span style="color: #0066CC;">load</span><span style="color: #66cc66;">&#40;</span>request<span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #66cc66;">&#125;</span></p>
<p><span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">function</span> onComplete<span style="color: #66cc66;">&#40;</span>event:Event<span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span><br />
<span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> loader:URLLoader = event.<span style="color: #0066CC;">target</span> as URLLoader;<br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> byteArray:ByteArray = loader.<span style="color: #0066CC;">data</span> as ByteArray;<br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> user:<span style="color: #0066CC;">Object</span> = byteArray.<span style="color: #006600;">readObject</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">// do something with the user</span><br />
<span style="color: #66cc66;">&#125;</span></div>
</div>
</div>
<p></p>
<p>You can even make your PHP objects cast into their actionscript equivalents using the <code>$_explicitType</code> property or <code>getASClassName</code> method in PHP as defined in the <a href="http://framework.zend.com/manual/en/zend.amf.server.html#zend.amf.server.typedobjects">documentation</a> and by using registerAlias in Flash.</p>
<p>Good luck and let me know if you end up using it!</p>
<p><a name="url-rewrite"></a><strong>Update:</strong> I am including an example .htaccess file for anyone who might need it. It will only rewrite requests to files that don't exist, so you can have images, css, or other PHP files in your webroot and they will still work. Anything that would give a 404 will redirect to your index.php file.</p>
<pre>
DirectoryIndex index.php
&lt;IfModule mod_rewrite.c&gt;
	RewriteEngine On
	RewriteRule ^$ index.php [QSA,L]
	RewriteCond %{REQUEST_FILENAME} !-f
	RewriteCond %{REQUEST_FILENAME} !-d
	RewriteRule ^(.*)$ index.php [QSA,L]
&lt;/IfModule&gt;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://jacwright.com/blog/250/simple-rest-server-in-php-supports-json-amf/feed/</wfw:commentRss>
		<slash:comments>52</slash:comments>
		</item>
		<item>
		<title>Flight Framework Highlights</title>
		<link>http://jacwright.com/blog/144/flight-framework-highlights/</link>
		<comments>http://jacwright.com/blog/144/flight-framework-highlights/#comments</comments>
		<pubDate>Thu, 12 Feb 2009 18:46:03 +0000</pubDate>
		<dc:creator>Jacob Wright</dc:creator>
				<category><![CDATA[ActionScript 3]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://jacwright.com/blog/?p=144</guid>
		<description><![CDATA[The Flight Framework is basically a collection of great utilities and independent tidbits that are organized to help us build our application. So I thought I'd make a call out to all the great standalone features in Flight, tell what they are, and leave it to another day to go more in depth on them. [...]]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://www.flightxd.com/flightframework/">Flight Framework</a> is basically a collection of great utilities and independent tidbits that are organized to help us build our application. So I thought I'd make a call out to all the great standalone features in Flight, tell what they are, and leave it to another day to go more in depth on them.</p>
<ol>
<li><strong>Fix for abstract classes</strong><br />
The tiny static classes in the flight.error package allow you to ensure an abstract class is not instantiated and that abstract methods are overriden.</li>
<li><strong>Registry</strong><br />
A global registry to store objects or data that anything in an application can have access too.</li>
<li><strong>Reflection<br />
</strong>The "Type" class handles all your reflection needs, including caching the expensive describeType calls and helping pull out needed metadata.</li>
<li><strong>Nice base for models<br />
</strong>The ValueObject class is a lazy IEventDispatcher that implements an equals() and clone() method which will work with all subclasses.</li>
<li><strong>ValueObjectEditor</strong><br />
This nifty utility lets you "edit" a ValueObject and then either commit the changes or revert them. Great for dialogs that let ValueObjects be changed but can then either Cancel or Ok the change.</li>
<li><strong>AS3 ArrayContainer</strong><br />
When working in an AS3 project, it would be nice to know when an array is changed, but Flex's ArrayCollection brings in half the framework when referenced. This little guy is the little brother AS3 has been wishing for.</li>
<li><strong>Services<br />
</strong>Some common services (RPC services, e.g. remoting, HTTP, etc.) that can be used in Flex or AS3. Much smaller than Flex's built in services.</li>
<li><strong>Configuration<br />
</strong>Config lets you define your application configurations in the app, an XML file, SharedObjects, and even the URL. Not only that, you can have multiple sources with some overriding others, and it is all accessible to your classes through a global config property. Super neat!</li>
<li><strong>Undo framework</strong><br />
With CommandHistory and all the command interfaces available, you can build undo-redo into your application without using any of the rest of Flight. Way, way awesome.</li>
<li><strong>Weak-referenced binding</strong><br />
Using the Bind class you can create faster, smaller, and weak-referenced binds. With two-way deep binds and being able to use in AS3-only projects without importing half the Flex framework, this is my favorite nugget.</li>
</ol>
<p>None of the above pieces references any of the others. They can all be used independently in your own frameworks or applications. That's my favorite part about Flight, is I can use it 100% if I want to, but if I can't that doesn't mean I have to give up my favorite features. I could use any/all of the above with any other framework, AS3 only, or Flex.</p>
]]></content:encoded>
			<wfw:commentRss>http://jacwright.com/blog/144/flight-framework-highlights/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>ooCommerce Help</title>
		<link>http://jacwright.com/blog/46/oocommerce-help/</link>
		<comments>http://jacwright.com/blog/46/oocommerce-help/#comments</comments>
		<pubDate>Thu, 27 Oct 2005 15:14:25 +0000</pubDate>
		<dc:creator>Jacob Wright</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Object Oriented Programming]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.jacwright.com/blog/46/oocommerce-help/</guid>
		<description><![CDATA[We are calling for developers who would like to join in on a fun object oriented PHP 5 ecommerce project entitle ooCommerce. Please email me or leave a comment if you would like to be a developer on this project or help in any way. The project is hosted at SourceForge and currently only has [...]]]></description>
			<content:encoded><![CDATA[<p>We are calling for developers who would like to join in on a fun object oriented PHP 5 ecommerce project entitle ooCommerce.  Please <a href="http://www.jacwright.com/blog/about/#contact">email me</a> or leave a comment if you would like to be a developer on this project or help in any way.  The project is hosted at <a href="http://sourceforge.net/projects/oocommerce/">SourceForge</a> and currently only has downloads for the template system it will be using, Arras Template.  Arras Template has a website at <a href="http://www.arrastemplate.org">www.arrastemplate.org</a>.</p>
<p>We (actually just myself right now) hope for this to be a good learning experience for others and are blogging about our design decisions how we are putting it together along the way.  This way it can be more of a case study in progress for others to learn in a more of hands-on way about object oriented programming.</p>
<p>Anyone is invited to help out, whether they know object oriented programming or not.  If OOP isn't a strong point, then you can just help coding (with guidance if desired).  If it is a strong point, then you can help in the design process as well and post some blog posts too.  I can do the design, database, classes, and all, but it would be a better project with more minds at work on it.  It will also be finished sometime this century.  Thank you for your help.</p>
]]></content:encoded>
			<wfw:commentRss>http://jacwright.com/blog/46/oocommerce-help/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>ooCommerce &#8211; A Deeper Look, More Decisions</title>
		<link>http://jacwright.com/blog/44/oocommerce-a-deeper-look-more-decisions/</link>
		<comments>http://jacwright.com/blog/44/oocommerce-a-deeper-look-more-decisions/#comments</comments>
		<pubDate>Fri, 07 Oct 2005 20:08:28 +0000</pubDate>
		<dc:creator>Jacob Wright</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Object Oriented Programming]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.jacwright.com/blog/?p=44</guid>
		<description><![CDATA[We've broken down our system down into some general parts <a href="http://www.jacwright.com/blog/43/the-overall-picture/" title="The Overall Picture">already</a>.  Now it's time to make some decisions on more specific pieces of ooCommerce and break the system down into some main objects.]]></description>
			<content:encoded><![CDATA[<p>We've broken down our system down into some general parts <a href="http://www.jacwright.com/blog/43/the-overall-picture/" title="The Overall Picture">already</a>.  Now it's time to make some decisions on more specific pieces of ooCommerce and break the system down into some main objects.</p>
<h3>What's in our Model</h3>
<p>Well, first off, we know we need a database to store all of our store's data.  We'll put off the database schema for now.  But what we do need to decide is what database to use.  And if we want to support several databases (which we do), what should we do to abstract the databases so that we use the same API no matter which database we use.</p>
<p>There are a few object-oriented options out there.  My favorite is Creole, a PHP 5 database abstraction layer which has a nice interface.  There is also <a href="http://www.devshed.com/c/a/PHP/Database-Abstraction-With-PHP/">PEAR's DB</a> which I've actually never used and have heard good things about.  The good things about these are that they're already built and they are actively developed which means others are fixing the bugs and adding features so we don't have to.  However, they are large, and the API of Creole is more of what Java programmers are use to and not what PHP developers are use to.  We could also create our own object oriented abstraction layer.  It would be smaller and use the API we want.  Much more simple code.  What do you think we should do?</p>
<p>The rest of the model would include the following list of objects, plus maybe a few we havn't thought of yet:</p>
<ul style="float:left">
<li>Customer</li>
<li>Address Book</li>
<li>Address</li>
<li>Payment (stored)</li>
<li>CustomerGroup</li>
<li>Order</li>
<li>OrderItem</li>
<li>PaymentMethod</li>
<li>DeliveryMethod</li>
<li>Product</li>
</ul>
<ul style="float:left">
<li>ProductReview</li>
<li>ProductSpecial</li>
<li>Catalog</li>
<li>Category</li>
<li>ShoppingCart</li>
<li>Translator</li>
<li>Pages</li>
<li>Content</li>
<li>Administrator</li>
<li>Report</li>
</ul>
<p style="clear:left">There of course will need to be an object type for each method of payment and other additions like that.  But I think we've got a pretty good layout here.  We may think of other things later, especially when we want to add features.</p>
<h3>How Will We Control Our Model</h3>
<p>The controller part of our system could be pretty simple, or pretty elaborate.  It all depends on what we value the most.  If we like simple the best, we can just have a bunch of PHP pages that our use will go to, they will run the code they need to run, using the model objects, and then they will pull in a template and output the results.  The URLs for these will be the name of the files, plus any parameters passed in the URL.  These will be pretty procedural, although we could make them into classes to keep it object oriented.  Another option is to push for search engine optimization by building our system with URLs that represent the page being displayed.  If we go simple, we will have a "product.php?id=10" or "product.php?name=james_bond_movie" displaying our products.  If we choose the more complex controller we would have "products/james_bond_movie" be our URL, which ranks it higher on the search engines.  To do this we would need to use mod_rewrite with Apache and set up our scripts to handle these URLs.  But it is very do-able.  Do we want full-featured, or do we want simplicity?  The value of ooCommerce will be higher with better features to it's users.</p>
<h3>Gotta See The View</h3>
<p>There are a million and one template systems out there (I wrote the 1,000,001 template system) and most very similar.  Smarty is the most popular it seems.  And most are similar to Smarty except less features or slower.  I happen to be partial to my templating system, <a href="http://www.jacwright.com/blog/arras/" title="The BEST Tempalting System to Walk the Face of the Earth">Arras</a>, which <em>is</em> different from most.  It is also fast, and small, and fun to use, and easy for designers to do design on.  So, I would like to use Arras.</p>
<p>So, what are your thoughts?  Please give feedback on the following design decisions.  We would love to get input.</p>
<ul>
<li>What database abstraction layer should we use?</li>
<li>Any additional classes I forgot in the model?</li>
<li>Go for a simpler controller, or nicer URLs?</li>
<li>Use Arras for the template system or something else?</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://jacwright.com/blog/44/oocommerce-a-deeper-look-more-decisions/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>ooCommerce &#8211; The Overall Picture</title>
		<link>http://jacwright.com/blog/43/oocommerce-the-overall-picture/</link>
		<comments>http://jacwright.com/blog/43/oocommerce-the-overall-picture/#comments</comments>
		<pubDate>Tue, 04 Oct 2005 22:13:59 +0000</pubDate>
		<dc:creator>Jacob Wright</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Object Oriented Programming]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.jacwright.com/blog/?p=43</guid>
		<description><![CDATA[So, we're going to build an ecommerce solution, an open source one.  What pieces are involved? What are the major components of the system?  Let's get this organized using a <a href="http://www.jacwright.com/blog/19/thinking-object-oriented/#top_down" title="Top Down Approach">top down approach</a>.]]></description>
			<content:encoded><![CDATA[<p>So, we're going to build ooCommerce, an ecommerce solution, an open source one.  What pieces are involved? What are the major components of the system?  Let's get this organized using a <a href="http://www.jacwright.com/blog/19/thinking-object-oriented/#top_down" title="Top Down Approach">top down approach</a>.</p>
<p>Every ecommerce system has a few major parts in common.  One is the catalog.  This is where we can browse and search for the products.  Then, we have the shopping cart.  This is where we put the products when we want to buy them.  We have our checkout, which is the process where we can purchase what is in our shopping cart.  And lastly, many systems including ours will have a customer account section, where we can view our past orders and get support.  Actually, we are fogetting a major part of the system.  The administrative section.  This can sometimes be the largest section and will help us organize the catalog, oversee orders, configure the system, and all the other administrative tasks associated with running an ecommerce store.  Here are the "main sections."</p>
<p><img src="/blog/images/basic_sections.gif" alt="Main Ecommerce Sections" /></p>
<p>We will be storing many of the store's information in a database.  So we will need a database package (when I say package, it might be one class or a group of classes, we can figure out which later).  We also want to keep the HTML and style of the site seperate from the code as much as possible so that it can change.  This is a very important piece that osCommerce has not done well in.  It can be very difficult to reskin osCommerce.  So we will have a template package.  We want to model an actual store in our code for a simpler and easier to code/understand system.  This part will be the model and will be the one to interact with the database.  Finally, we need something that takes the pages or actions of our store user, puts together the model information and the templates, and gives it back to our user.  This will be our controller.  So, we have a model, view, controller system we will be making.  It will give us greater flexability.  Here are the "MVC sections."</p>
<p><img src="/blog/images/mvc_sections.gif" alt="Model View Controller Sections" /></p>
<p>The MVC (model, view, controller) sections aren't different from the main sections described above.  Rather, they are another way of looking at our system.  We will have a customer class (from the model) used in the admin section, the shopping cart section, the order section, and the customer account section.  The main sections above indicate the sections of the website, and the MVC sections indicate the different layers of code we will use in the website.</p>
<p>Right now we haven't gotten to our classes yet.  We've just been breaking the system up into smaller pieces.  These may be organized into folders of classes or they may just be for our own reference.</p>
<p>We have successfully broken down the system one level.  We will look at breaking down the system into small parts next time.  We are on our way to a successful ecommerce solution.</p>
]]></content:encoded>
			<wfw:commentRss>http://jacwright.com/blog/43/oocommerce-the-overall-picture/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Tutorial? How About a Project!</title>
		<link>http://jacwright.com/blog/42/ecommerce-project/</link>
		<comments>http://jacwright.com/blog/42/ecommerce-project/#comments</comments>
		<pubDate>Fri, 30 Sep 2005 13:26:06 +0000</pubDate>
		<dc:creator>Jacob Wright</dc:creator>
				<category><![CDATA[Applications]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Object Oriented Programming]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.jacwright.com/blog/?p=42</guid>
		<description><![CDATA[In writing the articles on object oriented programming I have stuck with theory.  After all, it is not language specific and takes less space to say what there is to say.  However, I have been asked by serveral to provide a tutorial or include examples on object oriented code.  Well, I've decided to do almost that.]]></description>
			<content:encoded><![CDATA[<p>In writing the articles on object oriented programming I have stuck with theory.  After all, it is not language specific and takes less space to say what there is to say.  However, I have been asked by serveral to provide a tutorial or include examples on object oriented code.  Well, I've decided to do something more.  My good friend Andrew Branch has pointed out many times before that we learn better when we do things ourselves.  And so, in that spirit, we will start a new full-fledged project together.  I will write along as we develope it about how we should try to do things, so we can more fully understand object oriented principles.  And we can all write the code for it.</p>
<h3>The Project</h3>
<p>Going back to my roots, I learned to program by hacking on <a href="http://www.oscommerce.com/" title="osCommerce, Open Source Online Shop E-Commerce Solutions">osCommerce</a> code.  I wanted to make my own ecommerce site and run my own buisness.  It was then that I discovered how enjoyable programming was and stuck with that instead.  The problem with osCommerce is, however, that it is very procedural.  It has SQL queries inline with the HTML on it's pages.  It uses functions to output pixel images.  It requires a lot of hacking to modify.  It is an adequate example of what you might call "spaghetti code."</p>
<h3>ooCommerce</h3>
<p>We will be starting a new open source project that will implement all the features of osCommerce, but in a better way.  And hopefully, since this will be more extensable, we can add many new features.  We can call this project ooCommerce for object oriented ecommerce.  I have already purchased the domains oocomerce.com, .net, and .org so that we may, eventually, have our own site for it.  And I have submitted it to Sourceforge for pending approval.  The benchmark of features we will be aiming for is listed on <a href="http://www.oscommerce.com/solutions">osCommerce's site</a>.  And, because we are going full out object oriented, we will be using PHP 5.  I am sorry if you were hoping for PHP 4, but in order to teach better OOP principles, and because PHP 4 is such a hack in terms of OOP, that's what we need to use.</p>
<p>I hope ooCommerce will be, if nothing else, a great learning experience.  Instead of a little pointless tutorial on saying "hello world" in an object oriented manner, we will actually create a full-featured system as our tutorial, implementing all that we've learned previously.  We will look at planning this project out next week, so stay tuned.</p>
]]></content:encoded>
			<wfw:commentRss>http://jacwright.com/blog/42/ecommerce-project/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>PHP Package Management and Autoloading</title>
		<link>http://jacwright.com/blog/40/php-package-management-and-autoloading/</link>
		<comments>http://jacwright.com/blog/40/php-package-management-and-autoloading/#comments</comments>
		<pubDate>Mon, 19 Sep 2005 20:32:00 +0000</pubDate>
		<dc:creator>Jacob Wright</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Object Oriented Programming]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.jacwright.com/blog/?p=40</guid>
		<description><![CDATA[In PHP 5 and greater there is a magic function called <code>__autoload</code> (note: two underscores).  <code>__autoload</code> allows us to load a class on the fly so to speak.  It only gets called when a class can not be found, then it has a chance to load the class.  If the class still can not be found, you get your regular error stating so.  <code>__autoload</code> can be really useful if all of your classes happen to be in one directory, but what happens if you are managing a large project with many packages of classes?  We will look at some different options.]]></description>
			<content:encoded><![CDATA[<p>In PHP 5 and greater there is a magic function called <code>__autoload</code> (note: two underscores).  <code>__autoload</code> allows us to load a class on the fly so to speak.  It only gets called when a class can not be found, then it has a chance to load the class.  If the class still can not be found, you get your regular error stating so.  <code>__autoload</code> can be really useful if all of your classes happen to be in one directory, but what happens if you are managing a large project with many packages of classes?  We will look at some different options.</p>
<h3>Single Directory of Classes</h3>
<p>This is the simplest solution, and the best if you have a small project.  You may have situations where you would like to load the class without creating a new instance of it, so I will be creating a <code>loadClass</code> function in each example which <code>__autoload</code> will call.  That way you may load a class manually.  Here is what you might do if all of your classes are in one directory:</p>
<div class="code">
<div class="syntax_hilite">
<div id="php-7">
<div class="php"><span style="color:#000000; font-weight:bold;">function</span> __autoload<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$className</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; loadClass<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$className</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
<span style="color:#006600; font-weight:bold;">&#125;</span></p>
<p><span style="color:#000000; font-weight:bold;">function</span> loadClass<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$className</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; <span style="color:#616100;">include_once</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'classes/'</span> . <span style="color:#0000FF;">$className</span> . <span style="color:#FF0000;">'.php'</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
<span style="color:#006600; font-weight:bold;">&#125;</span></div>
</div>
</div>
<p>
</div>
<p>Pretty Simple.</p>
<h3>Packages of Classes</h3>
<p>Now how about package management, with many directories of classes?  A few developers have named their classes with the package names in the class name.  For example, <code>util_Parser</code> would be the Parser class in the util directory (in your base classes directory), and <code>util_html_HTMLParser</code> would be the HTML parser class in the <code>util.html</code> package.  Here is an example of how that would work:</p>
<div class="code">
<div class="syntax_hilite">
<div id="php-8">
<div class="php"><span style="color:#000000; font-weight:bold;">function</span> __autoload<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$className</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; loadClass<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$className</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
<span style="color:#006600; font-weight:bold;">&#125;</span></p>
<p><span style="color:#000000; font-weight:bold;">function</span> loadClass<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$className</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; <span style="color:#616100;">include_once</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'classes/'</span> . <a href="http://www.php.net/str_replace"><span style="color:#000066;">str_replace</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'_'</span>, <span style="color:#FF0000;">'/'</span>, <span style="color:#0000FF;">$className</span><span style="color:#006600; font-weight:bold;">&#41;</span> . <span style="color:#FF0000;">'.php'</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
<span style="color:#006600; font-weight:bold;">&#125;</span></div>
</div>
</div>
<p>
</div>
<p>Simple like the first method, but we get packages now.  However, we have to actually name our classes with the package names in front of it.  We start to get very long names for some of our classes.  If we extended the Parser class we might have <code>util_html_HTMLParser</code> and <code>util_xml_XMLParser</code> or perhaps even deeper packages.  We also find refactoring difficult because if a class must move to another package, we must go through all our code and rename the class everywhere we use it.</p>
<h3>Package Management Using <code>import</code></h3>
<p>There is another way, although not as simple, which allows packages as deep as you would like, and requires minimal work when refactoring.  This is the <code>import</code> way of doing things.  <code>import</code> is a function which keeps track of what classes you <em>might</em> use in a certain script/class and then uses <code>__autoload</code> to look up the location of the class.  Here's how it works.</p>
<ul>
<li>You import the class or package using the <code>import</code> function like this, <code>import('util.html.HTMLParser');</code>, at the top of your script</li>
<li><code>import</code> stores the name of the class, 'HTMLParser', and the path to the class, 'util/html/HTMLParser.php', in a global associative array called <code>imports</code></li>
<li>When the class is utilized, <code>__autoload</code> will do a lookup in the <code>imports</code> array for the class and load it in.</li>
</ul>
<p>Here is how the code looks.  It is a bit more complicated, but very nice to use for a larger system:</p>
<div class="code">
<div class="syntax_hilite">
<div id="php-9">
<div class="php"><span style="color:#000000; font-weight:bold;">function</span> __autoload<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$className</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; loadClass<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$className</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
<span style="color:#006600; font-weight:bold;">&#125;</span></p>
<p><span style="color:#000000; font-weight:bold;">function</span> loadClass<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$className</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; <a href="http://www.php.net/global"><span style="color:#000066;">global</span></a> <span style="color:#0000FF;">$imports</span>;<br />
&nbsp; &nbsp; <span style="color:#616100;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span><a href="http://www.php.net/isset"><span style="color:#000066;">isset</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$imports</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#0000FF;">$className</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#616100;">include_once</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$imports</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#0000FF;">$className</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><br />
<span style="color:#006600; font-weight:bold;">&#125;</span></p>
<p><span style="color:#0000FF;">$imports</span> = <a href="http://www.php.net/array"><span style="color:#000066;">array</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
<span style="color:#000000; font-weight:bold;">function</span> import<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$import</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; <a href="http://www.php.net/global"><span style="color:#000066;">global</span></a> <span style="color:#0000FF;">$imports</span>;<br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color:#FF9933; font-style:italic;">// seperate import into a package and a class</span><br />
&nbsp; &nbsp; <span style="color:#0000FF;">$lastDot</span> = <a href="http://www.php.net/strrpos"><span style="color:#000066;">strrpos</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$import</span>, <span style="color:#FF0000;">'.'</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color:#0000FF;">$class</span> = <span style="color:#0000FF;">$lastDot</span> ? <a href="http://www.php.net/substr"><span style="color:#000066;">substr</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$import</span>, <span style="color:#0000FF;">$lastDot</span> + <span style="color:#CC66CC;">1</span><span style="color:#006600; font-weight:bold;">&#41;</span> : <span style="color:#0000FF;">$import</span>;<br />
&nbsp; &nbsp; <span style="color:#0000FF;">$package</span> = <a href="http://www.php.net/substr"><span style="color:#000066;">substr</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$import</span>, <span style="color:#CC66CC;">0</span>, <span style="color:#0000FF;">$lastDot</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color:#FF9933; font-style:italic;">// if this import has already happened, return true</span><br />
&nbsp; &nbsp; <span style="color:#616100;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span><a href="http://www.php.net/isset"><span style="color:#000066;">isset</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$imports</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#0000FF;">$class</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span> || <a href="http://www.php.net/isset"><span style="color:#000066;">isset</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$imports</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#0000FF;">$package</span>.<span style="color:#FF0000;">'.*'</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#616100;">return</span> <span style="color:#000000; font-weight:bold;">true</span>;<br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color:#FF9933; font-style:italic;">// create a folder path out of the package name</span><br />
&nbsp; &nbsp; <span style="color:#0000FF;">$folder</span> = <span style="color:#FF0000;">''</span> . <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$package</span> ? <a href="http://www.php.net/str_replace"><span style="color:#000066;">str_replace</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'.'</span>, <span style="color:#FF0000;">'/'</span>, <span style="color:#0000FF;">$package</span><span style="color:#006600; font-weight:bold;">&#41;</span> : <span style="color:#FF0000;">''</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color:#0000FF;">$file</span> = <span style="color:#FF0000;">"$folder/$class.php"</span>;<br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color:#FF9933; font-style:italic;">// make sure the folder exists</span><br />
&nbsp; &nbsp; <span style="color:#616100;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span>!<a href="http://www.php.net/file_exists"><span style="color:#000066;">file_exists</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$folder</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$back</span> = <a href="http://www.php.net/debug_backtrace"><span style="color:#000066;">debug_backtrace</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#616100;">return</span> <a href="http://www.php.net/trigger_error"><span style="color:#000066;">trigger_error</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">"There is no such package &lt;strong&gt;'$package'&lt;/strong&gt; -- Checked folder &lt;strong&gt;'$folder'&lt;/strong&gt;&lt;br /&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Imported from &lt;strong&gt;'{$back[0]['file']}'&lt;/strong&gt; on line &lt;strong&gt;'{$back[0]['line']}'&lt;/strong&gt;&lt;br /&gt;"</span>, <span style="color:#000000; font-weight:bold;">E_USER_WARNING</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#616100;">elseif</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$class</span> != <span style="color:#FF0000;">'*'</span> &amp;&amp; !<a href="http://www.php.net/file_exists"><span style="color:#000066;">file_exists</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$file</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$back</span> = <a href="http://www.php.net/debug_backtrace"><span style="color:#000066;">debug_backtrace</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#616100;">return</span> <a href="http://www.php.net/trigger_error"><span style="color:#000066;">trigger_error</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">"There is no such Class &lt;strong&gt;'$import'&lt;/strong&gt; -- Checked for file &lt;strong&gt;'$file'&lt;/strong&gt;&lt;br /&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Imported from &lt;strong&gt;'{$back[0]['file']}'&lt;/strong&gt; on line &lt;strong&gt;'{$back[0]['line']}'&lt;/strong&gt;&lt;br /&gt;"</span>, <span style="color:#000000; font-weight:bold;">E_USER_WARNING</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color:#616100;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$class</span> != <span style="color:#FF0000;">'*'</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#FF9933; font-style:italic;">// add the class and it's file location to the imports array</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$imports</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#0000FF;">$class</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#0000FF;">$file</span>;<br />
&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#616100;">else</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#FF9933; font-style:italic;">// add all the classes from this package and their file location to the imports array</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#FF9933; font-style:italic;">// first log the fact that this whole package was alread imported</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$imports</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#FF0000;">"$package.*"</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#CC66CC;">1</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$dir</span> = <a href="http://www.php.net/opendir"><span style="color:#000066;">opendir</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$folder</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#616100;">while</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$file</span> = <a href="http://www.php.net/readdir"><span style="color:#000066;">readdir</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$dir</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span> !== <span style="color:#000000; font-weight:bold;">false</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#616100;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span><a href="http://www.php.net/strrpos"><span style="color:#000066;">strrpos</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$file</span>, <span style="color:#FF0000;">'.php'</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$class</span> = <a href="http://www.php.net/str_replace"><span style="color:#000066;">str_replace</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'.php'</span>, <span style="color:#FF0000;">''</span>, <span style="color:#0000FF;">$file</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#FF9933; font-style:italic;">// put it in the import array!</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$imports</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#0000FF;">$class</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#FF0000;">"$folder/$file"</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><br />
&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><br />
<span style="color:#006600; font-weight:bold;">&#125;</span></div>
</div>
</div>
<p>
</div>
<p>There you have it.  A powerful way to manage your packages and load only classes which are needed for use.  Also, a feature of this method of autoloading classes is that you can use an asterisk, *, to import all the classes in a package.  And it only loads the classes needed because of <code>__autoload</code>.</p>
<p>Finally, this is how you would use the <code>import</code> method in your scripts:</p>
<div class="code">
<div class="syntax_hilite">
<div id="php-10">
<div class="php">import<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'util.html.HTMLParser'</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
import<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'template.arras.*'</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</p>
<p><span style="color:#FF9933; font-style:italic;">// here would be all of your important code</span><br />
<span style="color:#FF9933; font-style:italic;">// not worrying about including files hwen you need them</span><br />
<span style="color:#FF9933; font-style:italic;">// because you've already set it up to include them</span><br />
<span style="color:#FF9933; font-style:italic;">// automatically when you use them, and only</span><br />
<span style="color:#FF9933; font-style:italic;">// _if_ you use them</span><br />
<span style="color:#0000FF;">$p</span> = <span style="color:#000000; font-weight:bold;">new</span> HTMLParser<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
<span style="color:#0000FF;">$t</span> = <span style="color:#000000; font-weight:bold;">new</span> ArrasTemplate<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
<span style="color:#FF9933; font-style:italic;">// etc. </span></div>
</div>
</div>
<p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://jacwright.com/blog/40/php-package-management-and-autoloading/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>Mint, Stat&#8217;s and Design</title>
		<link>http://jacwright.com/blog/39/mint-stats-and-design/</link>
		<comments>http://jacwright.com/blog/39/mint-stats-and-design/#comments</comments>
		<pubDate>Wed, 14 Sep 2005 20:01:22 +0000</pubDate>
		<dc:creator>Jacob Wright</dc:creator>
				<category><![CDATA[Applications]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.jacwright.com/blog/39/mint-stats-and-design/</guid>
		<description><![CDATA[<a href="http://www.haveamint.com/">Mint</a> is a new product recently released to track the statistics on your website.  It has gotten much attention from several areas, and I thought it would be worth it to check it out.]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.haveamint.com/">Mint</a> is a new product recently released to track the statistics on your website.  It has gotten much attention from several areas, and I thought it would be worth it to check it out.</p>
<p>I am currently using <a href="http://www.statcounter.com/">StatCounter.com</a> to track the traffic to my site.  It is really useful when you use their paid service which keeps track of more than the last 100 visits to your site (the free version cap).  It lets you view all the regular stats as well as "drill down" to see the actual path a single visitor took through your site.  But, it is a monthly subscription service, which means potenially hundreds of dollars a year, even though it's not much each month.</p>
<p>Mint is a one-time site liscence fee of $30.  So I felt it would be a good investment over the monthly fees of StatCounter.  What sums up my thoughts upon using Mint is this: a regular stat tracker was given a <em>great</em> design and some cool javascript effects to make things easier to use.  It looks wonderful, but it lacks much.  Things such as tracking return visitors, displaying charts and graphs of the data, and being able to drill down to see individual users and their paths are things that really make a web stat tracker useful.  A good user interface is important as well.</p>
<p>One bonus to Mint is it can be extendable with plugins or "pepper" as it's called for marketing.  Although, I'm not sure if extras will be sold by other developers, release for free even though the original is a paid product, or both.  I should make it easier for the maker of mint to deploy new features anyway.</p>
<p>Overall, I enjoy Mint, and it's price is much more favorable than the recurring price of StatCounter.  I will stick with it and create some nice graphs of the data for my personal use (whenever I get spare time).  Perhaps sell it as a plugin or something.</p>
]]></content:encoded>
			<wfw:commentRss>http://jacwright.com/blog/39/mint-stats-and-design/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Logout from HTTP Authorization</title>
		<link>http://jacwright.com/blog/37/logout-from-http-authorization/</link>
		<comments>http://jacwright.com/blog/37/logout-from-http-authorization/#comments</comments>
		<pubDate>Fri, 09 Sep 2005 17:28:49 +0000</pubDate>
		<dc:creator>Jacob Wright</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.jacwright.com/blog/37/logout-from-http-authorization/</guid>
		<description><![CDATA[A little trick to create a logout from your site if you are using HTTP Authentication.]]></description>
			<content:encoded><![CDATA[<p>This is a little trick to create a logout from your site if you are using HTTP Authentication.  I am using it for a current project I'm working on where cookie based sessions won't reliably work.  We (Derek Andriesian and I) are using HTTP Authenticaton to log into an account which is only accessed through javascript and image urls from other sites.  Some browsers disallow cookies being set by sites other than the current one, so keepig the user logged in is not always possible using cookie-base session management.</p>
<p>To use HTTP Authentication you just do this in your PHP:</p>
<div class="code">
<div class="syntax_hilite">
<div id="php-11">
<div class="php"><span style="color:#FF9933; font-style:italic;">// retrieve the vars passed through HTTP Auth</span><br />
<span style="color:#0000FF;">$user</span> = <span style="color:#0000FF;">$_SERVER</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#FF0000;">'PHP_AUTH_USER'</span><span style="color:#006600; font-weight:bold;">&#93;</span>;<br />
<span style="color:#0000FF;">$pass</span> = <span style="color:#0000FF;">$_SERVER</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#FF0000;">'PHP_AUTH_PW'</span><span style="color:#006600; font-weight:bold;">&#93;</span>;</p>
<p><span style="color:#000000; font-weight:bold;">function</span> login<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$user</span>, <span style="color:#0000FF;">$pass</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; <span style="color:#FF9933; font-style:italic;">// check if this is a valid login and process necessary stuff</span><br />
<span style="color:#006600; font-weight:bold;">&#125;</span></p>
<p><span style="color:#616100;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span>!<span style="color:#0000FF;">$user</span> || !<span style="color:#0000FF;">$pass</span> || !login<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$user</span>, <span style="color:#0000FF;">$pass</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; <span style="color:#FF9933; font-style:italic;">// send the headers which will popup the login dialog</span><br />
&nbsp; &nbsp; <a href="http://www.php.net/header"><span style="color:#000066;">header</span></a><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#FF0000;">'WWW-Authenticate: Basic realm=&quot;Private&quot;'</span> <span style="color:#006600; font-weight:bold;">&#41;</span>; <br />
&nbsp; &nbsp; <a href="http://www.php.net/header"><span style="color:#000066;">header</span></a><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#FF0000;">'HTTP/1.0 401 Unauthorized'</span> <span style="color:#006600; font-weight:bold;">&#41;</span>; <br />
&nbsp; &nbsp; <a href="http://www.php.net/exit"><span style="color:#000066;">exit</span></a>;<br />
<span style="color:#006600; font-weight:bold;">&#125;</span><br />
<span style="color:#FF9933; font-style:italic;">// logged in successfully </span></div>
</div>
</div>
<p>
</div>
<p>This works pretty good, however, there is no built in way to log a user out short of making them close their browser.  But, you can "log them in" with a different username and password encoded into the link like so: http://username:password@www.domain.com/page.php.  So, it's possible to create a logout page by sending them to a link http://x:x@www.domain.com/logout.php.  Then you may redirect them somewhere else, and as long as you don't have a user with a username and password of 'x' and 'x' then they will be logged out of any valid account.</p>
]]></content:encoded>
			<wfw:commentRss>http://jacwright.com/blog/37/logout-from-http-authorization/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>AMFPHP 1.0 Ready</title>
		<link>http://jacwright.com/blog/33/amfphp-10-almost-ready/</link>
		<comments>http://jacwright.com/blog/33/amfphp-10-almost-ready/#comments</comments>
		<pubDate>Fri, 12 Aug 2005 23:12:11 +0000</pubDate>
		<dc:creator>Jacob Wright</dc:creator>
				<category><![CDATA[Flash]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.jacwright.com/blog/33/amfphp-10-almost-ready/</guid>
		<description><![CDATA[<a href="http://www.amfphp.org">AMFPHP</a> (Flash Remoting written in PHP) is almost ready to hit a stable version 1.0 release!  I've been looking forward to this for a long time.  We've already used it at 4.4 million posts to a remoting service in one month.]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.amfphp.org">AMFPHP</a> (Flash Remoting written in PHP) has hit a stable version 1.0 release!  I've been looking forward to this for a long time.</p>
<p>Flash Remoting is a method of transfering data to a Macromedia Flash Movie.  It sends it in binary format and is much easier to use as it arrives in an object form, meaning, you don't have to sort through the child nodes of an XML object.  I have been using AMFPHP for over a year on several projects (being one of the main backend developers in my company, <a href="http://www.mediarain.com">mediaRAIN</a>) to send stuff.  I created the logo storage of <a href="http://www.logomaker.com">LogoMaker</a>/<a href="http://www.instalogo.com">InstaLogo</a> using AMFPHP which handles, and I quote, "a lot."  Actaully, in July we got 4.4 million posts to the remoting service.  I suppose that's on average almost 100 a minute!  We've also used remoting in several other applications.</p>
<p>I've been pretty pleased just with the ability to pass data back an forth from Flash to PHP.  The only things that bothered me was the beastly methodTable array the PHP service needed and the design issue in which your Flash objects are converted into associative arrays in PHP rather than PHP objects.  The methodTable is now created using reflecting and JavaDoc style documenting (very nice) and as for the array vs object issue, well, I made a hack for that myself in our version of the remoting.  Associative arrays are "more natural" in PHP, and you can use the methodTable to define custom object types.  Well, not recursively, however, you can now be able to associate a PHP class with a Flash class in version 1.0.  Really nice feature.  Kudos to all of those who have helped develop PHP remoting for Flash.  You can see all of the <a href="http://www.amfphp.org/wiki/doku.php?id=what_s_new">new features</a> in 1.0 yourself, but it's faster, more organized, more features, and the whole bit.</p>
<p>Pherret currently can be integrated with Flash Remoting and will have full support as an extra module.  mediaRAIN is all about Flash, so of course I had to take that into consideration as I built Pherret.  But you have a truer Model View Controller (MVC) system when you can use different views (HTML or Flash) or controllers and the same model.</p>
]]></content:encoded>
			<wfw:commentRss>http://jacwright.com/blog/33/amfphp-10-almost-ready/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
