Lessons
Parsing XML in PHP5 with SimpleXML
May 16th
PHP5 includes a library for parsing XML data called SimpleXML. This class (and associated classes) is a fantastic way to parse XML data in PHP5. Parsing of XML comes into almost every project i work on, whether it be creating/manipulating RSS feeds, sending data between Flex and PHP, and whatever else the client wants really
Below is the XML data i will be working with in this tutorial:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <languages> <language year="1999"> <name>ActionScript 3.0</name> <description>ActionScript is a scripting language based on ECMAScript. ActionScript is used primarily for the development of websites and software using the Adobe Flash Player platform (in the form of SWF files embedded into Web pages).</description> </language> <language year="1995"> <name>PHP</name> <description>PHP is a scripting language originally designed for producing dynamic web pages. It has evolved to include a command line interface capability and can be used in standalone graphical applications.</description> </language> <language year="1995"> <name>Java</name> <description>Java is a programming language originally developed by James Gosling at Sun Microsystems and released in 1995 as a core component of Sun Microsystems' Java platform. The language derives much of its syntax from C and C++ but has a simpler object model and fewer low-level facilities. Java applications are typically compiled to bytecode that can run on any Java virtual machine (JVM) regardless of computer architecture.</description> </language> <language year="2007"> <name>LOLCODE</name> <description>LOLCODE is an esoteric programming language inspired by the language expressed in examples of the lolcat Internet meme. The language was created in 2007 by Adam Lindsay, researcher at the Computing Department of Lancaster University.</description> </language> </languages> |
Now, say we wanted to parse this XML file using PHP, and extract the name of each of these languages…
1 2 3 4 5 6 | <?php $languages = simplexml_load_file("languages.xml"); foreach($languages as $language) echo $language->name."<br/>"; ?> |
In the above code, one can extrapolate that SimpleXML will go through your XML file and assign the nodes to an array, and in that array it will create an untyped Object with the data assigned to properties of that Object.
Simple enough, right?
Now, what if you wanted to access an attribute of each of these languages (in this scenario – the year attribute of each language)?
That’s also really easy with SimpleXML! You can reference the attributes of each node by using array notation…
1 2 3 4 5 6 | <?php $languages = simplexml_load_file("languages.xml"); foreach($languages as $language) echo $language["year"]."<br/>"; ?> |
Ok. So what if you wanted your returned data to be mapped to a class? I.e. each element in the array that is returned must be strongly typed to a class, rather than the unspecific stdClass Object that’s returned by default… This can also be done with SimpleXML!
Here’s the Language.php class i created for the returned array elements to be typed as (note that it ,must extend the SimpleXMLElement class):
1 2 3 4 5 6 7 8 | <?php class Language extends SimpleXMLElement { public $year; public $name; public $description; } ?> |
…and the code to return each array element as a Language Object:
1 2 3 4 5 6 7 8 9 | <?php require_once("Language.php"); $languages = simplexml_load_file("languages.xml", "Language"); foreach($languages as $language) { print_r($language); } ?> |
If you look at the output, you will see that the year attribute is not assigned to $year property of the Language class, but rather to a @attributes property. However, if you add this function to the Language.php class, the attributes will be assimilated to their respective properties:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <?php class Language extends SimpleXMLElement { public $year; public $name; public $description; public function attrToProp() { foreach($this->attributes() as $prop => $val) $this->$prop = (string) $val; } } ?> |
…and run the script again, but adding this line of code:
1 2 3 4 5 6 7 8 9 10 | <?php require_once("Language.php"); $languages = simplexml_load_file("languages.xml", "Language"); foreach($languages as $language) { $language->attrToProp(); // -- add this line print_r($language); } ?> |
Protecting your SWFs from prying eyes
Mar 20th
Ok. So you’ve made a Flex application… Now what? You’ve got to deploy your SWF on a server somewhere, and give access to the world. The only problem with that is……..
THE WORLD HAS ACCESS TO YOUR SWF
A SWF is a compiled file and can thus be decompiled using applications like Sothink SWF Decompiler. Applications like these can take your SWF file as decode the binary data, hence allowing you to see most of the source code contained therein. Flex apps are slightly more difficult to hack – as there is just so much more code than a plain old file made in Flash – but nonetheless, it can be done.
There a few ways to protect your SWF file and the data contained therein, but none of them are really hack-proof (and i’m sure my idea isn’t hack-proof either, but i see no easy way around it).
One highly obvious security tip is to keep all sensitive data out of your SWF. Rather store keys, codes and digests in your server-side scripts.
However, that only protects the data in your SWF, not the intellectual property (ActionScript logic, embedded images, etc). I had a brainfart last night about how to do this, and i figured it out this morning: let’s think about it… How do people access files on your server? They can access them if your files are in your webroot (public_html folder or /var/www). However, all files outside the webroot are not visible on the web.
So i got to thinking… How can i load a SWF at runtime from outside the webroot while fooling both the browser and the application into thinking that it is sitting in the webroot? Well, i managed this with PHP and got a few nice surprises. See the files below (i used this SWF in my last post and i was too lazy to make a new one):
|
The SWF on the left loads another SWF securely, while the one on the right loads a SWF as one normally would – via a relative or absolute link.
To actually see whether or not the SWF is being seen by the browser (i.e. via a GET request), try using the Net Monitor of Firebug. The SWF on the right – once clicked will force the browser into making a GET request while the one on the left will not. How’s this accomplished?
Well, it’s all about the PHP. See the script below:
1 2 3 | <?php echo base64_encode(file_get_contents("/home/riacoder/etc/SWF/menu.swf")); ?> |
If you navigate to http://ria-coder.com/blog/wp-content/uploads/2009/03/loader.php, you will see a bunch of nonsense being printed to the page. This is actually the base64 data of the menu.swf file, located outside my webroot, but there’s a copy of it here. As you can see in my PHP code, i have done is pointed PHP to the the menu.swf file located somewhere on my server (outside the accessible range) and i’m getting the file contents of the SWF (compiled binary data) and encoding it in base64 format.
In the ActionScript below, i am decoding the base64 data back into binary data and then returning those bytes.
1 2 3 4 5 6 | private function loadSWF(base64String:String):ByteArray { var decoder:Base64Decoder = new Base64Decoder(); decoder.decode(base64String); return decoder.toByteArray(); } |
You can download the files used in this tutorial here.
*** UPDATE: Serge Jespers (www.webkitchen.be) has informed me that this method is not infallable, as anybody could decompile the container SWF (the SWF from which you’re calling the PHP), find the link to your PHP script, decode the base64 data, and then write the bytes to a file – thus obtaining your SWF. Even though this method is not hack-proof, it’s still an extra deterrent and i’d recommend your using it nonetheless if you feel it’s worth the extra effort.
Succinct Singletons
Feb 11th
A singleton can be a very useful and essential Object-Oriented device in many instances (no pun intended). Singleton classes only allow one instance of that particular class, and this can be very useful in situations where you want one object to be used throughout your Flash/Flex application instead of many separate ones. I usually use singleton classes for classes that merely act as utility proxies to my applications.
Below is the code to create a very succinct singleton
package { public class Singleton { private static var _instance:Singleton; public static function getInstance():Singleton { if(!_instance) _instance = new Singleton(); return _instance; } } }
In the upcoming API i’m planning on releasing, i’ll be using Singletons extensively, and the API will – of course – be open source.
Working with the Security and SecurityPanel classes
Feb 5th
In a recent project, i was asked to build a system that would support storing cookies on a user’s local machine. This is obviously solved with SharedObjects if you’re working with the Flash Player. However, i ran into a few issues with this and found out a few interesting things.
Firstly, i wanted to detect if the user allows Flash/Flex to write to their computer. This can be solved as follows:
You can use the flush function of the SharedObject class… mySharedObject.flush(1) where 1 is the number in bytes that you require for your SharedObject. If the function returns a value of SharedObjectFlushStatus.PENDING, there is not sufficient space to store your SharedObject and a dialog appears that prompts the user to rectify this. If the function returns false, however, the user has not permitted using SharedObjects.
To call up a user’s Flash settings dialog (Camera, Display, Storage, Microphone, Privacy, Settings Manager), you would use the Security class from the flash.system package.
Linux Mint & Flex
Jan 24th
I recently moved over to Linux Mint. Their catch-phrase is “from freedom came elegance” and it rings so true.
Linux Mint is one of the surprise packages of the past year. Originally launched as a variant of Ubuntu with integrated media codecs, it has now developed into one of the most user-friendly distributions on the market – complete with a custom desktop and menus, several unique configuration tools, a web-based package installation interface, and a number of different editions. Perhaps most importantly, this is one project where the developers and users are in constant interaction, resulting in dramatic, user-driven improvements with every new release.
The truth be told – i’m a bit of a n00b when it comes to Linux, but wow… What an OS. You can download the OS here, then simply write it to disk and restart your PC and boot from the installer disk. Mint can be run from the disk, which is quite a cool feature (available on a few other Linux distros i’m told – such as Ubuntu)
My main line of work – and my passion – is developing Flex applications, and as a consequence, i need to be able to develop Flex apps from Linux. The incredible folks over at Adobe have released the fourth public alpha release of Flex Builder for Linux. Being an alpha version, it does not have all the features we’re accustomed to in the Windows or Mac incarnations, and you’ll need to install Eclipse Europa 3.3.2 for it to work (Flex Builder only comes as a plugin at this point). The main missing features are:
- Design view
- States view
- Refactoring
- Data Wizards
- Cold Fusion – Data Services Wizard
- Web Services introspection
- Profiler
However, the features that are present are more than enough to develop Flex/AIR applications, and if you can’t build Flex apps without design view, you suck
.
Please note: The Flex Builder plugin will NOT work with Eclipse Ganymede (3.4.x). The plugin will install just fine, but the MXML editor will not work. There has been much discussion about it on the bugs.adobe.com site, but no solution has been found as of yet.
The installation of Flex Builder for Linux is quite simple. Follow these instructions:
- Download Eclipse Europa 3.3.2 to your desktop. Open the terminal and extract the archive to wherever you like.
- Download the Flex Builder for Linux plugin to your desktop. Open the terminal, direct the terminal to your desktop and enter the following:
sudo sh flexbuilder_linux_install_a4_081408.bin
- Follow the installer’s instructions and install the plugin. Please be sure that the directory you’re installing the plugin to is the correct Eclipse directory.
- The plugin will now be installed to your Eclipse install. Go to your eclipse folder and run the main application. Click on the Window menu and select Open Perspective. Click Other and search for Flex. From here you can open your Flex Development perspective and start developing Flex applications
!
Great! So now you have installed the Flex Builder for Linux plugin. Unlike the Windows/Mac versions, you will have 311 days or something like that to test the application. If you are a student, you can apply for a free Flex license here. I’ve used my student license on both my Windows and Linux versions and it works fine.
Integrating Flex, AMFPHP and CodeIgniter (also including Value-Objects)
Jan 5th
Setting up email on localhost with PHP + PostCast Server
Dec 12th
I recently had a great ballache with trying to test emails from my local machine. Testing emails is painful enough when it fucking works, nevermind when it doesn’t! I’d been putting off setting my system up for weeks but tonight i finally decided to give it a proper bash… And it worked!
This is how i did it… In 3 easy steps!
Step 1 – Configure your PHP to allow for SMTP connections
Firstly, you need to edit your php.ini file found in the php folder of your local server. I personally use XAMPP because it’s everything i need in a web server. XAMPP now has versions for Windows, Mac and Linux, so nobody has an excuse not to use it now.
In your PHP config file (php.ini), if you do a search for SMTP, you will find the following code:
[mail function]
; For Win32 only.
;SMTP = localhost
;smtp_port = 25
All you need to do is uncomment the last two lines (take out the semi-colons).
Step 2 – Download, install and configure PostCast Mail Server
PostCast Mail Server is a great, simple to use application that will allow you to send email from your local machine. Download and install the application. Once installed, go to Tools->Settings, and set your host name to localhost with a server port of 25. Once you’ve done that, you’re almost ready to go!
Step 3 – Send a mail
Create a file on your server called testmail.php and use the following code:
$headers = “From:me@someaddress.com\r\n”.
“To:me@myaddress.com\r\n”.
“MIME-Version: 1.0\r\n” .
“Content-Type: multipart/mixed;\r\n”;
mail(“me@myaddress”,”PHP mail test”,”www.ria-coder.com/blog”, $headers);
?>
And you’re done!
A few Tree tricks
Dec 2nd
The tree control in Flex is a very complex and somewhat complicated component at first glance, but with further inspection the complexity begins to melt away.
A few ballaches i have had when using Trees are:
- Automatic horizontal and vertical scrolling
- Static use of leaf and node icons
- Dynamic use of leaf and node icons
- Item event handling
Ballache 1 – Automatic horizontal and vertical scrolling
At first i thought that the Tree control’s lack of horizontal and vertical scrollbars – when content grew to beyond the component’s bounds – was a bug. Then i scolded myself for such heresy. The Flex developers would never leave such a common feature out or release a fucked up version of it. So i did a little research and found this post: http://frishy.blogspot.com/2007/09/autoscrolling-for-flex-tree.html.
Ryan offers a great hack that works almost perfectly, besides for the fact that the labelField gets screwed up and sometimes the text is snipped off a little at the end. At the bottom of the page is a solution:
change maxHorizontalScrollPosition = NaN;to maxHorizontalScrollPosition = 0;
change maxHorizontalScrollPosition = diffWidth; to maxHorizontalScrollPosition = diffWidth + 10; …or what ever correction factor you need.The user-submitted fix in combination with Ryan’s sub-classed AuoSizeTree file will allow you to have the horizontal and vertical scrollbars on “auto” mode.
Ballache 2 – Static use of leaf and node icons
This one is a sinch. All you have to do is use the folderOpenIcon and folderClosedIcon properties of your Tree and embed an image that will act as an icon. Same thing goes for leaves: defaultLeafIcon.
Ballache 3 – Dynamic use of leaf and node icons
This one is a bit more tricky. What you have to do here is define a “class” that will refer to an embedded icon:
[Embed(source='myIcon.png')]
private var myIcons:Class;
You can now use this icon as so (considering that you set the icon property of your Tree component to “@icon”):
treeDataProvider.appendChild(XML(“<testLeaf icon=\”" + getQualifiedClassName(“myIcon”) + \”" label=\”hello\”></testLeaf>));
What this will do is add a child to your Tree’s dataProvider and get the class’ qualified class name and use that as the icon in your leaf.
Ballache 4 – Item event handling
Want to handle click events for your Tree nodes/leaves? No problem! Set the itemClick property of your Tree to execute a function (clickHandler in this instance). When you click an item in a Tree control, it will call a function and pass it an event object of type ListEvent.
private function clickHandler(event:ListEvent):void
{
trace(event.currentTarget.selectedItem);
}
In the example above, the function is finding the selected item in your Tree control and tracing it out. If you’re using XML to define your Tree’s model, it will return an XML object which you can then type as XML. It’s really that simple!
Hope i’ve saved you a ballache or four
A tip on using the Image component in Flex
Nov 14th
At some time in the future – if you’re using the <mx:Image> component in Flex – you will need to listen for an event that will signal the load completion of an image’s source. The Event.COMPLETE function doesn’t work, so you’ll have to use the FlexEvent.UPDATE_COMPLETE function. This will do exactly the same thing as using the Loader class, and using the following code: loader.contentLoaderInfo.addEventListener(Event.COMPLETE…).




