Introduction to Flex - for PHP Developers

DZone 's Guide to

Introduction to Flex - for PHP Developers

· Web Dev Zone ·
Free Resource

I’ve been working with web related technologies since the late ‘90s, and my first server side technology was PHP. Later on, I did ColdFusion and Java development, but I always considered myself a PHP developer. When AJAX came along, I started working with frameworks like Prototype and script.aculo.us, and I began building my own frameworks.

At the end of 2006, I had my first taste of Flex development. It was kind of a crash course, because I had about 4-6 weeks to create a demo application for the upcoming version of FDS (Flex Data Services, now called LiveCycle Data Services). Although I was new to Flex and FDS, the project went well, and I really enjoyed the development and learning process.

However, enjoyable as it was, it was different. I mean that when I did ColdFusion or Java web development, it didn’t feel different compared to PHP; it was more a question of finding the right APIs and getting acclimated with the specifics of the language. Later on, when I started doing AJAX on top of DHTML, it wasn’t that different either. You still create most of the website using the same techniques with the help of a server-side language, and you just throw in some spices here and there (in this case, some AJAX widgets).

When I did my first web project using Flex, boy oh boy, it was quite a switch! The clean separation between the client and the server, (the business logic on the client side in addition to business logic on the server side), client-side technology that is compiled instead of interpreted, two languages on the client, all these required a different mind-set from traditional web development.

And this is my reason for writing this article. I want to share with you some of the things that are specific to Flex in relation to PHP. At the same time I want to introduce Flex by comparing it with PHP whenever this comparison makes sense. Thus this article is for:

  • PHP developers that want to learn more about Flex and Action Script 3 than a simple definition can provide
  • PHP developers that have already made their first attempt at coding a Flex application and want a broader, deeper understanding

What is not in this article? It is not my intent to convert you, or to convince you that Flex is better than X or Y. I strongly believe that there are different types of projects and that they can and should be done with different tools. And when performance, maximizing return on investment, and usability are top priorities there is no such thing as a universal tool.

At the same time, this article does not completely document Flex or ActionScript 3. There are dozens of books out there that cover this subject in hundreds of pages. There are thousands of articles on Flex. My intent is to give you enough information on the most important topics, and, whenever it makes sense to relate the concepts to similar concepts from PHP. In order to keep the article useful I structured it and tried not to go into too much details. At the end of this article, I provide a brief introduction to Adobe AIR and some additional resources if you want additional details on this topic.

Finally, I chose to use Flex 3 for most of the examples. There are a couple of reasons for making this choice. First, at the time of writing this article, Flex 4 is still in beta. Second, Flex 4 is mainly an evolution of Flex 3 thus most things I cover here can be applied to Flex 4 with minimum changes, if any. In some cases, I’ll point out these differences. Regarding PHP, I chose to use PHP 5.3 as a reference. Having said that, let’s see the table of contents and then, let’s dig in!

What is Flex?

The simplest answer is: Flex is just another way of creating a Flash application. A Flex application gets compiled into a SWF file, which is played inside of the browser by Flash Player. Why did we need another way of creating Flash applications? Traditionally Flash applications were created using the Flash authoring tool. If you take a look at this tool, you’ll notice that it is oriented primarily for designers. There is a stage, a timeline, drawing tools, and so on.

When you are developing applications and you care about productivity, you want components, you want to be able to streamline development as much as possible by reusing code, and not last but not least, you want a modern IDE.

Thus a revised answer could be: Flex is an open source framework that helps developers to quickly create Rich Internet Applications that run inside Flash Player. The framework was shaped pretty much as it is today in 2006 with the arrival of Flex 2, Flash Player 9, and ActionScript 3. The current version is Flex 3, and early in 2010 the next version, Flex 4, will be out.


Flex: two languages, one framework to bind them

Under the umbrella of Flex, you’ll actually find the following:

  • Two languages: MXML and ActionScript 3. Flex offers two languages to lay down a Flex application. In the next chapters, I will go deep into each language.
  • A rich library of components
  • Compilers and debugger
  • Command-line tools for compiling and debugging a Flex application

Since Flex is an open source framework, I encourage you to go to the project home page at http://opensource.adobe.com/flex and download the SDK. You can see the source code of all the components from the library, you can check the open bugs and features database (http://bugs.adobe.com/flex), and you can see the wiki pages for the specifications.

Part of the productivity boost provided by Flex is due to the extensive components library. There are all the UI components you might think of (input boxes, panels, windows, sliders, data grids, combo boxes, accordions, tab sets, …). There are layout containers and form elements. Below, you can see a screenshot of the available UI components from Flex 3 (click to enlarge).


And if these are not enough, because you are able to access the source code, you can extend these to build your own components or you can create new components from scratch.

Why you should care about Flex

Before going deeper into what Flex is, let’s pause and revisit the reasons why you should care about Flex.

Traditional HTML web applications have a request – response architecture. The browser makes a request and the server sends a page back, and this cycle is repeated. HTML and CSS make an excellent choice for presenting the information, arguably one of the best out there. As years passed, however this architecture stretched beyond just static presentation to an application platform. With scripting technologies, we managed to create dynamic pages and to tailor the server response to a specific request. Furthermore, adding DHTML and AJAX we breathed  new life into the pages served by the web server: the user could interact with the loaded page and alter the view without refreshing the whole page.

As the technologies evolved, more complex applications appeared. Some web applications began to replicate many desktop application functionalities and at the same time retain the convenience of a web application (available anywhere that a browser and an Internet connection are available). Thus online versions of spreadsheets and text editors sprang up.

However, from a usability perspective, online applications were less friendly than the desktop applications. At the same time, to create these complex web application you need a lot of skills in many technologies (JavaScript, DHTML, CSS, AJAX libraries, server-side technologies), and you need to have experience with the differences between the browsers and how they implemented HTML/CSS/JS.

Thus, in 2002, Macromedia came up with the term RIA (Rich Internet Applications) to describe a new breed of applications that combine the benefits of the web applications with the advantages of the desktop applications. The technology that made this possible was Flash Player.

Basically, if you want to create an application (not merely a web site or web page), you can do it using Flex. Some things are simply not possible with HTML/JavaScript, others would be very hard to implement consistently across browsers. Flash Player offers one of the best graphics engines, it is installed on 98% of Internet-connected computers, and it treats sound and images as first class citizens. It has support for microphones and webcams, support for streaming and data pushing, excellent support for typography, and the list could go on.

Take a look at these three applications to get an idea of what is possible using Flex:

Over time, other technologies have entered the RIA space. Besides AJAX advancements that made  applications like Gmail or Google Spreadsheets possible, today we see Silverlight from Microsoft and JavaFX from Sun.

From thin client to smart/rich client

Let’s go back to browsers and how web applications are delivered. When the browser makes a request, the server uses a combination of static content (HTML/CSS/JS code) and scripts (these scripts may query a database or call other scripts, but in the end they output HTML/CSS/JS) to prepare a page. This page gets loaded and rendered by the browser. A key element here is that, usually this page (or response) has the presentation markup and the data baked into the same message.

When a new state of the application is to be presented, the browser makes a new request and the server prepares the page. The client “just” renders the data.

Flex applications works differently. The server sends the compiled Flex application (the SWF file) that runs inside the browser using the Flash Player plug-in. Usually, this SWF file holds only the client-side business logic. If data are need (from a database for example) the Flex application makes a request for those data. The server sends only the data (this can be in XML, JSON, AMF3 format), and the client knows how to represent this data visually. What we have here is a service oriented architecture: The Flex application is the client–a client that can consume data services from the server. The application can change  state without refreshing the page or reloading the SWF file in the browser. The application is a client that can do more than “just” render data. Thus using Flex and Flash Player it is possible to create almost anything that makes sense to deploy on the web, from games, to applications, to widgets that are integrated within “classic” web applications, and more.

But enough with dry theory, let’s see some code!


Introduction to the MXML language

MXML is a declarative, XML-based language. In a Flex application you use MXML to quickly lay down the structure/appearance of your application. In Flex, anything you can do using the MXML language, you can do with ActionScript 3 as well. The  reverse, however, is not true!

If you can use ActionScript 3 to do anything you do with MXML, why does MXML exist in the first place? Usually it is much easier to follow or understand a user interface described using an XML language than an imperative one. And this translates into less code to write for a user interface. Also it is much easier to build tools for declarative languages than imperative languages. Here is a ”Hello world!” example implemented using MXML:

   1: <Label text="Hello World!" fontSize="14" color="red" x="100" y="50"/>

In this code, I use a Flex component called Label to display some text on the screen. I set the text attribute to the text I want to be displayed. Furthermore, I wanted to customize (a little bit) the appearance and the label’s position on the screen. For this, I use the attributes fontSize, color, x, and y. I think you’ll agree that this is pretty simple to understand and follow.

Now, consider the same example implemented using ActionScript 3:

   1: var myLabel = new Label();

2: myLabel.text = "Hello World!";

3: myLabel.setStyle("fontSize", "14");

4: myLabel.setStyle("color", "red");

5: myLabel.x = 100;

6: myLabel.y = 50;

7: addChild(myLabel);

I have seven lines of code to do what I did in MXML with only one tag and some attributes! Now, imagine that in a real application you have lots of controls, grouped in different containers. It is much easier to maintain code that is written using MXML than code written as  hundreds of ActionScript 3 lines.

Although you can use MXML to describe your application, you cannot use MXML to implement business logic of your application. For this you use ActionScript 3.

Flex applications run in Flash Player, and Flash Player understands only ActionScript 2 and ActionScript 3. This means that any MXML code you write in your application must be transformed by the MXML compiler into ActionScript 3 code. This code is transformed by the ActionScript compiler into bytecode (a SWF file) that can be understood by the Flash Player.

Thus, behind almost every MXML component is an ActionScript 3 class (actually there are some MXML tags that don’t have a corresponding ActionScript class, such as Script and Model). For example here is a snippet from the Label class:

   1: public class Label extends UIComponent

2: implements IDataRenderer, IDropInListItemRenderer,

3: IListItemRenderer, IFontContextComponent


5: {

6: /**

7: * Constructor.

8: */

9: public function Label()

10: {

11: super();


13: // this is so the UITextField we contain can be read by a screen-reader

14: tabChildren = true;

15: }


17: /**

18: * @private

19: * Flag that will block default data/listData behavior.

20: */

21: private var textSet:Boolean;


23: ...

24: }

In any Flex application you have at least one MXML file, which is the main application. For example, here is the complete code for the “Hello World!” application:

   1: <?xml version="1.0" encoding="utf-8"?>

2: <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">

3: <mx:Label text="Hello World!" fontSize="14" color="red" x="100" y="50"/>

4: </mx:Application>

The root node must be always Application, and this is where namespaces are defined. In this case I have only one namespace for the MXML language and Flex components: mx. (The code above is in Flex 3, in Flex 4 there are minor differences in that there are more namespaces declared).

If you write your own custom components, you’ll have to add a namespace for them. Here, for example, I declare a second namespace to refer to all the components I created (in this example, I am using a custom label component called MyCustomLabel that I created):

   1: <?xml version="1.0" encoding="utf-8"?>

2: <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:local="*">

3: <mx:Label text="Hello"/>

4: <local:MyCustomLabel text="world!"/>

5: </mx:Application>

At this point you might wonder how do you deal with the different pages for a Flex application. For an HTML website, different states usually are implemented in different pages. A Flex application is much like a desktop application. This means that you could use only one MXML file, and display in this page the different states of the application. Flex offers a number of ways to do so, from Flex components like Accordions, Tabsets navigators, Card layout, to  Flex modules.

You’ve seen that MXML code can be used to define the appearance of the application. But you can also use it to create custom components by extending existing Flex components. Let’s see an example. Suppose you have in your application a lot of forms that have two buttons: Save and Cancel. Take a look at the code for this MXML custom component (the code is created inside of a file called FormButtons.mxml; all MXML files must have the mxml extension):

   1: <?xml version="1.0" encoding="utf-8"?>

2: <mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml" width="400" height="150">

3: <mx:Button id="saveButton" label="Save"/>

4: <mx:Button id="cancelButton" label="Cancel"/>

5: </mx:HBox>

When you create a custom component, you can choose what component to extend (you are not allowed to extend Application). I chose to extend HBox (Horizontal Box), which is a container that displays all the children on the same line. Inside the container, I added two buttons, one for Save and another one for Cancel. I also set the id attribute for each one. You use the id value as a way to reference the object in other parts of the code. This is the same as declaring a variable in ActionScript code.

Now, let’s see how you could use this custom component in a Flex application:

   1: <?xml version="1.0" encoding="utf-8"?>

2: <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:local="*" layout="horizontal">

3: <mx:TextInput width="150"/>

4: <local:FormButtons/>

5: </mx:Application>

Below you can see how the application looks:


You might think that in MXML you can use only visual Flex components (that is, components that end up being displayed). Actually, this is not true. You can have MXML tags that represent data (objects that are used to store data) or components that manipulate data (components that can retrieve/send data from/to a server). Below you can see an example of a generic Object component that has a property called name:

   1: <mx:Object id="myObj" name="Mihai Corlan"/>

 As I said before, all (well almost all) Flex components that come with Flex have an ActionScript class that implements the visual appearance (if any) and the logic. When you choose to create a custom component (whether it is a visual component or not) using ActionScript instead of MXML, you have to keep in mind that there is a restriction: the constructor of the class must be able to be called without arguments (and if there are arguments, they should have default values).

Mixing MXML and ActionScript 3

Returning to the custom component FormButtons (the one with two buttons), you may have spotted a problem: What if you want to use this component in a place where the Save and Cancel labels don’t make sense? Should you create another custom component with the labels you want (let’s say Show and Hide)? Of course this is an option but it isn’t scalable or elegant! What you really want is a component that is more general, and a way to change the component using code. This is why sooner or later you’ll have to write ActionScript code in addition to MXML code.

In the next example, I added ActionScript code inside of the MXML code of the component to define two variables that store the labels the buttons used. Note, that I am using a new tag, Script, and inside of that, CDATA. This is because inside of XML documents characters like >,<, & are illegal if they are not escaped. Also, I will not focus on the ActionScript code much right now, but I will cover it in more depth in later sections.

   1: <?xml version="1.0" encoding="utf-8"?>

2: <mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml" width="400" height="150">

3: <mx:Script>

4: <![CDATA[

5: public var label1:String = "Save";

6: public var label2:String = "Delete";

7: ]]>

8: </mx:Script>

9: <mx:Button id="saveButton" label="{label1}"/>

10: <mx:Button id="cancelButton" label="{label2}"/>

11: </mx:HBox>

The variables I defined can be set from the Flex application that uses this component. So let’s see how the revised Flex application code looks when using the new custom component:

   1: <?xml version="1.0" encoding="utf-8"?>

2: <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:local="*" layout="horizontal">

3: <mx:TextInput width="150"/>

4: <local:FormButtons label1="Show" label2="Hide"/>

5: </mx:Application>

Notice that on the FormButtons tag there are two attributes: label1, and label2. This is how you can set the text you want to be displayed on the buttons. And this is the mechanism you use to add more behavior to a MXML component (using ActionScript code). In a real application you might want to bind a behavior to each button, so that when the button is pressed, something happens. You use ActionScript code to write the functions that will be triggered by pressing the buttons.

There is a second method for adding ActionScript code to MXML. You can create an ActionScript file (in this example, the name of the file is buttons.as), and include this file in the MXML file. You do that by adding a Script tag with a source attribute that points to the ActionScript file. Here is the code for this approach:

   1: // ActionScript file called buttons.as

2: public var label1:String = "Save";

3: public var label2:String = "Delete";

1: <?xml version="1.0" encoding="utf-8"?>

2: <!-- MXML component file called FormButtons.mxml a-->

3: <mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml" width="400" height="150">

4: <mx:Script source="buttons.as"/>

5: <mx:Button id="saveButton" label="{label1}"/>

6: <mx:Button id="cancelButton" label="{label2}"/>

7: </mx:HBox>

Now, let’s step back a little and understand what it is happening when the MXML compiler parses the FormButtons.mxml file. You already know that all the code will be transformed into ActionScript code. But what happens with the existing ActionScript code I added (the two variables)? The MXML compiler compiles each MXML file into an ActionScript class. In this case I’ll get a class called FormButtons (because this is the name of the file and it is used for the name of the class) that extends the HBox component (because I chose HBox as the root node of the component). And all the ActionScript code inside of the class becomes members of the class: variables (like the ones in the example) become instance variables, and functions become instance methods.

CSS styles

At this point, you might be wondering if you can change the look and feel of the visual Flex components. Is there something like CSS for HTML? The answer is yes, Flex supports CSS. In Flex 4 the support for CSS is extended to allow definition of styles not only based on class names, but on ids, to allow pseudo-selectors (for example, for a Button you have the down selector, over selector, and so on), and much more.

As in HTML, styles can be defined inline (inside of the MXML code) or in a separate file. Let’s go back to the custom component, FormButtons, and set some styles. If you choose to define the styles in a separate file, you use a Style tag and set the path to the style file within the source attribute.

   1: <?xml version="1.0" encoding="utf-8"?>

2: <!-- MXML component file called FormButtons.mxml a-->

3: <mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml" width="400" height="150">

4: <mx:Style>

5: .Button1 {

6: font-size: 14;

7: color: #990000;

8: }

9: </mx:Style>

10: <mx:Script source="buttons.as"/>

11: <mx:Button id="saveButton" styleName="Button1" label="{label1}"/>

12: <mx:Button id="cancelButton" label="{label2}"/>

13: </mx:HBox>

I created a CSS class called Button1 that defines the color for the label and the font size. Then I set the style to the first button using the styleName attribute of the first button. The application now looks like this:


CSS styles can be changed at runtime (after the Flex application is loaded in the browser), and the application’s appearance will immediately change.

In Flex 4, Adobe added a new language called MXML for Graphics that adds primitives, effects, masks, and 2D transformations. You can create a skin class in an MXML file using these new tags, and then you can set this class to the component you want to skin. Below, you can see a list skinned in Flex 4. The image on the left shows the list in its default state, and the right shows the hover state. You can see the application live here.


 While wandering in the documentation for customizing of the look and feel for Flex applications, you might come across of the term “skinning”. You can do graphical skinning or programmatic skinning in order to change the appearance. Here is a good article on this matter.

Modifying MXML code at runtime

Sometimes you want to change the UI components at runtime. Maybe you want, depending on some data you retrieve from the server, to build a form on the fly. Again, you can use ActionScript code to do this. Any visual Flex component has methods for adding a new child, removing a child, getting all children, and so on. If you want, you can compare this with the way you change the DOM in HTML using JavaScript. However, there is a difference: with JavaScript you can inject HTML code that you can retrieve dynamically from a server (with an AJAX call). In Flex this is not possible, and the eval() function doesn’t exist in Flex. However, there is a way to load other Flex applications or Flex modules after the main application is loaded.

When you know all the different possible views for a component, you can use MXML States to implement different states for the same component or application. States are an area where Flex 4 has significantly improved on the Flex 3 implementation, making them much easier to use and adding more power. In Flex 4 states work like this:

  1. you define a number of states and specify the default one
  2. you can then specify on which states a particular component should appear
  3. you can specify separate values for any attribute for each state where it appears

Suppose you want to create a component that deals with the login functionalities of an application. You want to use this component for displaying the login form, and when the login is successful you want to display the log out button and the name of the user.

Here is how you can create this Login/Logout component using Flex 4:


   1: <?xml version="1.0" encoding="utf-8"?>

2: <s:Group xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/halo">

3: <s:states>

4: <s:State name="notlogged"/>

5: <s:State name="logged"/>

6: </s:states>


8: <s:TextInput includeIn="notlogged" text="user name"/>

9: <s:TextInput includeIn="notlogged" text="password"/>

10: <s:Button includeIn="notlogged" label="Login" click="{currentState='logged'}"/>


12: <mx:Label includeIn="logged" text="Current user: Mihai Corlan"/>

13: <s:Button includeIn="logged" label="Logout" click="{currentState='notlogged'}"/>

14: <s:layout>

15: <s:HorizontalLayout/>

16: </s:layout>

17: </s:Group>

The code should be self-explanatory. As the top container, I use a Group component that has the layout set to HorizontalLayout (this has the same effect as the HBox used in the Flex 3 example above). I have defined the available states for this component at the top of the file. Next I have the buttons, text inputs, and label. Notice the includeIn attributes that specify in which state the component appears. Just for the record, there is also an excludeFrom attribute. If you want to have a button in all the states, then you don’t specify anything for these two attributes. Finally, you can see I assigned an expression for the click attributes of the two buttons. For example, click=”{currentState=’logged’}” tells Flex that when the button is clicked, change the state of the component to the one named logged.

I’ve been including more and more ActionScript code in these examples, although I am still talking about the MXML language. This is a sign that it is time to move to the second Flex language, ActionScript 3.


Introduction to the ActionScript 3 language

ActionScript 3 is a dynamic object-oriented scripting language that is (almost) type-safe. ActionScript 3 is based on the ECMAScript 3 specifications (ECMA-262). Also, some its features are aligned with the proposal of the ECMAScript 4. I’ve found that it is easiest to explain ActionScript 3 to someone who is completely new to it in this way: ActionScript looks like a mix of JavaScript and Java plus it has its own strong personality. Actually, JavaScript is another language based on the ECMAScript specifications, thus it’s only natural to have things in common with ActionScript.

As I said before Flash Player can work with two languages: ActionScript 2 and ActionScript 3. Internally it uses two different Virtual Machines two accommodate these two languages (ActionScript 3 and the AVM2 Virtual Machine appeared in Flash Player 9). ActionScript 3 consists from the core language (keywords, data types, and so on) and the Flash Player API (this API gives developers access to all Flash Player features via the display list API, 3D API, drawing API, Animations, and so on. In this article I’ll focus on the core language. Here is a good introductory article on ActionScript 3.

From now on I will use the abbreviation “AS3” interchangeably with “ActionScript 3”.

Separating statements

In PHP you use a semicolon (;) to separate or end a statement. In AS3 you can use a semicolon (;) or simply the end of line. I have to say that when I see code written without semicolons it is not a joy for the eyes. So, I suggest you use the same method you use in PHP.

Data types, variables, constants

In PHP there are the following data types: Booleans, integers, floating point numbers, Strings, Arrays, Objects, Resources, and NULL.

In AS3 we have:

  • top level data types: Boolean, int, uint, Number (same as floating point from PHP), Strings, Null (contains only one value: null), void (contains only one value: undefined)
  • complex data types: Object, Array, Vector (starting with Flash Player 10), Dictionary, Bitmap, ByteArray, Date, XML, XMLList, Function, Error, RegExp

In AS3, a variable is just an identifier or reference associated with the actual value. The legal values in AS3 are object (int or uint are objects, the same goes for Number or Date), null, and undefined. null and undefined signify the absence of data, however there is a difference between them. When you declare a variable and you don’t initialize it, it will have the value null if the type of the variable is not Boolean, int, uint, or Number. If the variable is untyped and it isn’t initialized, it will have the value undefined. At the same time, when you have a dynamic object and you want to check that a particular method or property is defined you can check against undefined.

In PHP you declare a variable like this:

   1: $anInteger = 12;

2: $isTrue = true;

3: $aString = "my string";

4: //or

5: $aString = 'my string';

In AS3 you use the var keyword when declaring a variable:

   1: var anInteger:int = 12;

2: var isTrue:Boolean = true;

3: var aString:String = "my string";

4: //In AS3 you can not use simple quotes for declaring a String

Note that after the variable name, I have a type annotation; for example, myVarName:Boolean (the type is declared using “:” followed by the type). AS3 lets you work either with type annotations or without (if the strict mode for the compiler is set, then you must include type annotations).

Coming from PHP where you don’t have to declare the type of the variable, this might seem strange, and you may want to stick with the untyped way of doing things. As tempting as this might be, I strongly encourage you to use the type annotations. First of all, when you use an IDE for writing code, typing your variables will enable you to find more errors at compile time. For example, consider a function that has a single String argument. If you try to call this function passing an Object as argument, the IDE will alert you to you this error.

Without the type annotations you might get a run-time error, but only when you or the end-user runs the application, and at that point the source of the bug will be much harder to pinpoint.

The second reason for sticking to type annotations is that the AS3 compiler can make optimizations if it knows the specific types of the variables.

In PHP you can change the type of a variable with each assignment:

   1: $myVar = 12; //it is an int

2: $myVar = "now is a string";

In AS3 you can do the same (in strict mode) only when you declare the variable untyped using “*”:

   1: var myVar:int = 12;

2: //this will raise an error and the application can not be compiled

3: myVar = "this is a string";


5: //declaring the variable untyped you can change the type with each assignment

6: var myVar2:* = 12;

7: myVar2 = "this is a string now";

You notice that I use the var keyword only when declaring the variable. For further assignments you omit the var and type annotation.

As I said before, in AS3 variables are just references to the actual object. However, when you assign an int, uint, Number, Boolean, or String variable to another variable, a copy is created (the same goes when passing a variable of these types to a function). In PHP, you can use the “&” operator to always assign variables by reference even for primitive types; and when you change the value for one variable, the other variable will point to the same cahnged value.

To concatenate strings in PHP you use “.” (dot), in AS3 you use “+” (plus):

   1: //in PHP

2: $space = " ";

3: $a = "this" . $space . "is!";


5: //in AS3

6: var space:String = " ";

7: var a:String = "this" + space + "is!";

In PHP you can define variables wherever you want: at the file level, in a function, or in a class. In Flex applications, variables can be declared only inside of a function or at the class level.

Furthermore in PHP you can have a piece of procedural programming that it is not declared inside of a function:

   1: <?php


3: $a = 1;

4: for ($i=0; $i<100; $i++) {

5: $a += $i * $a;

6: }


8: ?>

In AS3 you can not do operations with variables outside of functions (although you can declare variables outside of functions) with one exception that I will explain when I cover Classes. Thus if you try to run the next code, you’ll get an error when you compile the application:

   1: <?xml version="1.0" encoding="utf-8"?>

2: <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">

3: <mx:Script>

4: <![CDATA[

5: var a:int = 1;

6: for (var i:int = 0; i<100; i++) { //this raises an error

7: a += i * a;

8: }

9: ]]>

10: </mx:Script>

11: </mx:Application>

This is how you can rewrite the code to work:

   1: <?xml version="1.0" encoding="utf-8"?>

2: <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">

3: <mx:Script>

4: <![CDATA[

5: var a:int = 1;


7: function calculations(a:int):int {

8: for (var i:int = 0; i<100; i++) {

9: a += i * a;

10: }

11: return a;

12: }

13: ]]>

14: </mx:Script>

15: </mx:Application>

In PHP, constants are declared and used like this:

   1: //constants

2: define("CONSTANT", "Hello");

3: $myString = CONSTANT . ‘ world!’;

In AS3 constants are declared using the const key word (there is a convention to name constants with uppercase letters):

   1: static const HELLO:String = "Hello";

2: var myString:String = HELLO + " world!";

What can be used as a name of a variable? Here PHP and AS3 are similar: as long as the first character of the name is a letter or “_” followed by letters, digits, or underscores it is legal. Here are examples of variable names that are legal in both languages: _1, _a1A, b.

In PHP you have a way to use a variable by knowing its string name:

   1: <?php

2: $myVar = 12;

3: $varName = 'myVar';

4: echo($$varName); //print 12;

5: ?>

You can achieve similar functionality in AS3 using the dynamic method of referencing members (variables/methods).

   1: <?xml version="1.0" encoding="utf-8"?>

2: <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="init()">

3: <mx:Script>

4: <![CDATA[


6: var myVar:int = 12;


8: function init():void {

9: var varName:String = "myVar";

10: trace(this[varName]); //output 12

11: }

12: ]]>

13: </mx:Script>


15: </mx:Application>

In the example I used this to reference the current object, but you could use the same technique on any object. I’ll add more on this when I talk about dynamic classes.

Functions and Anonymous functions (closures)

In AS3 you can do everything with functions that you can do in PHP, and some more.

First, in AS3 you can define the type of the arguments and the return type (in PHP you can add type annotations only to methods from objects).

   1: function calculate(x:int=0, y:int=0):int {

2: return x + y;

3: }

4: //using the function

5: var result:int = calculate(1, 2);


7: function calculateAverage(...arguments):Number {

8: var result:Number = 0;

9: for (var i:int=0; i<arguments.length; i++) {

10: result += arguments[i];

11: }

12: return result/arguments.length;

13: }


15: //using the function

16: var result:Number = calculateAverage(1, 2, 3, 4, 5, 6);

You can mix the … (rest) operator with explicit arguments as long as you place the rest operator as the last one in the list of the arguments: function foo(x:int, y:int, …arguments):Number {}. The rest operator can be useful when you want to create functions with a variable number of arguments.

If the function doesn’t return anything you use void as a return type.

In PHP and AS3 you can have default values for the arguments. For example:

   1: //php code


3: function doThing($a, $b="default value") {

4: echo $a . $b;

5: }


7: //AS code

8: function doThing(a:String, b:String="default value"):void {

9: trace(a + b);

10: }

Of course you can define functions inside of a function (you’ll see an example in the next code sample).

Second, in AS3 any function is represented as an instance of the Function class. This makes some interesting things possible:

  • you can create a literal function and assign it to a variable and then call the function through that variable (this is possible in PHP too)
  • you can return a function as a result of the execution of another function
  • you can pass functions as arguments when calling other functions
   1: var f:Function = function multiply(x:int, y:int):int {

2: return x*y;

3: }


5: trace(f(3,5));


7: function giveMeAFunction():Function {

8: return function multiply(x:int, y:int):int {

9: return x*y;

10: };

11: }


13: var h:Function = giveMeAFunction();

14: trace(h(3,4));

In PHP and AS3 you can create anonymous functions (or closures). In the previous code sample, you can see an example of creating an anonymous function inside giveMeAFunction() and returning it.

Maybe the biggest difference between functions in AS3 and PHP is how you define them. In PHP you can define any number of functions in a file. In AS3 you can define only one function in a file, and the name of the function must match the name of the file. For example, if you define a function called doSomeMath(), you have to create that function in a file called doSomeMath.as. When defining functions you use package declarations (you’ll learn about packages in the next section). Thus, when you want to create a bunch of utility functions, if you don’t want to write them in a bunch of files, you can create a single class and define them as static methods.

OOP: classes and interfaces

It is time to move to the Object Oriented Programming features of the PHP and AS3. In PHP you can write object oriented or procedural code; AS3 is object oriented.

Let’s start with a simple PHP class to see the differences in syntax (remember I use PHP 5.3 as a reference):

   1: namespace org\corlan {


3: class SimpleClass {


5: public $public = 'Public';

6: protected $protected = 'Protected';

7: private $private = 'Private';


9: function SimpleClass() {


11: }

12: // Redefine the parent method

13: function displayVar()

14: {


16: }

17: }

18: }


20: //use the class like this

21: require_once('flassFile.php');

22: $obj = new org\corlan\SimpleClass();

23: $obj->displayVar();

In AS3 the same class is written as follows:

   1: package org.corlan {


3: public class SimpleClass {


5: public var _public:String = "Public";

6: protected var _protected:String = "Protected";

7: private var _private:String = "Private";


9: function SimpleClass() {


11: }


13: // Redefine the parent method

14: public function displayVar():void

15: {


17: }

18: }


20: }


22: //you use the class like this:

23: import org.corlan.SimpleClass;


25: var object:SimpleClass = new SimpleClass();

26: object.displayVar();

Here are the main differences:

  • naming the file where the class is stored
    • In PHP you can define a class in a file that can be named in anyway
    • In AS3 the name of file must be the same as the name of the class (if the class is called SimpleClass, then the file must be SimpleClass.as)
  • namespaces vs Packages
    • In PHP you can use namespaces in order to avoid name collisions between classes
    • In AS3 you use packages; however when you declare a class that is in the org.corlan package for example, that means the class will be inside of a folder org/corlan in the Flex source folder. The package name translates into a folder structure. Packages used together with class access-modifiers can hide the class to the classes outside of the project (more on this later)
  • require/include vs. import
    • In PHP, usually, you include the file where the class is defined using the require_once function. Starting with PHP 5 you can define an __autoload() function and do the require_once or include_once in this function instead of writing the list of required file at the top of each file
    • In AS3 you use an import statement to include the desired class. However, if you want to include all the classes from the package org.corlan, you can write the import using a wild card: import org.corlan.*. Another difference is that the AS3 compiler will compile only the classes that are actually used in your code (that is only when an instance of that particular class is actually created).
  • calling a method/member on an instance:
    • In PHP you use the “->” operator
    • In AS3 you use the “.” (dot) operator

Now, let’s move to the class/methods/members modifiers.

I’ll start with class modifiers:

  • PHP has final, and abstract; public is implicit, all the classes are public in PHP
  • AS3 has public, internal, final, and dynamic. If you don’t specify any access-modifier (public or internal), then the class is by default internal, meaning it can be accessed only by the classes from the same package. public and final have the same meaning as in PHP; abstract doesn’t exist in AS3, but you can overcome this limitation using interfaces. Dynamic marks the class as a class that can be changed at run-time by modifying existing members or adding new ones.

Modifiers for class properties:

  • PHP has: public, private, protected, static
  • AS3 has the PHP modifiers plus internal. Internal is used for making properties available only inside of the same package. When no modifier is specified, internal is used.

Modifiers for class methods:

  • PHP has public, private, protected, static, final, and abstract.
  • AS3 has: public, private, protected, static, final, internal, and override. Abstract doesn’t exist in AS3; internal makes the methods available only to code from within the same package.

In AS3 everything you can do with a function closure, you can do with class methods.

Constructors in PHP can be marked as private, you can define a constructor with the same name as the class name, or you can use the special methods __construct(), __destruct(). In AS3 the constructor is always public and must have the same name as the class name. If none is provided, AS3 creates one behind the scenes for you.

Static members or static methods are accessed:

  • In PHP using ClassName::propertyName
  • In AS3 using ClassName.propertyName. However inside of the same class you can drop the class name.
   1: package org.corlan {


3: public class Foo {


5: private static myVar:String;


7: function Foo() {

8: Foo.myVar = "value 1";

9: myVar = "value 2";

10: }


12: }

13: }


  • In PHP you use the special class variable $this to refer to class members (variables/methods) defined within the same class: $this->myVar = 22;
  • In AS3 you use the same this: this.myVar = 22; however, you can drop this and just use myVar = 22.

In AS3 only one class can be declared inside of the package (an this class gives the name of the file). However, outside of the package declaration you can declare as many classes you wish:

   1: package org.corlan {


3: public class Foo {


5: private static var instance:Foo;


7: function Foo(object:Bar) {


9: }


11: static public getInstance():Foo {

12: if (Foo.instance == null) {

13: Foo.instance = new Foo(new Bar());

14: }

15: return Foo.instance;

16: }


18: }


20: class Bar {}

This has an interesting effect: all the classes defined in a file outside of the package will be available only to the code declared inside of the same file. For all other code they don’t exist. Remember the limitation that in AS3 you can’t declare the constructor private? Well, by using a technique similar to this example, you can make sure that there is only one instance of the Foo class. If some external code calls the constructor, a run-time exception will be thrown because the outside code cannot use an instance of Bar as this class is invisible to external code.


Extending classes in AS3 is very similar to how it is done in PHP. You use the same extends keyword followed by the name of the class you want to extend. Overriding is the same as in PHP, the only difference is that you have to add the override keyword to the method signature. Overloading is not supported (you cannot have two or more methods with the same name).

In PHP you access parent members using the syntax parent::memberName; in AS3 you use super.memberName. When the constructor of a class is executed, first the parent constructor is called. This happens even when you don’t call it explicitly from your code. Thus, when you have code in the constructor method you cannot have the call to the parent constructor after your code. This way, you give a chance for the parent class to be correctly initialized, so the child will not use members that aren’t set yet. You call the parent constructor using this syntax: super(). Let’s see these concepts at work, first the PHP code and then the AS3 code.

   1: class SimpleClass {


3: function SimpleClass() {

4: echo('SimpleClass() called');

5: }


7: function __construct() {


9: }



12: function displayVar()

13: {

14: echo "SimpleClass class\n";

15: }

16: }


18: class ExtendClass extends SimpleClass {


20: function ExtendClass() {

21: $myVar = 1;

22: parent::SimpleClass();

23: //or

24: parent::__construct();

25: }

26: // Redefine the parent method

27: function displayVar()

28: {

29: echo "Extending class\n";

30: parent::displayVar();

31: }

32: }
   1: public class SimpleClass {


3: function SimpleClass() {

4: trace("SimpleClass() called");

5: }


7: public function displayVar():void

8: {

9: trace("SimpleClass class");

10: }

11: }


13: public class ExtendClass extends SimpleClass {


15: function ExtendClass() {

16: super(); //we have to call first the parent constructor, and only after we can execute our code

17: var myVar:int = 1;

18: }


20: override public function displayVar():void {

21: trace("overrided displayVar()");

22: super.displayVar();

23: }

24: }

Let’s have a look at how a class is initialized in AS3. When a class is instantiated, first all the properties are initialized, then the static code defined at the class level is executed (this is something that is not possible in PHP), and then the constructor is executed. Here is an example:

   1: public class Foo {


3: private var a:int = 0;

4: private static var os:String;

5: trace("initializer");


7: if (Capabilities.os == "LINUX")

8: os = "LINUX";

9: else

10: os = "other";


12: public function Foo(a:int=1) {

13: trace("foo() executed");

14: }

15: }


17: var foo1:Foo = new Foo();

18: var foo2:Foo = new Foo();

19: //produces this output in console:

20: initializer

21: foo() executed

22: foo() executed

In AS3 you can create objects out of function closures using the prototype property of a function (it is similar to what you use in JavaScript to create/extend classes). Here is a short example:

   1: //we create a function

2: function MyClass(value:String = "Mihai") {

3: //we create a property

4: this.name = value;

5: }

6: //we use the special variable prototype of the function

7: //to create another method

8: MyClass.prototype.setName = function (value:String):void {

9: //we have access to the property defined on MyClass object

10: trace(this.name);

11: this.name = value;

12: trace(this.name);

13: }


15: //create an instance

16: var myObject = new MyClass();

17: //accesing the method created earlier

18: myObject.setName("Joe");

I will talk more about the dynamic features of AS3 in a later section.


In any OOP language usually you use getters/setters for controlling the class properties that you want to expose outside. PHP is no exception. However, in AS3 there is special support for properties using the keywords set and get. Here is an example:

   1: public class Employee {


3: private var _salary:int = 0;

4: private var _income:int = 0;


6: function Employee() {


8: }


10: public function set salary(value:int):void {

11: if (value > 0) {

12: this._salary = value;

13: this._income = this._salary * 12;

14: }

15: }


17: public function get salary():int {

18: return this._salary;

19: }


21: public function get income():int {

22: return this.income;

23: }

24: }


26: //using this class

27: var emp:Employee = new Employee();

28: emp.salary = 1000;

29: trace(emp.income);

30: //this raise an error, because the income property is read-only

31: //for the outside code

32: emp.income = 120;

Basically, although I have setter and getter for the _salary field, I can call these methods as if they were fields or properties and not functions: object.salary = 20 instead of object.salary(20). And if you choose to not define a setter, you get read-only properties. This is what I’ve done with the _income property.

This feature, besides making the code a little bit cleaner, makes it easier to write APIs or classes that will be used by others. Suppose that in my example I chose to create the _salary field as a public member. If later on I decide that I need to validate the values that can be set, I have to add a setter. In PHP this would be something like myObject.setSalary(). In this very moment any code that uses the class is broken; it must be updated to use the setter.

In AS3 you can start the class with the property defined as public var salary:int and when you decide you need a setter, you rename the variable and add the public function set salary() method. Any code that uses the class is not affected by this change, because it is still accessing the property using the same syntax: objectInstance.salary = 10.

There is a convention in AS3 when using this style of setters and getters, to add an underscore to the variable name.


Interfaces work almost the same in PHP and AS3. The notable difference is that while in PHP you can define methods and constants, in AS3 you can define only methods. However, you can define setters/getters:

   1: public interface IEmployee {


3: public function set salary(value:int);

4: public function get salary():int;

5: public function get income():int;

6: }


As in PHP, AS3 has support for exceptions:

   1: try {


3: } catch(e:Error) {


5: } finally {


7: }


9: //throwing an exception

10: throw new Error("Some error");

Error is the top class for all the errors in AS3. You can create your own errors extending this class, or you can use the existing subclasses.

Casting and testing the type of an object

Sometimes you want to cast an object to a different type, or you want to check the type. For checking the type in PHP you use instanceof, in AS3 you use is. To do a cast, in AS3 you have two different syntaxes.

   1: class A {};


3: class B extends A {};


5: var b:A = new B();

6: //casting

7: var c:B = b as B;

8: //or

9: var d:B = B(b);


11: //checking the type of an variable

12: if (b is A)

13: trace(true);

14: if (b is B)

15: trace(true);

Variable scope

Having seen how variables, functions, and classes work in Flex and AS 3, it is time to talk about variable scope. In PHP basically you have two scopes: global (variables defined at file level) and local (variables defined inside of functions).

In Flex there are five possible scopes: function body, instance method body, static method body, class body, and global scope. Adding to these the access modifiers (public/private/protected/internal) makes things a little bit more complicated than in PHP.

Scopes can be nested; in this case the variables/functions/members of the enclosing scope become available to the one nested. For example when you declare an anonymous function inside of the body of another function, in AS3 all the variables defined in the outer function are available inside of the nested function. In PHP, you have to pass the variables you want to be used, or add the use statement:

   1: //php code

2: function a() {

3: $a = 1;

4: $b = 2;


6: function b() use ($a, $b) {


8: }

9: }


11: //AS3 code

12: function a():void {

13: var a:int = 1;

14: var b:int = 2;


16: function b():void {

17: //variables a and b are available here

18: }

19: }

When you declare a function inside of an unnamed package, it is placed in the global scope and it is available to all code. However, anything declared outside of a package is still in the global scope, but it is visible only to code from the same file.


Arrays in AS3 are very similar to those from PHP, with one difference: in AS3 an array can have only numerical indexes. If you want to create an associative array, you can use the Object class. If you want to create a hash map where the keys are objects (and not strings) you can use the Dictionary class. You create an array using the Array class, and you can have multi-dimensional arrays. For both Object and Array you can use the literal definition. Let’s see some examples:

   1: var myArray1:Array = new Array(1, 2, "some string");

2: //creates an array with three elements: 0->1, 1->2, 3->some string


4: //literal definition for an array

5: var myArray2:Array = [1, 2, 3];

6: //ading two more elements

7: myArray2.push(4,5);


9: //a hash map, similar to associative arrays in PHP

10: var myMap:Object = new Object();

11: myMap.name = "Flex";

12: //literal definition of a map

13: var myMap2:Object = {name:"Flex"};


15: //using Dictionary class

16: var dic:Dictionary = new Dictionary();

17: var anObject:Object = new Object(); //creating the key

18: dic[anObject] = "some value"; //adding a value to Dictionary

You have all the expected methods to add elements or to remove elements, including push, shift, pop, unshift, and splice. Concat can be used to add arrays to another array. In the previous example you can see how I use push to add two more elements to an array.

Arrays are not fixed length; they can grow as you add more elements. In PHP you use “[]” to add a new element at the end of the array. There is a similar method in AS3 that uses the length property of the array (you can also use the length property to decrease the size of the array):

   1: var array:Array = new Array();

2: array[array.length] = 1;//array has the values: 1

3: array[array.length] = 23;//array has the values: 1, 23

You can use delete to set a specific element of an array to undefined: delete array[index]. This will not shorten the length of the array. You can use the for() statement to loop through an array using its length property. If you want to loop through an Object (again this could be used to create something similar to PHP associative arrays), you can use for – each (which works similar to the same construct in PHP) or for – in statements (more on this in the Dynamic section).



If you are looking for the equivalent AS3 concept for PHP namespaces, you should read about packages in the Classes section, because AS3 packages are similar to PHP namespaces.

In ActionScript, namespace has a different meaning. Let’s see what namespaces are used for, and then I’ll provide some examples:

  1. prevent naming conflicts (you can create multiple methods with the same name in the same class, each one in a different namespace)
  2. mark variables and methods across frameworks/programs to a custom visibility setting (for example, Flex uses a namespace called mx_internal; using the namespace instead of private or protected, makes it possible to use those methods across any package and class from the Flex framework. At the same time, developers are warned that those methods or members are not meant to be used externally, as they might change)
  3. implement permissions-based access control for a class
  4. create a class that can switch its behavior based on the specific selected namespace

Before going into details, I should note that namespaces are used internally by Flash Player to implement the access modifiers: public, protected, internal, and private.

You define a namespace using this syntax: namespace identifier = URI. Identifier is what you’ll use when declaring variables/methods, and when you want to qualify a member or method in order to use it. URI usually is an URL that must be unique for your application. It doesn’t have to exist, and in most cases you’d use your domain name. For example, I would define a namespace like this: namespace online = “http://corlan.org/apps/online”.

You can define a namespace wherever variables can be defined: at the top level of a package definition (it will be available across the program), or at class level (it will be available only in the class where it is defined). At the function level you can use only a namespace that was defined somewhere else (you might need this in order to qualify a variable that was defined elsewhere using the same namespace; you need to know the URI in order to do that).

You can declare a method or variable in a given namespace by placing the namespace identifier before the declaration. For example: mynamespace var a:int = 1. When you define a variable or method in a namespace, you are not allowed to use other access-modifiers (like private for example).

In order to call a variable or method that was defined in a namespace, you use the name-qualifier operator “::”. Suppose you defined a method called myMethod() in a namespace called online, you can access the method using this syntax: objectInstance.online::myMethod(). The same goes for variables. Sometimes you may need to use many variables or methods that must be qualified with the namespace name. You can open the namespace in that scope and get rid of the name-qualifier operator. You do this using the use namespace namespaceidentifier directive. For example:

   1: public function doSomething() {

2: use namespace online;

3: //call the method defined in that namespace:

4: myMethod();

5: }

You can pass around namespaces, for example you can return a namespace from a method, enabling the calling code to use it to qualify a method or member.

Now, let’s create two namespaces that can be used to change the behavior of a class at runtime. First, I’’ll define the two namespaces (I will use one file for each namespace):

   1: // ActionScript file online.as

2: package org.corlan {

3: public namespace online = "http://corlan.org/apps/online";

4: }
   1: // ActionScript file offline.as

2: package org.corlan {

3: public namespace offline = "http://corlan.org/apps/offline";

4: }

Next, I will use these two namespaces to create a class that persists an object. Depending on the connectivity status it can persist the object locally (using local storage for example), or remotely on the server (using a REST service). The interesting part comes when some code needs to use this class. The calling code doesn’t care about the method at all; it just wants to have the objects stored.

Using these two namespaces, I will create a class that has two methods both named save(), each one defined in one the two namespaces. Next, I have a private variable that stores the current namespace to be used depending on the status of the Internet connection. The calling program accesses the current namespace using a getter, and uses this to call the save() method. Again, the calling program doesn’t know about all these internals and doesn’t know about the namespaces, nor does it care. Let’s see the PersistObject code:

   1: package org.corlan {

2: import flash.events.Event;


4: public class PersistObject {


6: private var _mode:Namespace = offline;


8: public function PersistObject() {


10: }


12: online function save(object:Object):void {

13: //save the object back to server

14: trace("online");

15: }


17: offline function save(object:Object):void {

18: //save the object locally

19: trace("offline");

20: }


22: private function connectivityChanged(e:Event):void {

23: //here the mode can be changed from offline to online

24: //and vice-versa

25: }


27: public function get mode():Namespace {

28: return this._mode;

29: }

30: }

31: }

The next code snippet uses this class. The code is simple, and the inline comments should explain it.

   1: //creating an object that we want to be stored

2: var object:Object = {book:"Ulysses", author:"James Joyce"};

3: //create an instance of PersitObject

4: var persistenceObject:PersistObject = new PersistObject();

5: //get the current namespace

6: var currentMode:Namespace = persistenceObject.mode;

7: //use the namespace we retrieved to qualify the save method()

8: persistenceObject.currentMode::save(object);

Namespace accessibility

You can use the same access-modifiers you use for variables or methods: public, internal, protected, and private (for namespaces defined at the package level you can use only public and internal). Combining this with the location of a namespace definition you have great control over the visibility of a namespace in a program.

Working with XML

In PHP there is extensive support for XML through native functions or additional extensions. In AS3 there are two classes that represent XML natively: XML and XMLList. AS3 implements the XML class based on the W3C DOM (you have methods like children(), appendChild(), parent(), insertChildBefore() and so on). When you work with XML it is a good idea to know how to use E4X. E4X (ECMAScript-for-XML) is a ECMA-262 language extension that is implemented by AS3. You use XML to represent an XML document. Any node from the document is wrapped into an XMLList even when there is only one child.

You can create an XML object using anyone of the following methods:

  1. write the XML using literal form
  2. create an instance of XML and then import the XML from an external file
  3. create an instance of XML and use dot notation to add/change the structure:
   1: var author:XML = <author/>;

2: author.@id = 1; //setting an attribute called id and its value

3: //adding two child nodes to author:

4: author.name = "Mihai Corlan";

5: author.article = "Flex for PHP developers";


7: //this code is equivalent with:

8: var author:XML = <author id="1">

9: <name>Mihai Corlan</name>

10: <article>Flex for PHP developers</article>

11: </author>;

Using E4X you can easily find  nodes by creating conditions based on the name of nodes or attribute values. You can use the descendant operator “..” to retrieve all the nodes with a given name (for example to retrieve all the program nodes you can write: programs..program). You can create conditions based on attributes using the “@” operator (for example, programs..program.(@id==2)). And finally using dot notation you can navigate through nodes (just keep in mind that any child is treated as an XMLList even when it is the only child). Below you can see examples of using E4X to work with XML.

   1: var programs:XML = <root>

2: <program id="1">

3: <name>Flex</name>

4: </program>

5: <program id="2">

6: <name>ActionScript 3</name>

7: </program>

8: <program id="3">

9: <name>AJAX</name>

10: </program>

11: </root>;


13: //retrieving the second program node and printing its name

14: trace(programs.program[2].name[0]);

15: //retrieving all the program nodes:

16: var list:XMLList = programs..program;

17: //retrieving all the program nodes that have an id attribute equal to 2

18: var list:XMLList = pograms..program.(@id==2);

Dynamic ActionScript

Remember the definition of AS3? In the definition I stated that AS3 is a dynamic scripting language. Let’s dig a little more into this feature. Dynamic means that an object can be modified at runtime by adding or removing methods or members. It is possible to add new methods to the class itself (and any object created from that class will have those methods). You can even create new classes from scratch (using the protoype property). In AS3 there are built-in dynamic objects such as Object, and in Flex there is another example, ObjectProxy.

If you’re wondering why this feature exists in the first place, the answer is simple: the earlier versions of ActionScript didn’t have all the features and OOP that AS3 offers today. I have to say, that from my experience, not many developers use the dynamic features of AS3. There are a couple of reasons for this. First access time for dynamic members is slower than fixed members. Second, you end up with code that is more prone to bugs (there is no compile-time error checking, for example).

You are not limited to the built-in classes; you can create dynamic objects using the dynamic modifier on the class definition:

   1: dynamic public MyDynamicObject {


3: }

Now, using the class yoy’ve just defined, you can add members at run-time (remember that all dynamic instance variables are untyped and public):

   1: var a:MyDynamicObject = new MyDynamicObject();

2: a.author = "Mihai Corlan";

You can cycle through all the members of a dynamic class using for-each-in loop. Here is how you can display the members from the previous example:

   1: for each (var element:* in a) {

2: trace(element); //displays Mihai Corlan

3: }

If you want to get the members names instead of their values, you use for-in loop:

   1: for (var memberName:* in a) {

2: trace(memberName); //outputs author

3: trace(a[memberName]); //outputs Mihai Corlan

4: }


Flex is asynchronous

So far, I’ve covered many Flex features, and many of them were quite similar with their PHP counterparts. However, the asynchronous nature of Flex is something rather different from anything in PHP. It is important to understand this, stop fighting it, and go with the flow.

What does it mean that Flex is asynchronous? Suppose you create a Flex application, and after the application is loaded in the browser, the user can choose to load pictures from another site. You might use a URLLoader class for this task. When you execute the load() method, on the next line of code you won’t have the data. The script doesn’t pause after the load() call waiting for the data to be loaded. Instead the execution of the script is resumed. As a programmer you deal with this asynchronous nature using the built-in AS3 events system. If you’re familiar with AJAX programming, this is similar to what you do when you make an AJAX call: you provide a callback function, and when the data arrives the callback function is called and you can access the loaded data.

Going back to the ULRLoader example, you would add an event listener for the result event. This is the function that will be called once the data is loaded. Here is an example of how the code might look:

   1: function loadPic():void {

2: var loader:URLLoader = new URLLoader();

3: loader.dataFormat = URLLoaderDataFormat.BINARY;

4: //adding the event handlers or listeners

5: loader.addEventListener(EventComplete, picLoaded);

6: loader.addEventListener(IOErrorEvent.ID_ERROR, picError);

7: //starting the loading

8: loader.load(new URLRequest("http://some_url"));

9: }


11: //event handler for

12: function picLoaded(event:Event):void {

13: //get the data from the loader object

14: //use the target property to get the loader object

15: (event.target as URLLoader).data;

16: }


18: //event handler for the error event

19: function picError(event:IOErrorEvent):void {

20: //displays the error id in a pop-up windonw

21: Alert.show(event.errorID);

22: }

I can summarize it like this: don’t call us, we’ll call you!

As I said, AS3 has a built-in event system. The top class of all events is Event. All objects that work asynchronously have an addEventListner() method, and the first two arguments are the event type, and the name of the function to be called when the event occurs. You might think that only  objects that deal with retrieving remote data are subject to this event model. Actually that is not the case; all components or objects that are visual also have events. For example, every Flex application has a creationComplete event. This event is triggered once all the required components from the application are processed and drawn on the screen.

Although you might feel that such code is not as straightforward as PHP, there is a good reason for having asynchronous calls scattered around in Flex (and Flash Player): Flex is a client-side technology. If all calls were synchronous, the user interface of the application would stop being responsive for any call that involved loading data, for example. And users hate unresponsive user interfaces.

You can cancel some events and even change the default behavior. I’ll let to you explore these details on your own if you need to; for now you should have a fairly good idea of what events and event listeners are all about.


Data Binding, metadata tags, and reflection

Data binding is another Flex feature that makes a developer’s life a lot easier, and at the same time reduces the number of lines of code. Data binding is an elegant way to bind the data model to the view and automatically update the view to reflect any data model change.

Because Flex is used to create application user interfaces, Flex components typically end up displaying a lot of data. When the data are modified, even in real-time, you’ll usually want to display the latest data and not the old data. Using data binding you can achieve this very easily. Data binding links a property of an object (called the source) to another object’s property (called the destination), so whenever the source changes the destination is automatically updated.

In Flex 4 there is support for bidirectional binding (actually you can do it in Flex 3 too, but you need to declare it in a second step), which means that it operates the other way around too: when the destination is updated, the new value is copied to the source. This is useful when you have a data model and a form. You bind the data model to the form, and when the user changes values in the form, bidirectional data binding updates the data model with the form’s values. It’s time to see some code.

   1: <?xml version="1.0" encoding="utf-8"?>

2: <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="horizontal">

3: <mx:Script>

4: <![CDATA[


6: [Bindable]

7: private var labelValue:String = "Hello World!";


9: private function add():void {

10: labelValue += "!";

11: }

12: ]]>

13: </mx:Script>

14: <mx:Label id="myLabel" text="{labelValue}"/>

15: <mx:Button label="Add a !" click="add()"/>

16: </mx:Application>

The Bindable metadata on the labelValue variable marks it as a source of data binding. Next, I used the “{}” for the text attribute of the Label to mark this property as the destination of the binding. Having the binding in place, anytime the variable labelValue is changed, the label updates its view to reflect the change. I could use the same variable for many labels or text inputs, and all of them would be updated to reflect the new value.

There is also an MXML syntax: <mx:Binding source=”labelValue” destination=”myLabel.text”/>.

If you want to bind the data to an editable control (for example, a text input) and copy the value back to the source, in Flex 4 you can do bidirectional binding using the “@” operator:

   1: <s:TextInput id="txt" text="@{labelValue}"/>

And if you want to use the Binding tag, you set the attribute twoWay to true (again this is possible only in Flex 4):

   1: <mx:Binding source="labelValue" destination="myTextBox.text" twoWay="true"/>

In order to implement data binding, Flex adds glue code at compile time (remember data binding is not a feature of Flash Player or AS3), and the beauty of this is that you don’t have to write this code yourself.

Although data binding offers a straightforward way to bind a data model to a view, there will be a performance hit if you have a bunch of bindings for variables that get updated tens or hundreds times a second. For such variables there is no need to update the user interface that frequently, because there is a limit on frames per second imposed by the browser itself (somewhere around 50 frames per second). As a result it is pretty pointless to try to display hundreds of changes per second in real time.
Another thing to keep in mind is that not all objects are bindable. For example Object and Array are not bindable, you should use ObjectProxie and ArrayCollection. When you create classes to model the data, if you wish all the members of the class to be bindable, you can place the Bindable metadata at the class level, instead of adding for each property:

   1: package org.corlan {


3: [Bindable]

4: public class VOAuthor {


6: public var id_aut:int;

7: public var fname_aut:String;

8: public var lname_aut:String;

9: }

10: }

Now, let’s move to metadata tags (sometimes called annotations). You’ve already seen metadata tags in the form of Bindable metadata tag. For a complete list of metadata tags that you can use with Flex, click here. In some cases, metadata tags are used by the MXML compiler in order to generate the glue code (as in the case of Bindable), in other cases you can use metadata tags to give a hint to the Flash Builder IDE or to create properties on the MXML tag. This is the case of Event metadata. For example, suppose I write a class that throws an event when a movie is loaded. I can use the Event metadata tag to declare the type of the event and the name. By doing so, I can use the movieLoadedEvent property on the MovieLoader MXML tag to register the event listener for this event. Let’s see the code of the class and how you can use the class in MXML.

   1: //class definition

2: package org.corlan {

3: import flash.events.EventDispatcher;

4: import flash.events.IEventDispatcher;


6: [Event(name="movieLoadedEvent", type="flash.events.Event")]


8: public class MovieLoader extends EventDispatcher {


10: public function MovieLoader(target:IEventDispatcher=null) {

11: super(target);

12: }


14: }

15: }
   1: <?xml version="1.0" encoding="utf-8"?>

2: <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"

3: xmlns:local="org.corlan.*" layout="horizontal">

4: <mx:Script>

5: <![CDATA[

6: private function movieLoadedListener(event:Event):void {

7: //do something with it

8: }

9: ]]>

10: </mx:Script>


12: <local:MovieLoader id="loader" movieLoadedEvent="movieLoadedListener(event)"/>

13: </mx:Application>

There are other interesting things you can do with metadata. If you set a flag on the compiler (keep-as3-metadata followed by the tag’s names), you can add your custom metadata tags and the compiler will put the tags in the bytecode. You can then use these tags at runtime. For example, in this post, you can read how you use custom metadata tags to provide a way to persist a given data model in an AIR application (more about Adobe AIR a little bit later).

And this brings me to the last topic of this section: reflection. In order to use the custom metadata you have to rely on the AS3 reflection API.

In PHP there is a complete object-oriented reflection API: Reflection, ReflectionFunction, ReflectionParameter, ReflectionMethod, and so on. Here is an example using the Reflection class on a simple PHP class:

   1: class SimpleClass {


3: public $public = 'Public';

4: protected $protected = 'Protected';

5: private $private = 'Private';


7: private function SimpleClass() {

8: echo('SimpleClass() called');

9: }


11: private function __construct() {


13: }


15: function displayVar() {

16: echo "SimpleClass class\n";

17: }

18: }



21: Reflection::export(new ReflectionClass('SimpleClass')); //this outputs:


23: Class [ <user> class SimpleClass ] {

24: @@ /Applications/MAMP/htdocs/_learning/classes.php 7-26


26: - Constants [0] {

27: }


29: - Static properties [0] {

30: }


32: - Static methods [0] {

33: }


35: - Properties [3] {

36: Property [ <default> public $public ]

37: Property [ <default> protected $protected ]

38: Property [ <default> private $private ]

39: }


41: - Methods [3] {

42: Method [ <user> private method SimpleClass ] {

43: @@ /Applications/MAMP/htdocs/_learning/classes.php 13 - 15

44: }


46: Method [ <user, ctor> private method __construct ] {

47: @@ /Applications/MAMP/htdocs/_learning/classes.php 17 - 19

48: }


50: Method [ <user> public method displayVar ] {

51: @@ /Applications/MAMP/htdocs/_learning/classes.php 22 - 25

52: }

53: }

54: }


AS3 there are three functions in the flash.utils package that can be used for reflection: describeType(), getDefintionByNameI(), and getQualifiedSuperClassName(). Here is an example of the output of describeType() (the output is an XML object):

   1: public class SimpleClass {


3: public var _public:String = "Public";

4: protected var _protected:String = "Protected";

5: private var _private:String = "Private";


7: function SimpleClass() {

8: trace("SimpleClass() called");

9: }


11: public function displayVar():void

12: {

13: trace("SimpleClass class");

14: }

15: }


17: function reflect():void {

18: var s:SimpleClass = new SimpleClass();

19: var description:XML = describeType(s);

20: trace(description);

21: }


23: //the output:

24: <type name="org.corlan::SimpleClass" base="Object" isDynamic="false" isFinal="false" isStatic="false">

25: <extendsClass type="Object"/>

26: <method name="displayVar" declaredBy="org.corlan::SimpleClass" returnType="void"/>

27: <variable name="_public" type="String"/>

28: </type>

Where are my data? Bring it on!

As a PHP developer, you have a very direct way to read data, parse them, and display them on the screen. Connecting to a MySQL database is one of the first things any PHP developer learns. In fact, I highly doubt that you managed to read this whole article to this point without peeking at this section. :D

What about Flex? I have to disappoint you, because you don’t have direct access to data stored in a database. But there is something good in this, I guess, because you can continue to write PHP files to read/write data to your database, even when writing Flex applications :) . Why is there no direct way of reading data from a database? Because of the old saying “You should never trust the client!” Suppose  the client is a Flex component that knows how to connect to the MySQL server. How do you store the credentials so that it wouldn’t be easy to steal them and have the database compromised? Set a different user/password for each user and give them this information? This is just one of the reasons why it is not a good idea to have a client technology that can connect directly to a database server, without using an application server in the middle.

Basically, in Flex applications you rely on server-side scripts to manage the databases. Flex offers you a way to call the server pages and get back the answer in Flex. There are three different ways to connect to a server data source: REST style services, web services, and Remoting (or RPC).


You can use the HTTPService class to use REST style services. You can send POST variables when you do a request, and the response can be XML, JSON (there is a third-party library for parsing JSON), or custom formatting.

If you have web services on the server (SOAP/WSDL), you can use the WebService class.

But the most interesting method is remoting (using the RemoteObject class). There are three reasons why I think is the coolest method. First, using remoting you can leverage any PHP class you have on your server by calling any public method. Basically, from the Flex side you use an instance of RemoteObject as if it were the remote PHP class. Second, you can map the data model from the PHP side to an ActionScript data model, and have the conversion done automatically. This is extremely important, because when you use typed objects, you get the benefits of compile-time error checks and code completion. This means code that is easier to read and less prone to bugs. And third, the messaging format for this method,  AMF3 (Action Message Format) is a binary format, which can be much faster and smaller compared to SOAP/XML/JSON, especially for big sets of data. The format itself is open, and anyone can read the white papers and implement programs that use it.

AMF3 is faster because it encodes data. For example if the same string is repeated in a data set, then it is encoded one time, and all other occurrences of the string are references. If a number is smaller than four bits, then only the minimum number of bytes required are used.

James Ward from Adobe has created a nice test that shows the differences between remoting and other methods.

Remoting is natively supported by Flex, however on the server side the story is not the same. PHP doesn’t support remoting and AMF3 natively. This is why you need a server side library to enable remoting for a PHP web server. There are four available libraries, all are free, and I wrote tutorials about how to use each of them: Zend AMF, PHPAMF, WebORB for PHP, SabreAMF. And here you can read a post that compares them.

Because native data type are converted automatically (PHP type to a AS3 type and vice-versa), you have to pay attention how the native types from one language are converted to the other. Here is an example for the correspondence of data types in the AMFPHP library.


User authentication in Flex and PHP projects

So how can user authentication be done in Flex and PHP projects? The answer is very simple, just as with PHP websites, you use a session and some way to validate the user/password.

Basically whenever a call is done from Flex, the session id is automatically appended. Thus, if the user was previously authenticated, the same session will be used.

More on this subject here.


Working on Flex and PHP projects

Fortunately, both PHP and Flex are mature technologies, thus and you have plenty of choices when it comes to tools. I will present some of them in this section.

Flex SDK and text editors

The first option you might consider is to use the free open source Flex SDK, especially if you love command-line tools and text editors like vi :) . You can write the code in your favorite text editor, and use the command-line tools to compile/debug the application.

Flex Builder / Flash Builder and Eclipse PDT / Zend Studio

I prefer to use a modern IDE. For Flex and PHP projects, probably the best combination is Flex Builder or Flash Builder 4 and Zend Studio. Flex Builder is the name of the Adobe’s Flex IDE up to the fourth version; the fourth version was renamed to Flash Builder 4. This IDE is Eclipse based, it is available for Windows and Mac OS, and it come as a plug-in version and a standalone version. For example if you have Zend Studio, you might consider the Flash Builder plug-in, and install this plug-in on top of Zend Studio. You can use Flex Builder 3 for 60 days (trial version), and Flash Builder 4 is in beta now (summer of 2009). If you are a teacher or student you can get a license for free.

If you prefer to work with Eclipse PDT, you can use the same approach: install the plug-in version of Flash Builder 4 or the other way around, install PDT on top of the Flash Builder standalone.

Flash Builder 4 offers wizards for working with PHP and Flex: it can introspect PHP code and generate AS3 and Flex code (here is tutorial on this matter). You can use it to debug, profile, compile, and launch the application (web or AIR). You can also export the application for release, and there is support for refactoring as well as a Design view and a states editor.

It also integrates with Flash Catalyst, so you can create the UI of the application in Flash Catalyst and then open the generated project in Flash Builder 4 and continue adding the business logic (you can watch this screen cast to see how you can create a vertical scrollbar using Adobe Illustrator, Flash Catalyst, and Flash Builder 4).

There are other IDEs (commercial products) for Flex: IntelliJ IDEA and FDT (Eclipse Based).

Debugging Flex applications

You can debug Flex code using the debugger from the Flex SDK, or the debugger from Flash Builder 4 (or Flex Builder 3). If you chose a combined set-up of Flash Builder 4 and Zend Studio, then you can debug the PHP and Flex code from the same project very easily. You make a call from Flex to PHP and you can enter the PHP debugger, then when the answer is back in Flex, and you enter the Flex debugger. Here and here are some videos on this topic, and here is a tutorial on Zend Studio and Flex Builder debugging.

In PHP one of the first approach I try when I have bugs is to use a combination of die() and var_dump() calls to see what is happening. In AS3 you can use trace() to output variables values to console. The cool thing is that when you compile the application for production, all the trace() statements are removed. This is an un-obstructively way to output information; you can also use Alert class to display messages in a pop-up window (more like JavaScript debugging before having FireBug).

The key element to keep in mind is: now, you have a client that it is separated from the server, and problems may be on the client, on the server, or at the network level.

You can read more on debugging Flex and PHP projects here.


What is Adobe AIR

Adobe AIR is a desktop runtime for RIAs that run as desktop applications on Windows, Mac, and Linux. With AIR, you can create a single application that can run on any of these operating systems. Examples of AIR applications: Tour de Flex, TweetDeck, Times Reader, Dojo Toolbox, and Sideline from Yahoo!.


You might think of Adobe AIR as a “Flash Player” for the desktop. However, Adobe AIR is more than just a modified Flash Player.

Inside of this runtime, there is an HTML engine (WebKit, the same engine used by Safari and Google Chrome) and a modified Flash Player engine. These two engines offer a set of APIs that give access to the machine on which an AIR application runs. There are APIs for writing/reading files on the disk, detecting network connectivity, detecting the number of connected displays and resolution, application updates, desktop notifications, local databases, drag and drop, and more.

As a web developer you can choose any combination of the following technologies: Flex, ActionScript 3, or HTML/CSS/JavaScript. That’s right; you can create an AIR application using only HTML, JavaScript, and CSS. Actually, the Dojo Toolbox and Sideline from Yahoo! are created using HTML/CSS/JS.

So with AIR you can leverage your existing skills to build a desktop application. But why would you want to create a web application that runs as a desktop app? Actually there are many reasons for this:

  • you want to be able to use the application, or parts of it, when you don’t have an Internet connection
  • you want to get rid of the browser chrome, and to fully customize the appearance of your application
  • you want to be able to integrate the application with other applications on the user’s computer (for example, to drag and drop files from the AIR app to desktop and vice-versa)
  • you want to be able to persist files on the user’s machine
  • you want to build a notification system, and you want to run the application minimized in system tray (for example, instant messengers can notify you when a new message is received, although they are minimized and not having the focus)

For developing AIR applications, you can use the free AIR SDK (you have command line tools for building, testing, and debugging), you can use Aptana Studio (if you want to create AIR apps using HTML/JS/CSS), or you can use Flash Builder 4 (or Flex Builder 3).

Finally, any Flex application that was created for the browser can be transformed into an AIR application in no time. Of course, if you stop here and you don’t make use of the specific AIR features, it doesn’t make sense because you haven’t provided any additional value.


What’s next?

Early next year Flex 4 will be released. Adobe has developed a new tool (it is still in beta) called Flash Catalyst that can be used to transform static designs created in Photoshop or Illustrator into functional Flex user interfaces. Imagine a tool that could take as input a Photoshop or Illustrator file, and output HTML/CSS/JavaScript code and retaining the look and feel of the input files. This is what Flash Catalyst is doing, only it outputs Flex 4 code and not HTML.

At the same time, we are focusing heavily on making the Flash Platform available on all screens: from computers to mobiles devices, from set-top boxes to TV sets. Now we have Flash Lite 3 available on mobiles (Nokia, Sony Ericsson, HTC, Android, Palm). Next year, we’ll release the mobile version of Flash Player 10. Also, it is very possible that next year we’ll see the first TV sets with support for Flash. How cool would it be to have user interface that takes advantage of all the Flash Player features, or to be able to watch high definition videos from the web (Flash has support for the  H-264 standard). Some analysts think that in the near future there will be more mobile phones connected to the Internet than computers, and many people will use their mobile devices as the primary means for accessing Internet content as they will not have a computer.

What does this mean for a web developer? It means that you can expand your area of expertise and what you offer from web sites to desktop RIAs (using Adobe AIR), and from computers to mobiles and other devices with screens. Of course, in order to do that, you need to brush up some of your skills, but the level of complexity is not even close to what it takes to become proficient with C or C++ for a given platform.


Where to go from here

I hope you found answers to some of your questions. If you are serious about entering the Flex world, here are some resources:

Tour de Flex

I view Tour de Flex as the Web 2.0 or RIA version of the beloved php_manual.chm. You can install it from here. It provides examples of how to use any component in Flex (you can see how it looks and the code used to implement it). There is also easy access to the Flex documentation. The application itself is created using Flex and Adobe AIR.



There are many books on Flex and ActionScript 3. However my personal favorites, and those I usually recommend are these:

  • First steps in Flex, by Bruce Eckel and James Ward (Technical Evangelist at Adobe); this book gives you an overview of how you can use Flex for developing web and desktop applications, and you can read it in one weekend.
  • Essential ActionScript 3 by Colin Moock; this is a thick book, and you have to be an excellent reader to cover the book in one weekend. Although it doesn’t cover Flex, you can learn almost everything about ActionScript 3.



There are hundreds of websites and blogs covering Flex and ActionScript 3. It would be impossible to give you the complete list, but I will give you some of my favorites:

  • Adobe Developer Connection. A great place to read technical articles about Flash, Flex, and AIR. It is updated weekly. There is a section dedicated to Flex and PHP.
  • Adobe TV. This site gives you access to tons of videos with presentations from conferences and video tutorials.
  • Gotoandlearn.com. An excellent collection of video tutorials by fellow evangelist Lee Brimelow.
  • Flex documentation. Keep in mind that you can download a ZIP file of this documentation. You can find here resources in various formats.
  • Adobe Groups. A free platform where you can find Adobe User Groups (including Flex or Flash groups). Have a look, there might be a Flex User Group in your area, and usually they organize meetings monthly. There are forums under this platform, and they support localization, so there is content not only in English.
  • My blogroll. Check it out; most of them are people from Adobe who write about Flash and Flex.
  • Have a look at the list I maintain on frameworks, libraries, and other Flex-related resources.

And now, I think, you can understand why when a developer asks me what Flex is, I stare blankly for a while. During this time, all the thousands of words I wrote here pass in front of my eyes…there is so much to talk about, what the heck could I possibly say in one line!? Hopefully, now I can just answer “Flex is awesome, dude! Check this article. :) ”.

If you have comments, please take your time to leave one on this page. Thanks!



Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}