php

  • submit to reddit

Getting Started with Drupal

By Matt Vance

14,175 Downloads · Refcard 59 of 151 (see them all)

Download
FREE PDF


The Essential Drupal Cheat Sheet

Drupal is an open source content management system and framework written in PHP. Drupal is used to power many of today’s high-profile sites, such as Popular Science, Ubuntu and the Electronic Frontier Foundation. This DZone Refcard will provide useful information to help you perform three of the most common roles associated with setting up a new Drupal site: site building, theming, and development. Youll also enjoy these other related Refcardz from our DZone Refcardz library: Essential MySQL and PHP.
HTML Preview
Getting Started with Drupal

Getting Started with Drupal

By Matt Vance

about drupal

Drupal is an open source content management system and content management framework written in PHP. Drupal is used to power a variety of high-profile web sites, including sites for Popular Science (http://www.popsci.com/), Ubuntu (http://www.ubuntu.com/), and the Electronic Frontier Foundation (http://www.eff.org/).

Drupal is designed to be modular, with a number of optional modules included in the default “core” Drupal package. These modules serve to extend and enhance the capabilities of Drupal core. In addition, thousands of contributed modules are available for download from the central Drupal community website, Drupal.org.

Drupal is most often run on a LAMP server stack (an acronym for Linux, Apache, MySQL, and PHP). However, Drupal is not limited to a single architecture and can be run under Apple’s OS X or Microsoft Windows. Alternative web servers supported by Drupal include Microsoft IIS and lighttpd. In addition to MySQL, Drupal can also be run using PostgreSQL for database storage.

Hot Tip

For a more thorough PHP reference, see the PHP Refcard (http://refcardz.dzone.com/refcardz/php). Drupal also includes the open source jQuery JavaScript library to simplify the creation of dynamic behavior within a user’s browser. For help using jQuery, check out the jQuery Selectors Refcard. (http://refcardz.dzone.com/refcardz/jquery-selectors).

This Drupal Refcard will provide useful information to help you perform three of the common roles associated with setting up a new Drupal site: site building, theming, and development. This Refcard focuses on Drupal 6, the latest major release available as of this writing.

Drupal site building

Drupal can be used to create just about any type of website, from simple single-author blogs to multi-user social networking communities. Along with Drupal’s flexibility comes a steep learning curve. First time site builders can quickly become overwhelmed by the thousands of available contributed modules.

While the Drupal community strives to work together to create user friendly modules that combine together well, not all modules are created equal. Since developers can’t be expected to test their modules in combination with every other available module, there are bound to be incompatibilities. It is important, especially for first time site builders, to evaluate modules on a test site before installing them on a production site.

Not all Drupal modules are ready for prime time, but some modules have been around long enough and are useful for enough applications to warrant being on a site builder’s short list.

Hot Tip

Sign up for an account on Drupal.org. Some areas and tools on the site are only available to logged in users, plus it is an important first step toward getting involved in the “community” that develops, supports, and steers the Drupal project. Get involved on the forums; both asking and answering questions can help you get up-to-speed more quickly.

CCK

The Content Construction Kit module, also known as CCK (http://drupal.org/project/cck), allows site builders to extend beyond the default content types that are included with Drupal. Not only can the default page and story content types (sometimes called “node” types) be rearranged or customized with additional fields, but completely new content types can also be created. CCK includes several sub-modules for adding a variety of custom field types such as select boxes, check boxes, text boxes, and more. In addition, other contributed modules, such as Date (http://drupal.org/project/date), FileField (http://drupal.org/project/filefield), and ImageField

refcardzad

(http://drupal.org/project/imagefield), can be downloaded separately to add more complex fields to your custom content types.

Views

The Views module (http://drupal.org/project/views) allows site builders a great deal of control and flexibility in presenting lists of content, also called “views”, on a site. The Views module provides a graphical user interface that can output nodes, users, comments, and more. Views can be presented as pages, as RSS feeds, or “blocks” (the often small pieces of content that are typically reused on various pages in sidebars, headers, and footers). The individual items that make up a view can be customized in terms of sort order, fields displayed, and the format of the list (such as unordered lists or tables).

Views Module

The Views module interface can take some time to master, but it is worth the investment. The flexibility of Views can be useful not just to site builders but also to developers, since views can be exported and bundled with modules.

Add on modules such as the Views Bonus Pack (http://drupal.org/project/view_bonus) can extend the Views module even more to present content as CSV files, Microsoft Word DOC files, or as XML.

Hot Tip

When installing new contributed modules and themes, resist the temptation to place the files in the default /modules or /themes directories. To make future upgrades of Drupal easier, create a /sites/all/ modules and /sites/all/themes directory instead. Contributed and custom modules and themes should then be placed in their own respective subdirectories.

Administration menu

The Administration Menu module (http://drupal.org/project/admin_menu) provides administrators with a small drop-down menu at the top of every page to allow easy access to the various administration pages that must be configured when building a new Drupal site.

Pathauto

The Pathauto module (http://drupal.org/project/pathauto) extends Drupal’s core Path module by automating the process of creating more user friendly and search engine friendly URL aliases for a site’s content. Pathauto requires and works in conjunction with the Token module (http://drupal.org/project/token).

Wysiwyg API

Drupal does not include a WYSIWIG editor by default; however, a wide variety of WYSIWYG and other client-side editors can be made to work with Drupal. The WYSIWYG API module (http://drupal.org/project/wysiwyg) provides Drupal integration for a variety of add-on editors, including: TinyMCE, FCKeditor, the YUI Rich Text Editor. Other modules provide support for individual editors, but it is likely that more will opt to integrate with the WYSIWYG API module going forward, in order to avoid duplicating development effort.

Hot Tip

With thousands of contributed modules, there is inevitably overlap in the functionality provided by some modules. Rather than installing each overlapping module to compare functionality, first check the “Comparisons of contributed modules” section of the Drupal handbooks (http://drupal.org/node/266179) to see if someone else has already documented their comparison. Example comparisons include WYSIWYG modules, node access modules, and content rotator modules.

Drupal theming

Drupal provides a flexible theming layer to allow a site’s design to be highly customized. While Drupal can be used in conjunction with a variety of “theme engines” such as Smarty or PHPTAL, most users will want to become familiar with Drupal’s default theme engine format, PHPTemplate.

Depending on the needs of your site, you may choose to create a completely custom theme or use one of Drupal’s “starter themes” as the basis for a new site design. Starter themes such as Zen, Blueprint, or Framework strive to provide a basic foundation that can be customized to provide the look and feel your site requires.

To create your own custom theme from scratch, start by creating a new directory for the theme under the /sites/all/ themes directory. For example, to create a new theme called “Beautiful”, start by creating a new /sites/all/themes/beautiful directory.

Hot Tip

Drupal’s default theme, Garland, was not designed to be a “starter theme.” When looking to transform an existing theme to match a specific design, avoid using Garland. Instead, start from scratch or look to themes such as Zen, Framework, or Basic. For a detailed comparison of starter themes, see http://adaptivethemes.com/starter-themecomparison. html

.info file

Typically a theme directory contains a number of files that work together to make up the theme. At the very least, a [themename] .info file is required in order for Drupal to recognize a theme. Building on the example above, a minimal beautiful.info file might start with the following:


name = Beautiful
description = A example theme created for educational purposes.
core = 6.x
engine = phptemplate

A number of optional keys such as regions, stylesheets, and scripts can also be defined in order to override the defaults Drupal provides. More details can be found in the Drupal handbooks(http://drupal.org/node/171205).

Drupal themes typically contain a number of template files such as page.tpl.php or node.tpl.php. Each template file specifies how a particular portion of the site is to be presented. The various core modules provide default template files that can be copied into your theme directory and edited to customize them to suit the needs of a particular site.

Template files (.tpl.php)

The base template file found in most themes is the page.tpl. php file which acts as a wrapper around most of the other template files. When building a new theme, the default page. tpl.php theme file found in the /modules/system directory can provide a good starting point. You can copy that file into your theme’s directory and customize it as needed.

Hot Tip

Drupal uses a theme registry to cache information about a theme. In order for Drupal to recognize changes to a theme such as adding files or changing the .info file, it is important to clear the theme registry. To clear the theme registry, go to the Performance page (Administer > Site configuration > Performance) and click on the “Clear cached data” button.

Additional template files can be used to customize the presentation of the various smaller elements of a Drupal site such as blocks, comments, polls, and more.

Template file Purpose
page.tpl.php the main container template file, which acts as a wrapper for the other template files below; see the following page for a list of available variables within the page.tpl.php file: http://api.drupal.org/api/file/modules/system/page.tpl.php
page-front.tpl.php can be used to specify a custom front page
node.tpl.php controls how the various content types or “nodes” are displayed; see the following page for a list of available variables within the node.tpl.php file: http://api.drupal.org/api/file/modules/node/node.tpl.php/6
node-[nodetype].tpl.php optional template files used to target and customize nodes of a specific content type
block.tpl.php contains the code used to display reuseable “block” content that may appear in multiple places within a site
block-[region].tpl.php optional template files to customize how blocks in specific block “regions” will appear; regions are the areas specified in the theme’s .info file where blocks can be designated to appear (such as headers, sidebars, etc)
comment.tpl.php controls the formatting of user comments

Template files can be targeted to customize specific content of a site by naming the files according to specific “suggestions.” For example, to customize the front page of a site, create a copy of the page.tpl.php file named page-front.tpl.php and customize the new front page template as needed. See the Drupal handbooks (http://drupal.org/node/190815) for more details about the various core template files and how to use and customize the suggestion options.

Hot Tip

When creating your own theme from scratch, be sure to output the $closure variable, just before the closing tag in the page.tpl.php file. The $closure variable is easy to overlook, but it is important because it outputs some final markup, which may cause some modules to fail, if it is missing.

template.php

The template.php file is an optional file used as a container for conditional processing and overriding of theme functions. In addition to overriding theme output using the template file method outlined above, Drupal also allows theme functions (any function beginning with “theme_”) to be overridden inside the template.php file. Those more familiar with programming in PHP may prefer to use template functions to override Drupal’s defaults in order to gain more flexibility and performance. A list of Drupal’s default theme functions can be found on the Drupal API site
(http://drupal.org/api/group/themeable).

Hot Tip

For help tracking down the particular function that controls the content you want to customize, install the Devel module (http://drupal.org/project/devel) and enable the Theme developer module that comes with it. The Theme developer module provides a graphical tool that can be used to select specific portions of a page and display the theme function or template file responsible for generating it.

style.css

Drupal will automatically recognize a style.css file as a theme’s primary cascading style sheet file. Additional CSS files can be specified in the .info file using the “stylesheets” key.

screenshot.png

The screenshot.png file is a thumbnail sized image of the theme presented on Drupal’s theme administration page to provide users with a preview of how a theme will look.

Drupal development

Drupal has a reputation as being created by developers for developers. While it has made great strides recently at becoming more user friendly, Drupal still has a lot to offer developers. Drupal has been designed with flexibility in mind. Developers can customize the vast majority of Drupal’s functionality through Drupal’s system of hook functions.

Novice users should not be dissuaded from creating their own custom modules. Even a simple single-function module can be useful for things such as customizing how Drupal presents a particular piece of content or form.

Hot Tip

Resist the temptation to modify the core of Drupal. “Hacking core” is discouraged, in favor of creating modules that modify Drupal’s behavior instead. Creating modules avoids having to maintain and apply patches to Drupal as updates get released
.

To develop a new custom module, start by creating a new directory for the module under the /sites/all/modules directory. For example, to create a new module called “Functional”, start by creating a new /sites/all/modules/functional directory.

Hot Tip

Before sitting down to develop a new custom module, take the time to browse or search the contributed modules available on Drupal.org. The thousands of modules available there are typically developed to be reusable in a variety of environments. You may not find a module that does exactly what you are looking for, you may find one that can be adapted to suit your needs. If you make improvements to an existing module, consider contributing your code back in the module’s issue queue, in the form of a patch. In addition to helping others, if the patch gets accepted, it will make future upgrades of the module on your own site easier.

.info file

As with themes, each Drupal module must include at least a .info file in order to be recognized. An example functional.info file might consist of the following:


; $Id$
name = Functional module
description = “A simple example module created for educational
purposes.”
core = 6.x

See the Drupal handbooks (http://drupal.org/node/231036) for details on the other keys that can be specified in the module’s .info file.

Once the .info file has been created, a module can be enabled on the Module administration page (Site building > Modules). However, until the .module file has been created, the module won’t provide any new functionality.

.module file

The .module file typically contains the majority of the code for a module. Modules interact with the core of Drupal by implementing various hook functions that get called as Drupal carries out various tasks. Certain specific hook functions will need to be implemented depending on what functionality or customization a particular module needs to provide. A list of available hook functions can be found on the Drupal API Reference site (http://api.drupal.org/api/group/hooks).

For our example functional.module file, we will implement the hook_nodeapi function. By implementing hook_nodeapi, a module can act on the node object used as a container for the majority of content within Drupal.

To implement a particular hook function within a module, replace the word hook within the functions name with the name of the module. For example, in a module called functional, the hook_nodeapi function is implemented as functional_nodeapi:


<?php
  function functional_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
   switch ($op) {
    case ‘view’:
     $node->content[‘body’][‘#value’] .= “<br><br>Brought to you
by RefCardz”;
     break;
  }
}

Once the “functional” module is enabled, all nodes within the site will appear with a “Brought to you by RefCardz” notice at the bottom.

Hot Tip

To quickly dump variables to the screen for debugging purposes, you can take advantage of the message area typically found at the top of the page in most themes, by using the following function: drupal_set_message(‘<pre>’ . print_r($variable, TRUE) . ‘</pre>’);
If you have the Devel module enabled, you can take advantage of more cleanly formatted output by using the following instead: dpm($variable);

By implementing hook_form_alter, modules can use Drupal’s Form API to add, remove, or change forms. For example, some sites use the Views module or Panels module to customize the site’s front page, so the “Promoted to front page” publishing option may need to be removed to avoid confusion. The following code will remove the checkbox used to promote content to the front page.


function functional_form_alter(&$form, $form_state, $form_id) {
  if ($form_id == ‘page_node_form’) {
    unset($form[‘options’][‘promote’]);
  }
}

For a more detailed introduction to the Forms API, see the “Forms API Quickstart Guide” (http://api.drupal.org/api/file/ developer/topics/forums_api.html)

Useful Hook Functions (for a complete listing of hook functions, see
http://api.drupal.org/api/group/hooks/)
Description
hook_block
http://api.drupal.org/api/function/hook_block/
Declare a block or set of blocks
hook_cron
http://api.drupal.org/api/function/hook_cron/
Perform periodic actions
hook_db_rewrite_sql
http://api.drupal.org/api/function/hook_db_rewrite_sql/
Rewrite database queries, usually for access control
hook_enable
http://api.drupal.org/api/function/hook_enable/
Perform necessary actions after module is enabled
hook_form_alter
http://api.drupal.org/api/function/hook_form_alter/
Perform alterations before a form is rendered
hook_mail_alter
http://api.drupal.org/api/function/hook_mail_alter/
Alter any aspect of the emails sent by Drupal
hook_mail
http://api.drupal.org/api/function/hook_mail/
Prepare an email message based on parameters
hook_menu
http://api.drupal.org/api/function/hook_menu/
Define menu items and page callbacks
hook_perm
http://api.drupal.org/api/function/hook_perm/
Define user permissions
hook_user
http://api.drupal.org/api/function/hook_user/
Act on user account actions
hook_watchdog
http://api.drupal.org/api/function/hook_watchdog/
Log an event message

.install file

Another file commonly found in Drupal modules is the .install file. The .install file is used to store code that is run when a module is installed or uninstalled, such as the hook_schema and hook_install functions.

Common .install File Functions Description
hook_install
http://api.drupal.org/api/function/hook_install/
Install the current version of the database schema, and any other setup tasks.
hook_schema
http://api.drupal.org/api/function/hook_schema/
Define the current version of the atabase schema.
hook_uninstall
http://api.drupal.org/api/function/hook_uninstall
Remove any tables or variables that the module sets.

Modules for developers

Modules for Developers

Several of the contributed modules for Drupal provide tools useful to module developers.

Deadwood

As new versions of Drupal get released, it can take a while for existing modules to get upgraded. The Deadwood module (http://drupal.org/project/deadwood) helps speed up the process of upgrading Drupal modules by automating some of the code updates.

Devel module

The Devel module (http://drupal.org/project/devel) provides tools for clearing Drupal’s cache, for generating dummy content, for debugging access issues, for performance logging, and much more.

Devel Mode

The Devel module also includes an open source debugging tool called Krumo that can display a structured representation of any PHP variable. Devel adds “Dev load” and “Dev render” tabs to nodes which output the Node object through Krumo. With Devel enabled, you can output your own variables through Krumo using Devel’s print message function, dpm().

Coder module

Since the Deadwood module doesn’t completely automate the process of upgrading modules from one version of Drupal to the next, there is usually some manual coding to be performed after running Deadwood. That is where the Coder module (http://drupal.org/project/coder) comes in handy. The Coder module does not modify code, but it provides an automated code review that can pinpoint areas of code that need to be updated.

Coder Module

The Coder module can also help enforce coding standards by pinpointing sloppy coding and suggesting ways to clean it up. The Coder module can be especially helpful to run before contributing code back to the community at Drupal.org. Schema

The Schema module (http://drupal.org/project/schema)

provides tools for working with Drupal’s database Schema API. If you’ve already manually created the tables required by a module, the schema module can provide the corresponding schema data structure to be added to your module’s .install file, making it easier to replicate the same tables on another Drupal installation.

Cache Disable

Drupal’s caching system can be a source of confusion and productivity loss, if you are not careful. Rather than having to remember each of the various tasks that require the cache to be flushed, install and enable the Cache Disable module (http://drupal.org/project/cache_disable) when doing development on a new site. Just remember to turn the module off, once you have completed your development work.

API

The API module (http://drupal.org/project/api) is used to generate the hyperlinked documentation found at api.drupal. org. The same module can be used to provide a local version of Drupal’s API documentation. In addition to providing documentation on Drupal’s core modules, the API module can also generate documentation pages for installed modules that follow Drupal’s coding standards. If you prefer not to set up your own API site, you can still browse the documentation for many of the contributed modules, courtesy of Drupal consulting company Lullabot (http://api.lullabot.com/)

Other API Modules

Though Drupal does provide a full-fledged development framework, it doesn’t include everything one might need for every possible coding task. Thankfully, the repository of contibuted modules on drupal.org includes quite a few API modules. Many of the API modules provide no functionality on their own, but provide API code that other modules and module developers can build on. Example API modules include the Voting API (http://drupal.org/project/feedapi), Chart API (http://drupal.org/project/chart), and the Import/ Export API (http://drupal.org/project/importexportapi).

Resources

URL Reference
http://api.drupal.org/ Documentation of Drupal’s API
http://drupal.org/handbooks The Drupal community maintains several handbooks including documentation for beginners, themers, and developers
http://drupalcodesearch.com/ Drupal Code Search allows users to search much of Drupal’s contributed code, though the index may not reflect the latest up-to-the-minute changes
http://cvs.drupal.org/ A web interface to browse the code in the Drupal.org CVS repository, from the start of the project to the latest in contributed modules
http://drupalmodules.com/ Drupal Modules allows users to rate modules. Ratings can be handy when choosing modules to use on a site
http://drupal.org/planet Drupal Planet aggregates a number of blogs that post regularly about Drupal
http://groups.drupal.org/ Groups.Drupal is a gathering place for niche groups within the Drupal community. Try searching for a user group near you or a group focused on your specific area of interest
http://drupal.org/irc Learn how to connect to Drupals IRC channels and connect with a world-wide community of developers at all hours of the day
http://drupal.org/mailing-list Drupal.org provides a number of mailing lists to keep the community up-to-date. Anyone running a public Drupal site should subscribe to the security announcements mailing list
http://association.drupal.org/ The Drupal Association is a not-for-profit association charged with providing support to the Drupal project
http://drupal.org/getting-involved The Drupal project thrives largely due to a strong community of contributors. Read the “Getting Involved” handbook to learn how you too can contribute
http://ww.lullabot.com/podcast Several Drupal podcasts exist, both in audio and video formats, but the Lullabot podcasts are longest-running and arguably the most in-depth

About The Author

Photo of Matt Vance

Matt Vance

is a Web developer, technology consultant, and freelance writer living in Austin, Texas. He has written for Macworld magazine and Lifehacker.com. He can be contacted through his website, http://minezone.org/

Recommended Book

Drupal

Newcomers will find a thorough introduction to the framework, while experienced Drupal developers will learn best practices for building powerful websites. With Using Drupal, you’ll find concrete and creative solutions for developing the exact community website you have in mind.


Share this Refcard with
your friends & followers...

DZone greatly appreciates your support.


Your download should begin immediately.
If it doesn't, click here.

Daily Dose: Amazon Reveals New In-Memory Caching System "ElastiCache"

Amazon's new ElastiCache web service provides a fast, managed, in-memory caching system that is "protocol compliant with MemCached". The new service improves web application performance by using it's in-memory caching system, instead of...

0 replies - 14599 views - 08/23/11 by Ross Jernigan in Daily Dose

Flash Builder 4.5 for PHP

Adobe/Zend Tools for the PHP Professional

By Marco Tabini

3,229 Downloads · Refcard 96 of 151 (see them all)

Download
FREE PDF


The Essential Flash Builder 4.5 for PHP: Adobe/Zend Tools for the PHP Professional Cheat Sheet

"Flash Builder 4.5 for PHP, Adobe/Zend Tools for the PHP Professional is a DZone Refcard that covers tools used by professional web developers to develop applications with slick, Flex UIs and powerful, battle-tested backends coded in PHP. Adobes new Eclipse-based IDE, Flash Builder 4.5 for PHP, was co-developed by Adobe and Zend Technologies. Its one of the more interesting cross-platform integrations in a long time. This Refcard will show you how to profit from this marriage of tools created by the leaders in the RIA and PHP development arenas."
HTML Preview
Getting Started With Integrating PHP and Flex

Adobe® Flash® BuilderTM 4.5 for PHP: Adobe/Zend Tools for the PHP Professional

By Marco Tabini

WHAT IS FLEX?

Flex is an open-source framework developed and distributed by Adobe Systems. It is based on the Adobe® Flash Platform and primarily provides a streamlined approach to the development of Rich Internet Applications.

Flex eliminates many of the designer-oriented features of Flash in favor of establishing a development environment that caters more to programmers. As such, you will find that Flex encompasses many of the concepts that you are already familiar with if you have developed front-end systems using JavaScript or, indeed, most other GUI programming environment, allowing you to take advantage of the underlying Flash infrastructure without having to worry about concepts like timelines, assets, and so on.

Flex is multi-platform—this means that, with some exceptions, you can run a Flex application on any platform that supports Adobe Flash Player. If your users run on Windows, OS X or Linux and their browsers have a recent version of the Flash Player plug-in installed, they will also be able to run your Flex applications without a problem.

Because Flex is open source, there is no cost associated with creating and distribution applications that are based on it.

Hot Tip

You can download Adobe Flex SDK for free directly from the Adobe website at http://www.adobe.com/products/flex/

What is Adobe AIR?

The Adobe Integrated Runtime (Adobe AIR) is a companion technology to the Flex framework that extends the functionality provided by the latter into desktop application development. With AIR, you can build Flex applications that can be deployed as native applications on your user's machines, thus gaining all the advantages of running in a desktop environment.

Like Flex, AIR is also cross-platform, which means that you can write your code once and immediately deploy it across multiple operating systems. Because they run natively rather than in a web browser, AIR applications also gain access to functionality that is usually restricted by the Flash Player's security model, such as local file manipulation, unrestricted access to the network, and so forth.

What is Adobe Flash Builder?

Flash Builder 4 is Adobe's IDE for developing Flex and AIR applications. Although Flash Builder 4 is not required in order to compile or run a Flex-based application, it significantly simplifies the process of Flex development by providing an integrated environment that includes code intelligence, real-time analysis, compilation support, live debugging and much more.

Flash Builder 4 is based on the open-source Eclipse IDE and can either be downloaded as a standalone product or as a plug-in for the latter. Like Eclipse, Flash Builder 4 is also crossplatform and runs on both Windows and OS X.

Hot Tip

You can download a 60-day trial of Flash Builder 4 from the Adobe website at http://www.adobe.com/products/flex/

BUILDING APPLICATIONS WITH FLASH® BUILDER™ 4 AND PHP

Even though Flex is based on Flash, you don’t need to be proficient in the latter in order to use the former.

Flex uses a language called ActionScript3 (AS3), which is itself derived from the ECMAScript standard. ECMAScript is the same basic definition on which JavaScript is based—therefore, if you have any familiarity with browser programming, it's likely that you will find your bearings in AS3 very quickly.

Flex applications are based on the concept of component. A component defines a container of behaviors and, optionally, of a user interface representation. Components can be visual or non-visual, depending on whether the provide an interface of some kind (like a button) or just functionality of some kind (like a library for connecting to a remote server).

The visual structure of a component can be easily defined using MXML, Adobe’s specialized brand of XML. Other than the use of specific namespaces, MXML is nothing more than well-formed XML code; by nesting multiple components, you can create complex GUIs without ever writing a line of code.

Creating Flex Applications

Flash® Builder 4 makes creating new applications as easy as following the steps of its New Application Wizard. Simple select New Flex® Project from the File menu, then choose a name and type for your application. If you intend to write code that will be executed inside a browser, choose "Web" for your application type; if, on the other hand, you want to build a desktop application, choose "Desktop" instead.

You newly-created Flex project will contain a component that represents the application's main entry point:


<?xml version="1.0" encoding="utf-8"?>
<s:Application
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx">
<fx:Declarations>
</fx:Declarations>
</s:Application>

From here on, you can add more components to your application simply by typing the MXML code that represents them in the appropriate order. However, Flash Builder 4's strength resides in its visual layout editor, which allows you to arrange and wire the different components that make up your user interface using a WYSIWYG approach. For example, you can add a DataGrid object to show the contents of a data structure and then a button to fetch the data–all enclosed in a VGroup object to provide the overall layout:

Flex’s powerful layout capabilities, like the rest of the framework, are also designed to be developer-friendly and are almost entirely based on standard CSS, with a few exceptions designed to make automated positioning easier.

Useful Flex Components

Flex provides a rich ecosystem of components that can be easily expanded to meet your needs. While many of its components are designed to closely mimic their HTML cousins, there are also a number that provide unique functionality. For example:

  • AdvancedDataGrid and DataGrid: display tabular data in a rich, editable environment.
  • DateChooser and DateField: simplify the process of choosing and formatting date values.
  • NumericStepper: allows the user to increment and decrement a numeric value.
  • RichEditableText: allows you to create a rich text editor with support for several formatting options (e.g.: italic, bold, etc.).
  • VideoDisplay/VideoPlayer: provide fully-featured and completely skinnable video players that can be embedded directly in your application.
  • HSlider/VSliders:allows the user to select a value by sliding a selector across a horizontal or vertical range.
  • HGroup/VGroup: automatically arrange their content horizontally or vertically. Combine to easily create complex layouts.
  • Accordion/TabNavigator: allow multiple content panels to stack and be displayed one at a time.
  • MenuBar/TabBar: add a menu or tab bar to your component.
  • Flex Charting: adds powerful charting abilities to your applications.

Hot Tip

While Flex Charting and AdvancedDataGrid were only available in the Professional version of Flex Builder 3, they are now included in all versions of Flash Builder 4.

Connecting to PHP with AMF Introspection

One of the most interesting features of Flex is that it is designed to provide powerful data connectivity capabilities in a variety of formats and protocols, including XML, SOAP, JSON and Adobe’s own AMF. In fact, in most cases you will be able to use Flash Builder 4 to connect your Flex application to a PHP backend without having to write a single line of code in either!

In order to use Flash Builder 4's PHP-aware functionality through AMF, you need to have direct access to the root directory of a copy of your site—either through a network share or on your local computer. To get started, select Connect to Data/Service… from the Data menu, then choose PHP from the list of available connectors. Flash Builder 4 will ask you to confirm that your project type is set to PHP, then specify both the location of your site's server root and its URL:

At this point, you can click "Validate Configuration" to make Flash Builder 4 run a simple test to determine whether it can access your site as expected, then OK to complete the set up process.

Now, Flash Builder 4 will ask you to choose a PHP class that will provide the entry point to which your Flex application will connect. If your code is not encapsulated in classes, you could create some simple stubs for the purpose of providing services to your Flash Builder 4 code. The wizard will automatically fill in the defaults for you based on the name of the PHP file that you select.

Hot Tip

In order for this system to work, it is important that the class you want to import be stored in a file of the same name [e.g.: Index inside index.php]. Otherwise, Zend_AMF will be unable to find it.

At this point, if you website does not include a copy of Zend_AMF, a Zend Framework module that Flash Builder 4 uses to marshal data, remote procedure calls and error management, you will be asked to download and install a copy. This is required because Flash Builder 4 makes use of Action Message Format (AMF), a protocol that PHP does not support by default.

Hot Tip

Your application does not need to use Zend Framework in order to take advantage of AMF—Flash Builder 4 will only use Zend_AMF in order to communicate with your server, independently of the rest of your code.

Flash Builder 4 will introspect your code and discover which methods the service makes available:

Once you click Finish, the wizard will create a series of classes inside your project that provide all the necessary functionality required to connect to your project and execute your web service.

Hot Tip

Remember that it is your responsibility to provide a security layer where required—for example, by passing a secure key to the service as appropriate.

Establishing Data Connections

Your application is now capable of connecting to the PHP backend, but the data that the latter provides is not yet wired to any of the controls.

Luckily, this, too, is something that can be done without writing a line of code. You can, instead, use the Data/Services panel, visible in the bottom tray of the Flash Builder 4 window, where all the remote data services defined in your application are visible:

All you need to do in order to connect the data returned by a service call to any of your components is to simply drag it from the Data/Services panel to the component. Flash Builder 4 will ask you whether you intend to create a new call, or use an existing one. In the former case, you will first need to specify the type of data returned by the remote service call, because the data connection wizard has no way of determining it by means of static analysis of your code.

Flash Builder 4 can, however, auto-detect the data type returned by a service call by making a call to it, or you can specify it by hand. Where a sample service call will have no adverse effects on your PHP backend, allowing the wizard to determine the return type automatically is usually sufficient and produces all the infrastructure required to handle the data on the Flex side.

Hot Tip

In order for your data to be used in a Flex application, it must conform to all the appropriate AS3 rules—for example, you cannont return objects with properties whose names are reserved AS3 keywords like protected or private, even if those are perfectly acceptable in PHP

Your Flex application now has access to all the data returned by your service. If, for example, you drag a service on to a DataGrid component, the latter will be automatically populated with all the appropriate data columns—all you need to do is remove those you don’t want displayed and rename the header of the others to the proper human-readable format:

Your application is now fully functional—if you execute it, you will see that the data service is automatically called as soon as the DataGrid object finishes loading. If the call is successful, the data is immediately loaded and displayed.

If you prefer to add a manual method of refreshing the information, you can simply drag the appropriate data call on to the button—this will create all the code needed so that, when the user clicks on it at runtime, the service will be called again and all the data automatically updated.

Differences between PHP and AS3 Data

While much of the data types are interchangeable between AS3 and PHP, there are some notable differences.

  • Integer values in PHP can either be 32- or 64-bit long, whereas, in AS3, they are always 64 bits. Therefore, you must be prepared for the fact that a numeric value passed from AS3 to PHP may be represented as a float even if it is, in fact, just a large integer.

  • String values in AS3 are always Unicode-compliant. It is up to you to ensure Unicode compliance on the PHP side.

  • Array values in AS3 can only have contiguous numeric keys starting at zero. If your PHP arrays have string keys or non-contiguous numeric keys, they will be represented as objects in AS3.

    You should avoid passing objects into AS3 that contain members whose keys are reserved keywords, as handling them will be inconvenient—and many of Flash Builder 4's facilities will refuse to work with them.

Under most circumstances, these issues are unlikely to affect your application because both AS3 and PHP have a significant amount of flexibility.

CONNECTING TO WEB SERVICES

SOAP

AMF is not your only choice when it comes to external connectivity from Flash Builder 4—almost exactly the same functionality can just as easily be used to connect to an XML web service powered by SOAP.

You can start the process by selecting Connect To Data/ Service… from the Data menu and then choosing WSDL as the service type. This will bring up a dialog box that asks you to provide the URL of the service's WSDL specification:

Like before, Flash Builder 4 will fetch the WSDL file from the server and introspect it, extracting all the available remote procedure calls. You will then be able to drag and drop the data into your application like before.

Accessing XML Services

Of course, SOAP is not the only way of retrieving XML data from a remote location. Flash Builder 4 provides facilities for introspecting a remote URL that simply returns a flat XML document and extracting information from it.

Once again, you will need to click on Connect To Data/ Service… from the Data menu and, this time, choose XML as the service type. Flash Builder 4 will ask you to provide the URL of the service you wish to access, invoke it and create a stub class in AS3 to encapsulate the data:

The resulting data provider will become available in the Data/ Services panel of Flash Builder 4's GUI, from where you can connect it to your components like before.

Hot Tip

Be mindful of the fact that, when manipulation raw XML, Flash Builder 4 has no way of determining whether your service provides data in a consistent format. Therefore, you should ensure that this is the case, or your service call may unexpectedly fail at runtime.

JSON and XML

JSON (JavaScript Object Notation) has rapidly become a very popular choice for web service development because of its simplicity, lightweight format and ease of use in a number of languages.

While PHP has had built-in support for JSON since version 5.2.0, AS3 does not have any facilities for manipulating JSON data. Luckily, Flex provides a number of different ways for using JSON.

To start, you will need a PHP script that takes zero or more parameters either through a GET or POST HTTP transaction and outputs JSON-formatted data. For example:


<?php
function getTimeline($user) {
	$data = json_decode(
		file_get_contents("
			http://api.twitter.com/1/statuses/user_timeline.
			json?screen_name=" . urlencode($user)));
	
	foreach($data as $v) {
		unset($v->user->protected);
	}
	return $data;
}
echo json_encode(getTimeline($_GET['user']));

The simplest way of connecting to this service consists of once again using the Data/Service Connector wizard to access arbitrary HTTP-based web services. Choosing "HTTP" from the Connect To Data/Service… menu will result in this dialog, where Flash Builder 4 asks for the URL of the service and its parameters:

Once you provide the correct information and click on Finish, the wizard will once again create all the infrastructure required to run your service and make it available as before. The HTTP Data/Service Connection wizard also supports XML data.

DEPLOYING YOUR APPLICATION

In most cases, you will want to develop your application in Debug mode. This causes the Flex compiler to add all sorts of useful information that can be used to debugger to help you address any issues that may occur within your application.

However, when it comes time to deploy your application for production, you will want to switch to a Release build so that you can end up with the most compact and efficient codebase possible. You can do so by selecting Export Release Build... from the Build menu.

Exporting a Release build causes a new directory, called binrelease, which contains a number of different files:

Most of these files play a support role to your application—in fact, the only one you will normally interact with is the host HTML file that contains the code required to display your application.

Hot Tip

You can change the template used to generate your host HTML file by editing the html-template/index.template. html file in your application's root directory.

Passing Data to Your Flex Application

It is sometimes useful to pass data, like request parameters, to your Flex application as it is being initialized on the client browser.

This can be accomplished by introducing a special parameter in the HTML code that causes the application to be embedded in the web page. In reality, Flex provides a series of convenient wrappers that make the job even easier; if you look inside your HTML template, you will find a portion of code that looks like:


var flashvars = {};
...
swfobject.embedSWF(
		"Fle.swf", "flashContent",
		"100%", "100%",
		swfVersionStr, xiSwfUrlStr,
		flashvars, params, attributes);

All you need to do is change the content of flashVars to suit your need—that same data will be made available inside the application as the FlexGlobals.topLevelApplication.parameters object, where you can peruse it as needed.

Understanding the Security Model for Flash

When running in the browser, Flash employs a very strict security model that places your code in a sandbox through which all network and disk activities are regulated.

Hot Tip

For more information about the Flash security model, read the "Security" section under "Application architecture" in the Flash Builder help online at http//help.adobe.com/en_US/Flex/4.0/UsingSDK/

The sandbox is turned off during debugging—therefore, you don't normally become aware of it until you run your code in production mode and find out that your application cannot access any of its remote data.

Flash supports a number of different sandboxes, depending on what kind of data your application needs to deal with. Most of the time, you will want to use the local-with-networking sandbox, which allows your application to access remote locations, but denies all access to local files.

By default, the sandbox model prevents an application from accessing any resources outside of its own domain, unless that domain specifically grants access with a crossdomain.xml file. Therefore, it is important to remember that you may not be able to access information across different domains.

Hot Tip

Adobe AIR applications usually run in the local-trusted sandbox and, therefore, are not subject to connectivity restrictions.

Documenting Your Code with ASDoc

While much of the functionality provided by Flex can be accessed without writing significant amounts of AS3 code, it is entirely possible to address extremely complex tasks entirely within the Flex runtime — systems as complex as encryption engines and image compression libraries have been built in pure AS3 and are used in production every day (in fact, the entire Flex framework itself is built in AS3 as well).

Through a featured called ASDoc, Flash Builder 4 allows you to write inline comments that can be used to document your entire codebase. The syntax used by ASDoc is very similar to the PHPDoc syntax that is commonly used to comment PHP code; for example:


/**
* Performs some important function
*
* @param event The event dispatched to this method
*/
protected function handler(event:FlexEvent):void
{
	// Do something
}

Flash Builder 4 will automatically scan your code and add any information you write as part of your ASDoc blocks to its code intelligence features; these, in turn, will display the information as you use your code, providing you with a handy dynamic reference for your classes and methods:

About The Author

Marco Tabini

Marco Tabini is the co-founder, with Arbi Arzoumani, of php|architect, the world's largest PHP magazine in the English language, currently distributed in over 145 countries. He is also the co-founder, with Keith Casey, of Blue Parabola, LLC, a consulting firm that specializes in information architecture, code and security auditing, large-scale deployments and optimization.

An accomplished author on the subject of PHP and the business of web development, Marco is also a frequent speaker at PHP and OSS conferences throughout the world.

Recommended Book

Flash Builder 4 and Flex 4

Create desktop applications that behave identically on Windows, Mac OS X, and Linux with Adobe's new Flash Builder 4 platform and this in-depth guide. The book's tutorials and explanations walk you step-by-step through Flash Builder’s new, faster tools; the new framework for generating code; how to connect to popular application servers; upgrading from Flex 3; and much more.


Share this Refcard with
your friends & followers...

DZone greatly appreciates your support.


Your download should begin immediately.
If it doesn't, click here.

Daily Dose: NetBeans 7.0 Has Java 7 Support

Oracle's newly released NetBeans 7.0 features support for Java 7 features.  The JDK 7 component of NetBeans 7.0 is technically an early access snapshot.  A NetBeans 7.0.1 release in October will feature the final version of JDK 7.  Even developers who...

2 replies - 25500 views - 04/20/11 by Katie Mckinsey in Daily Dose

Daily Dose: Introducing Drizzle: A New, Lightweight Version of MySQL

Drizzle is the latest lightweight fork originating from Oracle's MySQL database.  The Drizzle development team has eliminated all of the features they considered non-essential, leaving behind a leaner, faster version of MySQL.  Users will enjoy the reduced...

2 replies - 19897 views - 03/17/11 by Katie Mckinsey in Daily Dose

PHPUnit

PHP Test-Driven Development - Automated Tools to Improve Your PHP Code Quality

By Giorgio Sironi

8,624 Downloads · Refcard 124 of 151 (see them all)

Download
FREE PDF


The Essential PHPUnit Cheat Sheet

This PHPUnit: PHP Test-Driven Development cheat sheet will show you how to set up and automate your testing with ease and help you improve code quality. Tests are the first users of your code and extensively testing a web application is the only way to make sure that the code you have written really works. This DZone Refcard includes How to Write a Test, Assertions, Fixtures, Annotations, and much more. Youll learn the ins and outs of PHPUnit and along the way youll get useful nuggets of advice on how to perform proper unit testing, test-driven development, and basic test automation.
HTML Preview
PHPUnit: PHP Test-Driven Development Automated Tools to Improve Your PHP Code Quality

PHPUnit: PHP Test-Driven Development - Automated Tools to Improve Your PHP Code Quality

By Giorgio Sironi

HOW TO WRITE A TEST

Extensively testing a web application is the only way to make sure that the code you have written really works. Formal proofs of correctness are impossible or impractical to put together for the majority of computer programs. Therefore, actually running code in a sandbox under controlled conditions is the way to uncover bugs and drive the development of new features.

Of course, manual testing cannot be totally substituted by automated approaches, but automating a large part of an application’s tests leads to greater testing frequency, and quicker discovery of issues and regression.

Automated testing is based on the concept of test cases (classes in PHPUnit’s case) that compose a complete test suite. This suite, or a subset of it, can be run at will to check the production code correctness.

In this approach, the simplest and most effective way to write tests is to write code—simple code, but with the mandatory expressiveness of imperative languages that should give you the needed freedom.

Hot Tip

Besides the quality assurance side of testing, there is also the advantage in feedback that a good test suite provides. The more fine-grained the tests are, the more internal quality is put under “the lens”. Clean code is easy to test, while you can’t get away with technical debt if you have to write automated tests at the same time.

Tests are the first users of your code. They will tell you much about its simplicity of use, the isolation from component dependencies and the side effects that may arise.

Installation

In the first part of this DZone Refcard, we’ll test array_sum(), a simple, native PHP function that computes the sum of values in an array. The purpose of this first test is to introduce the mechanics of PHPUnit usage.

Before writing a test at all, we need PHPUnit. You can simply grab it via its PEAR channel:


sudo pear channel-discover pear.phpunit.de
sudo pear channel-discover ... # other channels
sudo pear install phpunit/PHPUnit
sudo pecl install xdebug # for code coverage

The other channels where PHPUnit pulls components from may change in the future, so refer to the official documentation (http://phpunit.de/manual). This DZone Refcard is updated to the 3.5 version.

The first test

Here is how a test case looks like:


<?php
class ArraySumTest extends PHPUnit_Framework_TestCase
{
	public function testSumTheValuesOfAnEmptyArray()
	{
		$sum = array_sum(array());
		$this->assertEquals(0, $sum, “The sum of an empty array is computed
as $sum.”);
	}
}

Essentially, this is a class that extends PHPUnit_Framework_ TestCase so that it can be run by the /usr/bin/phpunit script. Here is a sample output:

Figure1

The methods whose names start with ‘test’ are executed, one at a time, on a different instance of this Test Case. You can execute whichever code you prefer in order to produce a set of results to confront with the ones you expect.

You can use methods on the Test Case that start with ‘assert’ to execute checks on the result of your computations that will ensure the system is behaving correctly. PHPUnit provides many simple assertion methods, but you can always define your own by adding private methods.

Executing phpunit filename.php from the command line would run the test. You can also run all the tests in a certain folder (subfolders included) simply by passing a path to the directory. This was the simplest test we could possibly write: it will provide good practice to start with and you can augment the complexity as you gain confidence about the System Under Test (SUT).

Now that we are capable of running a test on your machine, let’s gain confidence and expand the test a bit:


<?php
class ArraySumTest extends PHPUnit_Framework_TestCase
{
	public function testSumTheValuesOfAnEmptyArray()
	{
		$sum = array_sum(array());
		$this->assertEquals(0, $sum);
	}
	public function testSumTheValuesOfAnArrayWithOneValue()
	{
		$sum = array_sum(array(42));
		$this->assertEquals(42, $sum);
	}
	public function testSumTheValuesOfAnArrayWithManyElements()
	{
		$sum = array_sum(array(1, 2, 3, 4, 5, 6));
		$this->assertEquals(21, $sum);
	}
	public function testSumTheValuesOfAnArrayWithFloatValues()
	{
		$sum = array_sum(array(1, 2.5));
		$this->assertEquals(3.5, $sum);
	}
}

A failing test

Here is a failing test instead. We expect that array_sum works recursively by summing up all the values in internal arrays:


<?php
class ArraySumTest extends PHPUnit_Framework_TestCase
{
	// ...
	public function testSumsRecursively()
	{
		$sum = array_sum(array(1, array(2, 3)));
		$this->assertEquals(6, $sum);
	}
}

When run, this test gives the following result:

Figure2

We were asserting that the production code performed a task that it couldn’t. The test tells us it is not living up to our expectations.

Before diving into PHPUnit’s features, I want to highlight some methods that complement assertions in the flow control of PHPUnit.

Method Effect
$this->fail($message = '') Will instantly make the test fail, like in the case an assertion fails.
$this->markTestSkipped() Tells PHPUnit that this test should be interrupted and marks it with an (S) in the results.
$this->markTestIncomplete() Tells PHPUnit that this test is incomplete and shouldn't be run either. It will be marked with an (i) in the results and will turn the green bar of PHPUnit into an orange one.

ASSERTIONS

Assertion methods are used to check the result of your test’s execution with predefined expected values. All these methods are available on $this, as they are defined on PHPUnit_Framework_TestCase. I report here the ones that, by experience, are the most handy and widely called in my test suites.

Basic assertions are the ones you always see in introductory material, and can serve many needs. They are also versatile, since corner cases can be reconduced to assertTrue() and assertEquals() in nearly any scenario.

Method Effect
assertEquals() Fails if the two arguments are not equal (checks with the == operator).
assertSame() Fails if the two arguments are not identical (checks with ===), that is, they are not the same object or they are not scalar equal in value and type.
assertTrue() Fails when this argument is not true.
assertFalse() Fails when this argument is not false.
assertEmpty() Fails when empty() on the parameter is false.
assertNull(), assertNotNull() Checks if the variable is the special value NULL or not.
assertInstanceOf() Checks that an object is an instance of (using this operator) the class or interface passed.
assertInternalType() Checks if a scalar is of a particular PHP type-like integer or boolean.

Here is a first sample of these methods in action:


<?php
class BasicAssertionsTest extends PHPUnit_Framework_TestCase
{
	public function testBasicAssertionsWorkAsExpected()
	{
		$this->assertEquals(1, 1);
		$this->assertEquals(1, “1”);
		$this->assertEquals(3.0001, 3.000, ‘Floats should be compared with
a tolerance’, 0.001);
		$this->assertSame(42, (int) “42”);
		$this->assertTrue(true);
		$this->assertFalse(false);
		$this->assertEmpty(‘0’);
		$this->assertNull(null);
		$this->assertNotNull(42);
		$this->assertInstanceOf(‘stdClass’, new stdClass);
		$this->assertInternalType(‘string’, ‘hello, world’);
	}
}

There are more elaborate assertions which are indeed frequently called:

Method Effect
assertArrayHasKey(),
assertArrayNotHasKey()
Checks the presence of a key in an array.
assertContains($needle,
$haystack)
Checks the presence of a value in an array, both numerical or associative. Works also with two strings, checking that the first is contained in the other one.
assertContainsOnly($type) Checks that an array is composed only of $type values, like integers or booleans.
assertRegExp() Checks that a string matches a PREG-based regular expression.

Here is a sample test case:


<?php
class ArrayAndStringsAssertionsTest extends PHPUnit_Framework_TestCase
{
	public function testArrayAndStringsAssertionsWorkAsExpected()
	{
		$this->assertArrayHasKey(‘key’, array(‘key’ => ‘value’,
‘anotherKey’ => ‘anotherValue’));
		$this->assertArrayNotHasKey(‘key’, array(‘anotherKey’,
‘yetAnotherKey’));
		$this->assertContains(‘value’, array(‘value’));
		// works for strings too
		$this->assertContains(‘world’, ‘Hello, world!’);
		// this would work with any primitive type
		$this->assertContainsOnly(‘string’, array(‘value’, ‘otherValue’));
		// PCRE regular expression
		$this->assertRegExp(‘/[A-Za-z ,!]+/’, ‘Hello, world!’);
	}
}

There are also special cases:

Method Effect
assertEquals() Fails if the two arguments are not equal (checks with the == operator).
assertSame() Fails if the two arguments are not identical (checks with ===), that is, they are not the same object or they are not scalar equal in value and type.
assertTrue() Fails when this argument is not true.
assertFalse() Fails when this argument is not false.
assertEmpty() Fails when empty() on the parameter is false.
assertNull(), assertNotNull() Checks if the variable is the special value NULL or not.
assertInstanceOf() Checks that an object is an instance of (using this operator) the class or interface passed.
assertInternalType() Checks if a scalar is of a particular PHP type-like integer or boolean.

Here is a first sample of these methods in action:


<?php
class BasicAssertionsTest extends PHPUnit_Framework_TestCase
{
	public function testBasicAssertionsWorkAsExpected()
	{
		$this->assertEquals(1, 1);
		$this->assertEquals(1, “1”);
		$this->assertEquals(3.0001, 3.000, ‘Floats should be compared with
a tolerance’, 0.001);
		$this->assertSame(42, (int) “42”);
		$this->assertTrue(true);
		$this->assertFalse(false);
		$this->assertEmpty(‘0’);
		$this->assertNull(null);
		$this->assertNotNull(42);
		$this->assertInstanceOf(‘stdClass’, new stdClass);
		$this->assertInternalType(‘string’, ‘hello, world’);
	}
}

There are more elaborate assertions which are indeed frequently called:

Method Effect
assertArrayHasKey(),
assertArrayNotHasKey()
Checks the presence of a key in an array.
assertContains($needle,
$haystack)
Checks the presence of a value in an array, both numerical or associative. Works also with two strings, checking that the first is contained in the other one.
assertContainsOnly($type) Checks that an array is composed only of $type values, like integers or booleans.
assertRegExp() Checks that a string matches a PREG-based regular expression.

Here is a sample test case:


<?php
class ArrayAndStringsAssertionsTest extends PHPUnit_Framework_TestCase
{
	public function testArrayAndStringsAssertionsWorkAsExpected()
	{
		$this->assertArrayHasKey(‘key’, array(‘key’ => ‘value’,
‘anotherKey’ => ‘anotherValue’));
		$this->assertArrayNotHasKey(‘key’, array(‘anotherKey’,
‘yetAnotherKey’));
		$this->assertContains(‘value’, array(‘value’));
		// works for strings too
		$this->assertContains(‘world’, ‘Hello, world!’);
		// this would work with any primitive type
		$this->assertContainsOnly(‘string’, array(‘value’, ‘otherValue’));
		// PCRE regular expression
		$this->assertRegExp(‘/[A-Za-z ,!]+/’, ‘Hello, world!’);
	}
}

There are also special cases:

Method Effect
assertFileExists() Check that a file is present in the filesystem based on its path.
assertFileEquals() Check that the content of two files are equal.
assertGreatherThan(),
assertGreatherThanOrEqual(),
assertLessThan(),
assertLessThanOrEqual()
All assertion methods oriented to operate with >, >=, <and <= over the two values passed.

Here is an example of them in action:


<?php
class ExoticAssertionsTest extends PHPUnit_Framework_TestCase
{
	public function testExoticAssertionsWorkAsExpected()
	{
		$this->assertFileExists(__FILE__);
		$this->assertFileEquals(__FILE__, __FILE__);
		$this->assertGreaterThan(23, 42);
		$this->assertGreaterThanOrEqual(42, 42);
		$this->assertLessThan(16, 15);
		$this->assertLessThanOrEqual(16, 16);
	}
}

Custom assertions are great tools (you just have to define an assert*() method). However, taking advantage of the assertions already supported by the framework will not require that you reinvent the wheel, or extend your base Test Case class in all your tests.

All assertion methods take a last optional argument $message, which is displayed when they fail. You may enhance your tests error messages when they are not clear with this additional parameter.

FIXTURES

Fixtures are a common way to set up objects that are used in all test methods before each test run.

In PHPUnit, fixtures can be implemented with the setUp() and tearDown() hook methods, which can populate $this private fields, preparing them for usage by the single test methods.

There are also two static methods, setUpBeforeClass() and tearDownAfterClass(), that are called only one time for each test case class. Because of their static modifier, they can only access static properties and are typically used for resources that are particularly heavy to set up, like database connections.

Hot Tip

PHPUnit creates a new Test Case object for each run, so you won’t have to reset your fields between the test methods. Therefore, each test method is run in isolation and won’t interfere with the $this fields set in previous runs.

Due to this isolation property, tearDown() is usually not present unless there is some external resource to release, like a database. For in-memory objects, garbage collection will be enough.

Due to the space available, this Refcard won’t go into mechanisms for setting up global variables or static attributes, which are usually more a design problem than a testing one.

Here is a test case which uses fixtures implemented with setUp().


<?php
class FixtureTest extends PHPUnit_Framework_TestCase
{
	private $systemUnderTest;
	public function setUp()
	{
		$this->systemUnderTest = new stdClass;
	}
	public function testFixtureWorkAsExpected()
	{
		$this->assertInstanceof(‘stdClass’, $this->systemUnderTest);
		$this->systemUnderTest->field = true;
	}
	public function testAnotherTestIsRunInIsolation()
	{
		$this->assertFalse(isset($this->systemUnderTest->field));
	}
	public function tearDown()
	{
		// don’t need to do anything if garbage collection would take care
 of this
		// close your database connections, for example
	}
}

ANNOTATIONS

PHPUnit supports the use of some annotations on test case and single test methods with the goal of transforming into declarative options some common behaviors diffused in test suites. For example, running the same test multiple times with a different set of input data is an operation common enough to warrant its own annotation. The mechanism of these multiple runs isn’t duplicated throughout the test suite of our projects, instead it is kept in the framework.

PHP does not have native support for annotations, so they are embedded into the docblocks of classes and methods, much like the @param and @return annotations used for API documentation. These annotations will save you from writing boilerplate code you would otherwise end up repeating in a bunch of tests that all look alike, or inheriting from some base test case class that gets longer and longer.

@dataProvider

This annotation tells PHPUnit to run a single test method multiple times by passing a different data set as method parameters each time.

PHPUnit will display a different failure for each of the different runs, so that multiple tries are independent and one failing does not affect the sebsequent execution of the others. Running the same test code with a foreach() cycle would not have the same effect.

test code
@depends

Hot Tip

This annotation declares a test as dependent on a previous one, saying essentially that when a basic test on the SUT fails, it is not worthy to even try to run a more complex, related one.

In case the SUT experiences a large regression, the errors presented by a test run would be much more focused, consisting only of the tests that failed first and excluding their dependent siblings.

Defining dependencies is usually only a good idea inside the same test case class. In fact, it is the only scale supported by this feature. The dependent test will be marked as ‘skipped’ when the first one fails, otherwise it will be run normally. Moreover, the first test can pass a computation result to its dependency by returning it (the dependent will accept it as a parameter). A classic example is testing the add() and remove() methods of a collection:

The first test will exercise add(), check that the inserted element is present and return the collection.

The second test will exercise remove() on the passed collection, and check that the element is not present anymore.

test code2
@expectedException (with @expectedExceptionCode and @expectedExceptionMessage)

This annotation asserts that the code contained in the test methods throws an exception, and optionally checks its code and its message.

Note that any line of code can be throwing the exception, as long as it is called inside the test method. If you want a more accurate check on which statement should raise an exception, stick to try/catch blocks.

@group

Hot Tip

Grouping aids you in running the exact amount of tests during development, and not the entire suite, which can require much more time. You will get feedback on a more frequent basis, and only from the code you select. This leaves the rest of the code base for subsequent integration (pre-commit or pre-push).

This annotation is not applicable to test methods, but only on test cases. It defines a test case as pertaining to a particular group that can be used as a filter to run all the grouped tests independently from the rest of the suite.

A test case can be in multiple groups. They can be thought of as labels rather than folders (which are an independent filter.)

For examples, you may use annotations such as @group acceptance (for Selenium-based tests); @group functional (for tests which do not exercise a single unit and, hence, are a bit slower to run), and @group ticket-42 (for the tests regarding a particular bug fix).

The command used to filter tests of a particular group is *phpunit --group*, which will be treated later in the command line section. However, you can also filter groups in the XML configuration.

@runTestsInSeparateProcesses

This too is a test case annotation. It is not diffused and should be used only for special case tests. It runs tests in different executions of the *php* command, so that they do not affect each other. This mechanism can be useful when testing something related to autoloading or a similar necessary global state. For example, you may be testing that the autoloader loads the same class multiple times under different conditions, and this can only be done in different processes.


<?php
/**
  * @group acceptance
  * @group someOtherGroup
  */
class AnnotationsTest extends PHPUnit_Framework_TestCase
{
	public static function dataToFeed()
	{
	  return array(
		array(1, 2, 3),
		array(4, 2, 6),
		array(10, 12, 22)



		);
	}
	/**
	 * @dataProvider dataToFeed
	 */
	public function testSumOperatorsWorksCorrectly($a, $b, $total)
	{
		$this->assertEquals($total, $a + $b);
	}
	public function testFails()
	{
		$this->fail(‘I fail in order to stop my dependent test from
 running.’);
	}
	/**
	 * @depends testFails
	 */
	public function testIAmDependent()
	{
		$this->fail(‘I would fail too, but I\’m not run.’);
	}
	/**
	 * @expectedException Exception
	 * @expectedExceptionCode 400
	 * @expectedExceptionMessage This is the message
      */
	public function testRaisesException()
	{
		throw new Exception(‘This is the message’, 400);
	}
}

Test Doubles

Test Doubles are substitutes for real objects that you don’t want to involve in your tests. By injecting Test Doubles in your System Under Test, you can effectively isolate it from the rest of the system and let it call its collaborators without null checks. You can also define what the Test Doubles expect as method parameters, or what they should return.

The taxonomy of Test Doubles comprehends:

Pattern Meaning
Dummies Objects that exist only to satisfy type hints and runtime checks. They are passed around but no methods are called on them.
Stubs Objects that return canned results when their methods are called.
Mocks Stubs that can also check what parameters are passed to them.
Fakes Real implementations of collaborators, but much more lightweight than the real object.

PHPUnit offers support for automatic generaton and instantiation of Dummies, Stubs, and Mocks. It subclasses the defined class, overrides methods and eval() the resulting code. In PHPUnit, Mock is used as an umbrella term covering any Test Double category.

The getMock() or getMockBuilder() methods can be called to obtain the mock, or a Builder implementation over the mock itself. They accept an interface or a concrete class as the first argument. getMockForAbstractClass is the equivalent of getMock() for this special case.

Hot Tip

I contributed getMockBuilder() to provide a cleaner way for complex mock instantiation, which usually requires calls with 7 arguments to getMock(). It provides a fluent interface with different methods to set the creation options one by one, prior to creating the mock.

Once you have a mock, you can perform the expects() call on it to create an expectation object. The expectation object then presents different methods which provide a fluent interface:

Method Effect
method() Defines the name of the method it refers to.
with() Specifies assertions to make on the parameters passed. In the simplest cases, you call it with the value you would use to call the method, in the identical order.
will() Defines the behavior of the overridden method as traits such as what to return or whether to throw an exception.

Here is a test case which covers many instances of stubs and mocks usage:


<?php
class TestDoublesTest extends PHPUnit_Framework_TestCase
{
	public function testInstantiatesADummy()
	{
		$dummy = $this->getMock(‘stdClass’);
		$this->assertInstanceOf(‘stdClass’, $dummy);
	}
	public function testInstantiatesAStub()
	{
		$stackStub = $this->getMock(‘SplStack’);
		$stackStub->expects($this->any())
				  ->method(‘pop’)
				  ->will($this->returnValue(42));
		$this->assertEquals(42, $stackStub->pop());
	}
	public function testSetsUpAStubMethodWithACallback()
	{
		$callback = function($argument) {
			$map = array(
				‘key’ => ‘value’,
				‘otherKey’ => ‘otherValue’
			);
			return $map[$argument];
		};
		$stackStub = $this->getMock(‘SplStack’);
		// don’t ask me why a Stack has getter and setters
		// I use it only because of its availability
		$stackStub->expects($this->any())
				  ->method(‘offsetGet’)
				  ->will($this->returnCallback($callback));
		$this->assertEquals(‘value’, $stackStub->offsetGet(‘key’));
	}
	/**
	  * @expectedException InvalidArgumentException
      */
	public function testThrowsAnException()
	{
		$stackStub = $this->getMock(‘SplStack’);
		$stackStub->expects($this->any())
				  ->method(‘push’)
				  ->will($this->throwException(new
InvalidArgumentException));
   		$stackStub->push(42);
	}
	public function testInstantiatesAMockAndPutExpectationOnAParameter()
	{
		$stackMock = $this->getMock(‘SplStack’);
		$stackMock->expects($this->once())
			      ->method(‘push’)
			      ->with(42);
		$stackMock->push(42);
	}
	public function
testInstantiatesAMockAndPutExpectationOnMultipleParameters()
	{
		$stackMock = $this->getMock(‘SplStack’);
		$stackMock->expects($this->once())
				  ->method(‘offsetSet’)
				  ->with(2, 42);
		$stackMock->offsetSet(2, 42);
	}
	public function
testInstantiatesAMockAndPutExpectationsOnParametersDifferentFromEqualTo()
	{
		$stackMock = $this->getMock(‘SplStack’);
		$stackMock->expects($this->once())
				  ->method(‘offsetSet’)
				  ->with($this->anything(), $this->identicalTo(‘42’));
		$stackMock->offsetSet(2, ‘42’);
	}
	public function
testInstantiatesAMockAndPutOtherExpectationsOnParameters()
	{
		$stackMock = $this->getMock(‘SplStack’);
		$stackMock->expects($this->once())
				  ->method(‘offsetSet’)
				  ->with($this->isType(‘int’), $this-
>isInstanceOf(‘stdClass’));
		$stackMock->offsetSet(2, new \stdClass);
	}
	public function
testInstantiatesAMockAndPutYetOtherExpectationsOnParameters()
	{
		$stackMock = $this->getMock(‘SplStack’);
		$stackMock->expects($this->once())
				  ->method(‘offsetSet’)
				  ->with($this->lessThan(3), $this->isTrue());
		$stackMock->offsetSet(2, true);
	}
	public function testCallsAMockTwice()
	{
		$stackMock = $this->getMock(‘SplStack’);
		$stackMock->expects($this->exactly(2))
				  ->method(‘push’);
		$stackMock->push(23);
		$stackMock->push(42);
	}
	public function testShouldNotCallAMock()
	{
		$stackMock = $this->getMock(‘SplStack’);
		$stackMock->expects($this->never())
				  ->method(‘push’);
	// this would fail
	// $stackMock->push(42);
	}
	/**
	* Each call on the MockBuilder apart from getMock() is optional.
	*/
public function testInstantiatesAMockUsingBuilder()
	{
		$arrayIteratorMock = $this->getMockBuilder(‘ArrayIterator’)
								  ->setMethods(array(‘current’, ‘next’))
								  ->disableOriginalConstructor()
								  ->disableOriginalClone()
								  ->getMock();
	}
}

COMMAND LINE USAGE

The phpunit script is the main means to run PHPUnit-based test suites, even if there are ways to bypass it like Phing (http:// phing.info/trac/) tasks for purposes of Continuous Integration.

Knowing how to use *phpunit* effectively is therefore crucial to leverage your test suite power. These are the various options available to modify its behavior:

Switch Effect
--configuration <file>, --no-configuration Includes a phpunit.xml file different from the one in the working directory or excludes its automatic recognition.
--coverage-html <directory> Generates an HTML report on code coverage in the specified folder. The xdebug extension is required for code coverage to be collected and the test execution will be much slower.
--colors Specifies to use colors in the output as a nice way to visualize the test success.
--bootstrap <file> Defines a PHP file to include before starting the test suite execution. It is included also in the configuration from some releases.
--filter Lets you filter test methods that match the passed pattern. You won’t have to comment on the other tests when you want to focus on a single one.
--group Filters the tests defined by the current suite and runs only the ones in the specified group.
--exclude-group Runs all the tests except the ones in the chosen group.
--list-groups Shows all the groups available for running independently.
--include-path Sets a particular include_path ini directive for running the test.
-d key=value Sets a php.ini value (temporarily).
--verbose Displays a list of test case names as the execution goes along, so that you can catch errors during long run just when they happen, instead of waiting for the whole test suite to finish.
--version Displays current version of PHPUnit. Handy to know, since running it without parameters starts the whole test suite. -v is not supported.
--testdox Generates a “kind” of Agile documentation from the test names. If you write test names well, it documents what your class or component under test does for a living.

CONFIGURATION

PHPUnit supports configuration of the test suite via an XML file that can be stored under version control. Common options like bootstrap files, logging formats or filters can be saved in this file instead of being passed with each PHPUnit command.

PHPUnit looks for phpunit.xml and phpunit.xml.dist, which are assumed to be present in the working directory. Usually one of them is kept in the test suite root directory.

Hot Tip

The common practice is to store phpunit.xml dist in the source control system and ignore phpunit.xml, so that users can personalize their run if they do not have the tools for running all tests available (such as Selenium or staging http servers).

It can also be the case that you do not want to run slow integration tests sometimes. With a phpunit.xml.dist present however, you will be able to run tests just after a checkout.

Root element

<phpunit> is the root element. It accepts various attributes such as “bootstrap”, which specifies a boostrap file to execute prior to the tests, or “colors”, which prescribes the use of colors like red and green in the output.

Test suites

The <testsuites> and <testsuite> elements let you group tests from different folders. They can contain these two elements:

  • <file>, which defines a single PHP file.
  • <directory>, which will include all the tests inside that directory or a subdirectory. <directory> accepts a suffix attribute to filter the test case name: by default it is ‘Test’.
Filtering, logging, and more

Inside the configuration, you also have different modifiers available. You can:

  • Filter tests of a certain <group> to run (or not run) them.
  • Define code coverage inclusion (and exclusion) of files. The <filter> element refers to code coverage.
  • Log results and statistics in various formats, with the <logging> element. It may contain various <log> entries, of various types: coverage-html, coverage-xml, json, tap, junit, testdox-html, testdox-text.
  • Attach listeners with the <listeners> and <listener> elements.
  • Configure a Selenium RC server to run acceptance tests, with the <selenium> and <browser> elements.
<phpunit bootstrap=”/path/to/bootstrap.php” colors=”false”>
	<testsuites>
		<testsuite>
			<directory>tests/</directory>
			<file>DoctrineTest.php</file>
		</testsuite>
	</testsuites>
	<groups>
		<include>
			<group>functional</group>
		</include>
		<exclude>
			<group>acceptance</group>
		</exclude>
	</groups>
	<filter>
		<blacklist>
			<directory suffix=”.php”>library/</directory>
			<exclude>
				<file>library/App</file>
			</exclude>
		</blacklist>
		<whitelist>
			<directory suffix=”.php”>application/</directory>
			<file>bootstrap.php</file>
			<exclude>
				<directory suffix=”.php”>application/views</directory>
			</exclude>
		</whitelist>
	</filter>
	<logging>
		<log type=”coverage-html” target=”/tmp/coverage-report-folder” />
		<log type=”junit” target=”/tmp/junit-log.xml” />
		<log type=”testdox-html” target=”/tmp/testdox.html”/>
	</logging>
	<listeners>
		<listener class=”App_Test_FunctionalTestListener” file=”library/App/Test/FunctionalTestsListener.php”>
		<arguments>
			<string>staging</string>
		</arguments>
		</listener>
	</listeners>
	<selenium>
		<browser name=”Ubuntu-Firefox” browser=”*firefox /usr/bin/firefox” host=”localhost” port=”4444” />
	</selenium>
</phpunit>

About The Authors

Photo of author James Sugrue

Giorgio Sironi

Giorgio Sironi is a Bachelor of Computer Engineering and works as a PHP software architect while continuing his studies in a Master Program at Politecnico di Milano. During the last six years he transitioned from his early work as a websites developer to the creation of web-based applications. He practices Test-Driven Development every day and believes in testing as a design tool. Giorgio is an international speaker at PHP conferences and you may have already heard of him as the author of the Practical PHP Testing free ebook, or the “Practical PHP Patterns” series on DZone.

Recommended Book

HTML5

Test-Driven Development (TDD) is now an established technique for delivering better software faster. TDD is based on a simple idea: Write tests for your code before you write the code itself. However, this “simple” idea takes skill and judgment to do well. Now there’s a practical guide to TDD that takes you beyond the basic concepts. Drawing on a decade of experience building real-world systems, two TDD pioneers show how to let tests guide your development and “grow” software that is coherent, reliable, and maintainable.

Share this Refcard with
your friends & followers...

DZone greatly appreciates your support.


Your download should begin immediately.
If it doesn't, click here.

Adobe ColdFusion Web Services for PHP Programmers

By Marco Tabini

3,798 Downloads · Refcard 116 of 151 (see them all)

Download
FREE PDF


The Essential ColdFusion Web Services Cheat Sheet

ColdFusion Web Services can be deployed using a variety of standard protocols like SOAP or plain XML, you can easily take advantage of them from your PHP 5 scripts using nothing more than the standard web service facilities of the language. This DZone Refcard will introduce you to features that allow PHP Programmers to take advantage of the ColdFusion platform. Specifically, youll find out how to access and discover exposed web services and services from PHP, how to generate documents and charts, and how to manipulate PDFs and images.
HTML Preview
Adobe® ColdFusion Web Services for PHP Programmers

Adobe® ColdFusion Web Services: for PHP Programmers

By Marco Tabini

INTRODUCTION

Adobe® ColdFusion 9 (CF9) is a technology platform that allows developers to create web-based applications of any complexity using a set of easy-to-use tools.

In addition to being a standalone server-side technology, ColdFusion also provides a number of facilities that allow you to perform tasks like manipulating PDF or Microsoft Office files, sending e-mail, creating charts, and much more—all tasks that often require expensive dedicated solutions that must be developed in-house.

Because ColdFusion services can be deployed using a variety of standard protocols like SOAP or plain XML, you can easily take advantage of them from your PHP 5 scripts using nothing more than the standard web service facilities of the language. In fact, you can take advantage of CF9’s “Exposed Services” without even writing a single line of CFML code!

Obtaining and Installing CF9

Much like PHP, ColdFusion is a cross-platform product that is capable of running on a variety of platforms, including Windows, Mac OS X and any variety of Linux on which you can install a Java runtime environment.

CF9 comes in two different editions: Standard and Enterprise. The latter provides a number of scalability and monitoring facilities designed for large deployments, while the former is targeted at simpler needs. Outside of these differences, however, both editions offer a comparable set of core features, which means that your CF9 server setup can grow organically without having to sacrifice any functionality—which CF9 edition you choose will be primarily dictated by the amount of traffic that you need to serve, rather than by the type of task that you need to perform.

Hot Tip

You can find a feature-by-feature comparison of each CF9 edition at http://www.adobe.com/products/ coldfusion/pdfs/cf9_feature_comparison_matrix_ue.pdf

While CF9 is a commercial product that requires the purchase of a license in order to be used in a production environment, Adobe makes a Developer Edition of the platform available free of charge. Its only limitation is that it allows no more than two concurrent connections—perfect for developing locally on your machine.

You can download the Developer Edition of CF9 directly from the Adobe website at http://www.adobe.com/products/coldfusion/; like the commercial versions of CF9, the Developer Edition is available for every platform supported by the product. Once you have downloaded and launched the installer, the setup process will ask you a number of questions, including whether you want to install OpenOffice, which CF9 uses to manipulate Microsoft Office documents, and whether to enable the Remote Development Service, which you should do in a development environment if you plan on taking advantage of CF9’s debugging features.

Configuration and Settings

At the end of the setup process, the installer will launch the Configuration and Settings Wizard, a web-based application that completes your server’s configuration and eventually grants you access to the ColdFusion Administrator, from which you can control and manipulate all your server-side settings.

ACCESSING EXPOSED WEB SERVICES

You don’t need to know how to develop ColdFusion applications in order to take advantage of the Exposed Services that are part of the platform.

In fact, CF9 makes a number of its features available directly through a SOAP-based interface, allowing you to:

  • Generate and manipulate PDF files
  • Manipulate images
  • Generate Micr osoft Office documents
  • Send and r eceive e-mail

Access Control

In order to access any of the exposed CF9 services, you need to first define the appropriate set of access controls. You can do so by creating a user by opening the Administrator and clicking on the “User Manager” item under the “Security” menu. Click on the “Add User” button, and then fill the user authentication form with the appropriate information.

authentication

At this point, you can define which Exposed Services the user has access to by selecting them in the “Prohibited Services” list and transferring them to the ”Allowed Services” list. Exposed Services

To finish, click on the “Add User” button and you’re all set!

Enabling Client Access

By default, to ensure the security of your server, CF9 precludes any client from accessing Exposed Services.

You can change this setting by clicking on the “Allowed IP Addresses” item under the “Security Menu,” where you can add one or more IPs (or IP ranges) to the server’s whitelist for Exposed Services.

Security Menu

Hot Tip

The examples in this Refcard assume that you are running the Developer Edition of CF9 on your local machine. For deployment, you will need to alter your settings according to the make-up of your specific production environment.

Configuring Services

Some services must be configured before they can be used. For example, the Mail service requires you to specify an SMTP server before it can be used to send messages, while the Document service requires you to specify the location of OpenOffice, and so on.

In all cases, you can view and modify the settings for the services exposed by your server directly from the Administrator.

DISCOVERING EXPOSED SERVICES FROM PHP

Exposed Services are made available through a specific location on your server; typically, if you have installed your copy of CF9 using the standard settings, this will be at http://127.0.0.1:8500/CFIDE/services/. If you point your browser to that URL, you will be greeted with a list of all the service entry points available.

Clicking on a specific file will cause CF9 to output a help page that describes all the functionality provided by the service and all the available remote method calls.

remote method calls

Hot Tip

Complete documentation for all the Exposed Services can be found on the Adobe Help site at http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/ index.html both in a “live” web-based version and in PDF format.

Accessing a Service’s WSDL Specification

Since your PHP scripts will be accessing Exposed Services through SOAP, you need access to the WSDL specification for the services you want to interface with.

Luckily, CF9 supports the built-in generation of WSDL documents, so all you need to do is add a special query string to the end of the URL of its entry point. For example, the WSDL for the Mail service can be accessed at this URL: http://127.0.0.1:8500/CFIDE/services/mail.cfc?WSDL

Using SOAP

PHP 5’s web service libraries make accessing web services of any kind very easy.

Once you have access to the WSDL, you can call any of the services directly from a PHP 5.x script by using the SOAPClient class. SOAPClient encapsulates a SOAP service and provides the means for introspecting its methods and data types, as well as performing calls against it.

For example, having obtained the URL of the WSDL document for the Mail service, you can find out which method calls it supports by running this simple script:


$service = new SOAPClient(‘http://127.0.0.1:8500/CFIDE/services/mail.
cfc?WSDL’);
var_dump($service->__getFunctions());

This will produce the following output:


array(1) {
  [0]=>
  string(35) “sendResponse send(send $parameters)”
}

This indicates that the service supports a method called send() that takes a single parameter of type “send” in input and returns a value of type “sendResponse” in output.

Much like the __getFunctions() method of SOAPClient can be used to retrieve the names of all the remote procedure calls provided by a service, __getTypes() can be used to retrieve a description of all the compound data types defined by it. In this case, the output will contain a description of both the “send” and “sendResponse” data types, which we can then use to issue a call to the service:


<?php
$service = new SOAPClient(‘http://127.0.0.1:8500/CFIDE/services/mail.
cfc?WSDL’);
$payload = array(
‘serviceusername’ => ‘johndoe’,
‘servicepassword’ => ‘johndoepassword’,
‘server’ => ‘smtp.example.com’,
‘port’ => ‘25’,
‘username’ => ‘smptuser’,
‘password’ => ‘smptpassword’,
‘from’ => ‘marco@example.com’,
‘to’ => ‘marco@example.com’,
‘bcc’ => ‘’,
‘cc’ => ‘’,
‘subject’ => ‘Test’,
‘content’ => ‘This is a test e-mail!’,
‘type’ => ‘’,
‘charset’ => ‘’,
‘failto’ => ‘’,
‘mailerid’ => ‘’,
‘mimeattach’ => ‘’,
‘priority’ => ‘’,
‘replyto’ => ‘’,
‘timeout’ => ‘’,
‘useSSL’ => ‘’,
‘useTLS’ => ‘’,
‘wraptext’ => ‘’,
‘attachments’ => ‘’,
‘mailparts’ => ‘’,
);

As you can see, you can leave those fields that are not required blank by setting them to an empty string; however, you must include them in the payload, and they cannot be set to NULL.

Hot Tip

If you use an IDE to edit your PHP code, you may be able to take advantage of advanced SOAP functionality such as code completion or service proxying. Check your IDE’s documentation for more information.

You have probably noticed the serviceusername and servicepassword properties at the beginning of the payload: these are the credentials of the user that you defined earlier in the Administrator.

Dealing with Failure

Occasionally, any code can fail. It is, therefore, essential to be able to manage failure in a predictable and safe way.

When a service call fails, SOAPClient throws an exception of the appropriate kind, which, generally, includes some information about the error and provides useful clues on how to address it. For example:


PHP Fatal error: Uncaught SoapFault exception: [soapenv:Server.
userException] coldfusion.xml.rpc.CFCInvocationException: [coldfusion.
servicelayer.ServicelayerExceptions$UserNotAuthorizedException : User
johndoe is not authorized to invoke mail service]
Stack trace:
[...]

In this particular case, you can plainly see that the failure is caused by the fact that the password provided for the service user was incorrect.

Hot Tip

In a production environment, you should always encapsulate your service calls in a try... catch code block and handle failures appropriately.

GENERATING DOCUMENTS

The Document Exposed Service can be used to generate documents based on existing templates, or even on the contents of a web page.

You can find the WSDL for the Document service at this URL: http://127.0.0.1:8500/CFIDE/services/document.cfc?wsdl

As you can see by introspecting the WSDL descriptor or reading the documentation for the service, Document supports a method called generate() that requires a long list of parameters. However, you only need a couple of them to create a PDF out of a web page:


<?php

$service = new SOAPClient(‘http://127.0.0.1:8500/CFIDE/services/document.
cfc?wsdl’);

$payload = array(
	‘serviceusername’ => ‘johndoe’,
	‘servicepassword’ => johndoepassword’,
	‘format’ => ‘pdf’,
	‘content’ => ‘’,
	‘authpassword’ => ‘’,
	‘authuser’ => ‘’,
	‘backgroundvisible’ => ‘’,
	‘bookmark’ => ‘’,
	‘encryption’ => ‘’,
	‘fontembed’ => ‘’,
	‘marginbottom’ => ‘’,
	‘marginleft’ => ‘’,
	‘marginright’ => ‘’,
	‘margintop’ => ‘’,
	‘mimetype’ => ‘’,
	‘orientation’ => ‘’,
	‘ownerpassword’ => ‘’,
	‘pageheight’ => ‘’,
	‘pagetype’ => ‘’,
	‘pagewidth’ => ‘’,
	‘permissions’ => ‘’,
	‘proxyhost’ => ‘’,
	‘proxypassword’ => ‘’,
	‘proxyport’ => ‘’,
	‘proxyuser’ => ‘’,
	‘src’ => ‘http://google.com’,
	‘scale’ => ‘’,
	‘unit’ => ‘’,
	‘useragent’ => ‘’,
	‘userpassword’ => ‘’,
	‘documentsection’ => ‘’,
	‘documentitem’ => ‘’,
);

$result = $service->generate($payload);

$pdfUrl = $result->generateReturn;


As you can see, the service returns a structure that contains the URL to the PDF file that was generated from the URL you provided in input. You can either redirect your client to that URL, or read the file and output it directly from your PHP file if the CF9 server is not directly reachable to the client that invoked your PHP script.

Hot Tip

The Trial and Developer edition of CF9 will place a watermark on all generated files. Licensed versions of CF9 do not have this limitation.

While the example above is a bit contrived, there are many practical scenarios in which being able to create PDF files can be useful to a web project—think, for example, of e-commerce systems that must deliver receipts to their customers.

MANIPULATING PDF FILES

The PDF service, as its name implies, makes it possible for you to manipulate PDF files. You can perform tasks like add watermarks, add, delete and extract pages from a document, merge documents together and modify their security features. The PDF service can be accessed through this WSDL file: http://127.0.0.1:8500/CFIDE/services/pdf.cfc?WSDL

Retrieving Information About a PDF File

The getinfo() method of the service allows you to retrieve a wealth of information from a PDF file—from the name of the application that was used to create it to the number of pages it contains:


<?php

$service = new SOAPClient(‘http://127.0.0.1:8500/CFIDE/services/pdf.
cfc?wsdl’);

// var_dump($service->__getTypes());

$payload = array(
	‘serviceusername’ => ‘johndoe’,
	‘servicepassword’ => ‘johndoepassword’,
	‘source’ => ‘http://example.com/example.pdf’,
	‘password’ => ‘’,
);

$result = $service->getinfo($payload);

echo $result->application;
echo $result->totalPages;

As you can see, the service expects you to pass a URL to the PDF file that needs to be inspected—clearly, this location must be accessible to your CF9 installation.

Hot Tip

You can examine and manipulate protected PDF files by providing a value for the password parameter of most PDF service calls. Note that using the document’s user password will limit you to the functionality that has been enabled by the creator. For more information on the PDF security model, visit http://createpdf.adobe.com/cgi-feeder.pl/help_security

Generating Thumbnail Views

Another useful feature of the PDF service is the ability to generate thumbnail images of a document’s pages:


<?php

$service = new SOAPClient(‘http://127.0.0.1:8500/CFIDE/services/pdf.
cfc?wsdl’);

$payload = array(
	‘serviceusername’ => ‘johndoe’,
	‘servicepassword’ => ‘johndoepassword’,
	‘source’ => ‘http://example.com/example.pdf’,
	‘format’ => ‘jpg’,
	‘imageprefix’ => ‘img’,
	‘password’ => ‘’,
	‘pages’ => ‘’,
	‘resolution’ => ‘high’,
	‘scale’ => ‘’,
	‘transparent’ => ‘’,
);

$result = $service->thumbnail($payload);

foreach ($result->thumbnailReturn as $thumbnail) {

	echo $thumbnail->value;
}


Upon a successful execution, this method returns a collection of objects that provide URLs for each of the thumbnails generated. As you can see, you can specify a number of different options: the output format (JPEG in this case, but PNG and TIFF are also supported), the resolution (high or low), the scale (a percentage between 1 and 100), and so on.

Password-protect and Encrypt PDF Documents

It is sometimes convenient to be able to dynamically password-protect a PDF document—for example to provide each user with a customized version that can only be opened using his or her password.

This can be easily accomplished by calling the protect() method:


<?php
$service = new SOAPClient(‘http://127.0.0.1:8500/CFIDE/services/pdf.
cfc?wsdl’);

$payload = array(
	‘serviceusername’ => ‘johndoe’,
	‘servicepassword’ => ‘johndoepassword’,
	‘source’ => ‘http://example.com/example.pdf’,
	‘newUserPassword’ => ‘userpass’,
	‘newOwnerPassword’ => ‘ownerpass’,
	‘permissions’ => ‘AllowPrinting,AllowScreenReaders’,
	‘encrypt’ => ‘RC4_128M’,
	‘password’ => ‘’,
);

$result = $service->protect($payload);

echo $result->protectReturn;

The result of the call will contain the URL to the newly protected document in a property called protectedReturn.

Note that the service call allows you to specify both an owner and client password (http://createpdf.adobe.com/cgi-feeder.pl/help_security for more information on the Adobe PDF security model) as well as specific permissions that users are allowed to take advantage of. All these options are explained in the CF9 documentation.

Merging PDF Files

The ability to merge one or more PDF files can be handy in a number of different scenarios. Imagine, for example, compiling several reports into a single document, or dynamically creating PDF books for your customers based on specific chapters that they decide to buy.

CF9 makes this task very easy to accomplish:


<?php

error_reporting(E_ALL | E_STRICT);

$service = new SOAPClient(‘http://127.0.0.1:8500/CFIDE/services/pdf.
cfc?wsdl’);

$payload = array(
	‘serviceusername’ => ‘johndoe’,
	‘servicepassword’ => ‘johndoepassword’,
	‘source’ => ‘http://example.com/example.pdf, http://example.com/
example2.pdf’,
	‘keepbookmark’ => ‘1’
);

$result = $service->mergeFiles($payload);

echo $result->mergeFilesReturn;

The merge operation can be performed on an arbitrary number of files (greater than or equal to two). The keepbookmark parameter allows you to maintain all the existing bookmarks from your source PDFs into the final result.

MANIPULATING IMAGES

While PHP has some powerful image manipulation functions provided by the GD Library, the latter does have some limitations. It is sometimes difficult to install, and the process of creating and manipulating the images can require multiple complex steps.

If you happen to also have access to an instance of CF9, however, you can take advantage of its Image services for a set of easy-to-use manipulation functions that, while not as rich as the ones provided by GD, require much less effort, especially for simple tasks.

The Image service’s WSDL can be accessed at this URL: http://127.0.0.1:8500/CFIDE/services/image.cfc?WSDL

Obtaining Information About an Image

For example, you can obtain a wealth of information on an image through a simple call to the Info method of the Image service:


<?php

$service = new SOAPClient(‘http://127.0.0.1:8500/CFIDE/services/image.
cfc?wsdl’);

$payload = array(
	‘serviceusername’ => ‘johndoe’,
	‘servicepassword’ => ‘johndoepassword’,
	‘source’ => ‘http://example.com/logo.png’,
);
$result = $service->info($payload);
foreach ($result->InfoReturn as $info) {
	echo $info->key, ‘ => ‘, $info->value, “\n”;
}


The result of the method call is a long list of data on the image:


source => _cf5341945594648670180.png
height => 126
width => 103
colormodel.pixel_size => 32
colormodel.bits_component_1 => 8
colormodel.bits_component_2 => 8
colormodel.alpha_channel_support => YES
colormodel.colormodel_type => ComponentColorModel
colormodel.colorspace => Any of the family of RGB color spaces
colormodel.alpha_premultiplied => NO
colormodel.transparency => TRANSLUCENT
colormodel.num_color_components => 3
colormodel.bits_component_3 => 8
colormodel.num_components => 4
colormodel.bits_component_4 => 8

As you can see, we can now determine the width and height of the image, as well as gather lots of information about its color model.

Resizing an Image

Another typical operation that is performed on images is resizing them; in this case, the functionality provided by CF9 is much simpler than its GD equivalent:


<?php

$service = new SOAPClient(‘http://127.0.0.1:8500/CFIDE/services/image.
cfc?wsdl’);

$payload = array(
	‘serviceusername’ => ‘johndoe’,
	‘servicepassword’ => ‘johndoepassword’,
	‘source’ => ‘http://example.com/logo.png’,
	‘width’ => 100,
	‘height’ => 100,
	‘interpolation’ => ‘highestquality’,
	‘blurfactor’ => 1,
);

$result = $service->resize($payload)->ResizeReturn;

As you can see, the process is fairly simple. All you need to do is specify a location for the image, its new dimensions, an interpolation algorithm and a blur factor; the latter is used to reduce resizing artifacts when the final image has a larger size than the original.

Compared to the GD method of resizing images, the CF9 approach has several advantages. First, it’s a one-step operation, whereas GD requires multiple separate steps. Second, CF9 takes care of caching the output image for you, thus making caching repeated resize operations easier.

CHARTING

While there are numerous open source libraries and free web services that can be used to generate charts, CF9 provides a truly powerful service whose functionality is hard to beat.

For example, in addition to creating charts in a multitude of different varieties, the Chart service allows you to output in several formats, including as an interactive file in the form of an Adobe® Flash® movie that features mouse-over effects and animations.

The WSDL for the Chart service can be found at this URL: http://127.0.0.1:8500/CFIDE/services/chart.cfc?WSDL

Generating Charts

The functionality provided by the Chart service is rich and complex, but can all be accessed through a single call to the generate() method. As a result, the latter has a signature that looks a little intimidating at first, but that is, in reality, very easy to grasp once you get through the basics. Here’s an example:


<?php

$service = new SOAPClient(‘http://127.0.0.1:8500/CFIDE/services/chart.
cfc?wsdl’);

$payload = array(
		‘serviceusername’ => ‘johndoe’,
		‘servicepassword’ => ‘johndoepassword’,
		‘backgroundcolor’ => ‘’,
		‘chartheight’ => ‘’,
		‘chartwidth’ => ‘’,
		‘databackgroundcolor’ => ‘’,
		‘font’ => ‘’,
		‘fontbold’ => ‘’,
		‘fontitalic’ => ‘’,
		‘fontsize’ => ‘’,
		‘foregroundcolor’ => ‘’,
		‘format’ => ‘flash’,
		‘gridlines’ => ‘’,
		‘labelformat’ => ‘’,
		‘markersize’ => ‘’,
		‘pieslicestyle’ => ‘’,
		‘scalefrom’ => ‘’,
		‘scaleto’ => ‘’,
		‘seriesplacement’ => ‘’,
		‘show3d’ => ‘’,
		‘showborder’ => ‘’,
		‘showlegend’ => ‘’,
		‘showmarkers’ => ‘’,
		‘showxgridlines’ => ‘’,
		‘showygridlines’ => ‘’,
		‘sortxaxis’ => ‘’,
		‘tipbgcolor’ => ‘’,
		‘tipstyle’ => ‘’,
		‘title’ => ‘’,
		‘url’ => ‘’,
		‘xaxistitle’ => ‘’,
		‘xaxistype’ => ‘’,
		‘xoffset’ => ‘’,
		‘yaxistitle’ => ‘’,
		‘yaxistype’ => ‘’,
		‘yoffset’ => ‘’,
		‘chartseries’ => array (
				‘chartdata’ => array (
					0 => array (
						‘item’ => ‘Sales’,
						‘value’ => ‘90000’
					),
					1 => array (
						‘item’ => ‘Revenue’,
						‘value’ => ‘150000’
						)
			),
			‘colorlist’ => ‘red,green’,
			‘datalabelstyle’ => ‘’,
			‘paintstyle’ => ‘’,
			‘seriescolor’ => ‘’,
			‘serieslabel’ => ‘’,
			‘type’ => ‘bar’,
		)
);
$result = $service->generate($payload)->generateReturn;

As you can see, despite the long list of parameters, all you really need to provide is one or more “chartseries” values, which are nothing more than a collection of data points in item/value format and a few specs on how those data points should be represented. The remaining parameters can be used to further tweak the chart’s appearance and manipulate items like its title, font characteristics, the visibility of grid-lines, and so on.

Chart

This last example barely scratches the surface of CF9’s charting service has to offer. For example, you can actually create 3-D charts, or combine multiple graphs into a single image. Depending on the complexity of your project, CF9 can greatly enhance the look of your application, and provide your users with helpful visuals.

LEARN MORE ABOUT CF9 WEB SERVICES

There is a lot more to CF9’s Web Services offerings than what can be covered in this Refcard — for example, there is an entire service dedicated to e-mail. Luckily, Adobe maintains a comprehensive set of documentation for developers at http://help.adobe.com/en_US/ColdFusion/9.0/Developing/index.html.

About The Authors

Photo of author By Marco Tabini

MANIK SURTANI

Marco Tabini is the co-founder, with Arbi Arzoumani, of php|architect, the world’s largest PHP magazine in the English language, currently distributed in over 145 countries. He is also the co-founder, with Keith Casey, of Blue Parabola, LLC, a consulting firm that specializes in information architecture, code and security auditing, largescale deployments and optimization.

An accomplished author on the subject of PHP and the business of web development, Marco is also a frequent speaker at PHP and OSS conferences throughout the world.

Recommended Book

Adobe Coldfusion 9

Written by the best known and most trusted name in the ColdFusion community, Ben Forta, The ColdFusion Web Application Construction Kit is the best-selling ColdFusion series of all time - the books that most ColdFusion developers used to learn the product. This Getting Started volume starts with Web and Internet fundamentals and database concepts and design, and then progresses to topics including creating data-driven pages, building complete applications, implementing security mechanisms, integrating with e-mail, building reusable functions and components, generating data-driven reports and graphs, building Ajaxpowered user interfaces, and much more. Complete coverage of ColdFusion 9 continues in “Volume 2, Application Development” (ISBN:0321679199) and “Volume 3, Advanced Application Development” (ISBN:0321679202).


Share this Refcard with
your friends & followers...

DZone greatly appreciates your support.


Your download should begin immediately.
If it doesn't, click here.

Getting Started with PHP and Flex

By Marco Tabini

7,812 Downloads · Refcard 96 of 151 (see them all)

Download
FREE PDF


The Essential PHP and Flex Cheat Sheet

Flash Builder 4.5 for PHP is used by professional web developers to develop applications with slick, Flex UIs and powerful, battle-tested backends coded in PHP. Adobes new Eclipse-based IDE, Flash Builder 4.5 for PHP, was co-developed by Adobe and Zend Technologies. Its one of the more interesting cross-platform integrations in a long time. This Refcard will show you how to profit from this marriage of tools created by the leaders in the RIA and PHP development arenas.
HTML Preview
Getting Started With Integrating PHP and Flex

Adobe® Flash® BuilderTM 4.5 for PHP: Adobe/Zend Tools for the PHP Professional

By Marco Tabini

WHAT IS FLEX?

Flex is an open-source framework developed and distributed by Adobe Systems. It is based on the Adobe® Flash Platform and primarily provides a streamlined approach to the development of Rich Internet Applications.

Flex eliminates many of the designer-oriented features of Flash in favor of establishing a development environment that caters more to programmers. As such, you will find that Flex encompasses many of the concepts that you are already familiar with if you have developed front-end systems using JavaScript or, indeed, most other GUI programming environment, allowing you to take advantage of the underlying Flash infrastructure without having to worry about concepts like timelines, assets, and so on.

Flex is multi-platform—this means that, with some exceptions, you can run a Flex application on any platform that supports Adobe Flash Player. If your users run on Windows, OS X or Linux and their browsers have a recent version of the Flash Player plug-in installed, they will also be able to run your Flex applications without a problem.

Because Flex is open source, there is no cost associated with creating and distribution applications that are based on it.

Hot Tip

You can download Adobe Flex SDK for free directly from the Adobe website at http://www.adobe.com/products/flex/

What is Adobe AIR?

The Adobe Integrated Runtime (Adobe AIR) is a companion technology to the Flex framework that extends the functionality provided by the latter into desktop application development. With AIR, you can build Flex applications that can be deployed as native applications on your user's machines, thus gaining all the advantages of running in a desktop environment.

Like Flex, AIR is also cross-platform, which means that you can write your code once and immediately deploy it across multiple operating systems. Because they run natively rather than in a web browser, AIR applications also gain access to functionality that is usually restricted by the Flash Player's security model, such as local file manipulation, unrestricted access to the network, and so forth.

What is Adobe Flash Builder?

Flash Builder 4 is Adobe's IDE for developing Flex and AIR applications. Although Flash Builder 4 is not required in order to compile or run a Flex-based application, it significantly simplifies the process of Flex development by providing an integrated environment that includes code intelligence, real-time analysis, compilation support, live debugging and much more.

Flash Builder 4 is based on the open-source Eclipse IDE and can either be downloaded as a standalone product or as a plug-in for the latter. Like Eclipse, Flash Builder 4 is also crossplatform and runs on both Windows and OS X.

Hot Tip

You can download a 60-day trial of Flash Builder 4 from the Adobe website at http://www.adobe.com/products/flex/

BUILDING APPLICATIONS WITH FLASH® BUILDER™ 4 AND PHP

Even though Flex is based on Flash, you don’t need to be proficient in the latter in order to use the former.

Flex uses a language called ActionScript3 (AS3), which is itself derived from the ECMAScript standard. ECMAScript is the same basic definition on which JavaScript is based—therefore, if you have any familiarity with browser programming, it's likely that you will find your bearings in AS3 very quickly.

Flex applications are based on the concept of component. A component defines a container of behaviors and, optionally, of a user interface representation. Components can be visual or non-visual, depending on whether the provide an interface of some kind (like a button) or just functionality of some kind (like a library for connecting to a remote server).

The visual structure of a component can be easily defined using MXML, Adobe’s specialized brand of XML. Other than the use of specific namespaces, MXML is nothing more than well-formed XML code; by nesting multiple components, you can create complex GUIs without ever writing a line of code.

Creating Flex Applications

Flash® Builder 4 makes creating new applications as easy as following the steps of its New Application Wizard. Simple select New Flex® Project from the File menu, then choose a name and type for your application. If you intend to write code that will be executed inside a browser, choose "Web" for your application type; if, on the other hand, you want to build a desktop application, choose "Desktop" instead.

You newly-created Flex project will contain a component that represents the application's main entry point:


<?xml version="1.0" encoding="utf-8"?>
<s:Application
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx">
<fx:Declarations>
</fx:Declarations>
</s:Application>

From here on, you can add more components to your application simply by typing the MXML code that represents them in the appropriate order. However, Flash Builder 4's strength resides in its visual layout editor, which allows you to arrange and wire the different components that make up your user interface using a WYSIWYG approach. For example, you can add a DataGrid object to show the contents of a data structure and then a button to fetch the data–all enclosed in a VGroup object to provide the overall layout:

Flex’s powerful layout capabilities, like the rest of the framework, are also designed to be developer-friendly and are almost entirely based on standard CSS, with a few exceptions designed to make automated positioning easier.

Useful Flex Components

Flex provides a rich ecosystem of components that can be easily expanded to meet your needs. While many of its components are designed to closely mimic their HTML cousins, there are also a number that provide unique functionality. For example:

  • AdvancedDataGrid and DataGrid: display tabular data in a rich, editable environment.
  • DateChooser and DateField: simplify the process of choosing and formatting date values.
  • NumericStepper: allows the user to increment and decrement a numeric value.
  • RichEditableText: allows you to create a rich text editor with support for several formatting options (e.g.: italic, bold, etc.).
  • VideoDisplay/VideoPlayer: provide fully-featured and completely skinnable video players that can be embedded directly in your application.
  • HSlider/VSliders:allows the user to select a value by sliding a selector across a horizontal or vertical range.
  • HGroup/VGroup: automatically arrange their content horizontally or vertically. Combine to easily create complex layouts.
  • Accordion/TabNavigator: allow multiple content panels to stack and be displayed one at a time.
  • MenuBar/TabBar: add a menu or tab bar to your component.
  • Flex Charting: adds powerful charting abilities to your applications.

Hot Tip

While Flex Charting and AdvancedDataGrid were only available in the Professional version of Flex Builder 3, they are now included in all versions of Flash Builder 4.

Connecting to PHP with AMF Introspection

One of the most interesting features of Flex is that it is designed to provide powerful data connectivity capabilities in a variety of formats and protocols, including XML, SOAP, JSON and Adobe’s own AMF. In fact, in most cases you will be able to use Flash Builder 4 to connect your Flex application to a PHP backend without having to write a single line of code in either!

In order to use Flash Builder 4's PHP-aware functionality through AMF, you need to have direct access to the root directory of a copy of your site—either through a network share or on your local computer. To get started, select Connect to Data/Service… from the Data menu, then choose PHP from the list of available connectors. Flash Builder 4 will ask you to confirm that your project type is set to PHP, then specify both the location of your site's server root and its URL:

At this point, you can click "Validate Configuration" to make Flash Builder 4 run a simple test to determine whether it can access your site as expected, then OK to complete the set up process.

Now, Flash Builder 4 will ask you to choose a PHP class that will provide the entry point to which your Flex application will connect. If your code is not encapsulated in classes, you could create some simple stubs for the purpose of providing services to your Flash Builder 4 code. The wizard will automatically fill in the defaults for you based on the name of the PHP file that you select.

Hot Tip

In order for this system to work, it is important that the class you want to import be stored in a file of the same name [e.g.: Index inside index.php]. Otherwise, Zend_AMF will be unable to find it.

At this point, if you website does not include a copy of Zend_AMF, a Zend Framework module that Flash Builder 4 uses to marshal data, remote procedure calls and error management, you will be asked to download and install a copy. This is required because Flash Builder 4 makes use of Action Message Format (AMF), a protocol that PHP does not support by default.

Hot Tip

Your application does not need to use Zend Framework in order to take advantage of AMF—Flash Builder 4 will only use Zend_AMF in order to communicate with your server, independently of the rest of your code.

Flash Builder 4 will introspect your code and discover which methods the service makes available:

Once you click Finish, the wizard will create a series of classes inside your project that provide all the necessary functionality required to connect to your project and execute your web service.

Hot Tip

Remember that it is your responsibility to provide a security layer where required—for example, by passing a secure key to the service as appropriate.

Establishing Data Connections

Your application is now capable of connecting to the PHP backend, but the data that the latter provides is not yet wired to any of the controls.

Luckily, this, too, is something that can be done without writing a line of code. You can, instead, use the Data/Services panel, visible in the bottom tray of the Flash Builder 4 window, where all the remote data services defined in your application are visible:

All you need to do in order to connect the data returned by a service call to any of your components is to simply drag it from the Data/Services panel to the component. Flash Builder 4 will ask you whether you intend to create a new call, or use an existing one. In the former case, you will first need to specify the type of data returned by the remote service call, because the data connection wizard has no way of determining it by means of static analysis of your code.

Flash Builder 4 can, however, auto-detect the data type returned by a service call by making a call to it, or you can specify it by hand. Where a sample service call will have no adverse effects on your PHP backend, allowing the wizard to determine the return type automatically is usually sufficient and produces all the infrastructure required to handle the data on the Flex side.

Hot Tip

In order for your data to be used in a Flex application, it must conform to all the appropriate AS3 rules—for example, you cannont return objects with properties whose names are reserved AS3 keywords like protected or private, even if those are perfectly acceptable in PHP

Your Flex application now has access to all the data returned by your service. If, for example, you drag a service on to a DataGrid component, the latter will be automatically populated with all the appropriate data columns—all you need to do is remove those you don’t want displayed and rename the header of the others to the proper human-readable format:

Your application is now fully functional—if you execute it, you will see that the data service is automatically called as soon as the DataGrid object finishes loading. If the call is successful, the data is immediately loaded and displayed.

If you prefer to add a manual method of refreshing the information, you can simply drag the appropriate data call on to the button—this will create all the code needed so that, when the user clicks on it at runtime, the service will be called again and all the data automatically updated.

Differences between PHP and AS3 Data

While much of the data types are interchangeable between AS3 and PHP, there are some notable differences.

  • Integer values in PHP can either be 32- or 64-bit long, whereas, in AS3, they are always 64 bits. Therefore, you must be prepared for the fact that a numeric value passed from AS3 to PHP may be represented as a float even if it is, in fact, just a large integer.

  • String values in AS3 are always Unicode-compliant. It is up to you to ensure Unicode compliance on the PHP side.

  • Array values in AS3 can only have contiguous numeric keys starting at zero. If your PHP arrays have string keys or non-contiguous numeric keys, they will be represented as objects in AS3.

    You should avoid passing objects into AS3 that contain members whose keys are reserved keywords, as handling them will be inconvenient—and many of Flash Builder 4's facilities will refuse to work with them.

Under most circumstances, these issues are unlikely to affect your application because both AS3 and PHP have a significant amount of flexibility.

CONNECTING TO WEB SERVICES

SOAP

AMF is not your only choice when it comes to external connectivity from Flash Builder 4—almost exactly the same functionality can just as easily be used to connect to an XML web service powered by SOAP.

You can start the process by selecting Connect To Data/ Service… from the Data menu and then choosing WSDL as the service type. This will bring up a dialog box that asks you to provide the URL of the service's WSDL specification:

Like before, Flash Builder 4 will fetch the WSDL file from the server and introspect it, extracting all the available remote procedure calls. You will then be able to drag and drop the data into your application like before.

Accessing XML Services

Of course, SOAP is not the only way of retrieving XML data from a remote location. Flash Builder 4 provides facilities for introspecting a remote URL that simply returns a flat XML document and extracting information from it.

Once again, you will need to click on Connect To Data/ Service… from the Data menu and, this time, choose XML as the service type. Flash Builder 4 will ask you to provide the URL of the service you wish to access, invoke it and create a stub class in AS3 to encapsulate the data:

The resulting data provider will become available in the Data/ Services panel of Flash Builder 4's GUI, from where you can connect it to your components like before.

Hot Tip

Be mindful of the fact that, when manipulation raw XML, Flash Builder 4 has no way of determining whether your service provides data in a consistent format. Therefore, you should ensure that this is the case, or your service call may unexpectedly fail at runtime.

JSON and XML

JSON (JavaScript Object Notation) has rapidly become a very popular choice for web service development because of its simplicity, lightweight format and ease of use in a number of languages.

While PHP has had built-in support for JSON since version 5.2.0, AS3 does not have any facilities for manipulating JSON data. Luckily, Flex provides a number of different ways for using JSON.

To start, you will need a PHP script that takes zero or more parameters either through a GET or POST HTTP transaction and outputs JSON-formatted data. For example:


<?php
function getTimeline($user) {
	$data = json_decode(
		file_get_contents("
			http://api.twitter.com/1/statuses/user_timeline.
			json?screen_name=" . urlencode($user)));
	
	foreach($data as $v) {
		unset($v->user->protected);
	}
	return $data;
}
echo json_encode(getTimeline($_GET['user']));

The simplest way of connecting to this service consists of once again using the Data/Service Connector wizard to access arbitrary HTTP-based web services. Choosing "HTTP" from the Connect To Data/Service… menu will result in this dialog, where Flash Builder 4 asks for the URL of the service and its parameters:

Once you provide the correct information and click on Finish, the wizard will once again create all the infrastructure required to run your service and make it available as before. The HTTP Data/Service Connection wizard also supports XML data.

DEPLOYING YOUR APPLICATION

In most cases, you will want to develop your application in Debug mode. This causes the Flex compiler to add all sorts of useful information that can be used to debugger to help you address any issues that may occur within your application.

However, when it comes time to deploy your application for production, you will want to switch to a Release build so that you can end up with the most compact and efficient codebase possible. You can do so by selecting Export Release Build... from the Build menu.

Exporting a Release build causes a new directory, called binrelease, which contains a number of different files:

Most of these files play a support role to your application—in fact, the only one you will normally interact with is the host HTML file that contains the code required to display your application.

Hot Tip

You can change the template used to generate your host HTML file by editing the html-template/index.template. html file in your application's root directory.

Passing Data to Your Flex Application

It is sometimes useful to pass data, like request parameters, to your Flex application as it is being initialized on the client browser.

This can be accomplished by introducing a special parameter in the HTML code that causes the application to be embedded in the web page. In reality, Flex provides a series of convenient wrappers that make the job even easier; if you look inside your HTML template, you will find a portion of code that looks like:


var flashvars = {};
...
swfobject.embedSWF(
		"Fle.swf", "flashContent",
		"100%", "100%",
		swfVersionStr, xiSwfUrlStr,
		flashvars, params, attributes);

All you need to do is change the content of flashVars to suit your need—that same data will be made available inside the application as the FlexGlobals.topLevelApplication.parameters object, where you can peruse it as needed.

Understanding the Security Model for Flash

When running in the browser, Flash employs a very strict security model that places your code in a sandbox through which all network and disk activities are regulated.

Hot Tip

For more information about the Flash security model, read the "Security" section under "Application architecture" in the Flash Builder help online at http//help.adobe.com/en_US/Flex/4.0/UsingSDK/

The sandbox is turned off during debugging—therefore, you don't normally become aware of it until you run your code in production mode and find out that your application cannot access any of its remote data.

Flash supports a number of different sandboxes, depending on what kind of data your application needs to deal with. Most of the time, you will want to use the local-with-networking sandbox, which allows your application to access remote locations, but denies all access to local files.

By default, the sandbox model prevents an application from accessing any resources outside of its own domain, unless that domain specifically grants access with a crossdomain.xml file. Therefore, it is important to remember that you may not be able to access information across different domains.

Hot Tip

Adobe AIR applications usually run in the local-trusted sandbox and, therefore, are not subject to connectivity restrictions.

Documenting Your Code with ASDoc

While much of the functionality provided by Flex can be accessed without writing significant amounts of AS3 code, it is entirely possible to address extremely complex tasks entirely within the Flex runtime — systems as complex as encryption engines and image compression libraries have been built in pure AS3 and are used in production every day (in fact, the entire Flex framework itself is built in AS3 as well).

Through a featured called ASDoc, Flash Builder 4 allows you to write inline comments that can be used to document your entire codebase. The syntax used by ASDoc is very similar to the PHPDoc syntax that is commonly used to comment PHP code; for example:


/**
* Performs some important function
*
* @param event The event dispatched to this method
*/
protected function handler(event:FlexEvent):void
{
	// Do something
}

Flash Builder 4 will automatically scan your code and add any information you write as part of your ASDoc blocks to its code intelligence features; these, in turn, will display the information as you use your code, providing you with a handy dynamic reference for your classes and methods:

About The Author

Marco Tabini

Marco Tabini is the co-founder, with Arbi Arzoumani, of php|architect, the world's largest PHP magazine in the English language, currently distributed in over 145 countries. He is also the co-founder, with Keith Casey, of Blue Parabola, LLC, a consulting firm that specializes in information architecture, code and security auditing, large-scale deployments and optimization.

An accomplished author on the subject of PHP and the business of web development, Marco is also a frequent speaker at PHP and OSS conferences throughout the world.

Recommended Book

Flash Builder 4 and Flex 4

Create desktop applications that behave identically on Windows, Mac OS X, and Linux with Adobe's new Flash Builder 4 platform and this in-depth guide. The book's tutorials and explanations walk you step-by-step through Flash Builder’s new, faster tools; the new framework for generating code; how to connect to popular application servers; upgrading from Flex 3; and much more.


Share this Refcard with
your friends & followers...

DZone greatly appreciates your support.


Your download should begin immediately.
If it doesn't, click here.

Getting started with Drupal? Check out this cheat sheet!

Download our Getting Started with Drupal Refcard now! 

0 replies - 5075 views - 06/23/09 by Lyndsey Clevesy in Announcements