4. User facing software

After slugging through the preliminary information necessary to understand developing PHP in a non-web context, we’re now getting to the nitty-gritty of how to start communicating with our users without the rendering engine of a web browser.

Some software sits and happily runs without any interaction from humans, we’ll call this “system software” and will examine it in Chapter 6. However a large proportion of software requires interactivity with the user, and there are a number of different ways of performing the interaction in PHP. From interactive command lines through to fully fledged GUI (Graphical User Interface) based software, it can all be done with PHP.

When choosing how your software interacts with humans, you need focus on the needs of the user and put your own preferences to one side if at all possible. Command line interactions are (usually) very straight forward to code, text is, well, just text and it’s what PHP excels at. However many users, particularly non-technical users, shy away from text based CLI software. Unless you are meticulous about your software structure and interface flow, text based input can be :

  • prone to error
  • hard to navigate
  • require mental agility on the part of the user
  • have low discoverability
  • and be initially slower to use than a GUI

If you choose a text based interface, make sure your target users will be happy with it (you may be, but often your users aren’t much like you!). Text interfaces, because of the simplicity of coding, can often be a good choice for proof-of-concept and prototype software (particularly where the main benefits of the application are in what it does, not in how the user interacts with it), but be aware that temporary interfaces have an uncanny way of “sticking around”. Additionally, some non-technical commissioning users (the words “pointy-haired-boss” spring to mind here) can’t see past an interface to the application beneath and may not be happy with your proposed project, even after you explain that the interface is just temporary. This is understandable to some extent as, for most users, the application IS the interface. It is all they see and use day-in day-out. The changes to their files and other functions performed just happen by “magic” of course. Good user interface design (whether it be for text based interfaces or fully-fledged GUIs) is a field of endeavour in and of itself, so get help from the professionals where you can, read some of the multitude of books available on the subject, or take a course. If you ever looked at a piece of software and wondered how it got so popular while your preferred, much more functionally superior software, languished in obscurity, the answer is often at least partly down to good user interface design.

4.1 Command line interface basics

As described above, there are still uses for text-based interfaces, particularly in environments with technically-adept users. When creating a text based program to run on the command line, there are three primary considerations over-and-above the PHP you are already accustomed to. These are

  1. Getting keyboard input
  2. Outputting text (and graphics) to the screen
  3. Program flow control

Rather than describe each one in isolation, we will instead look through a simple program that contains elements of each. Read through the code and comments below. The program is a screen-saver type routine which fills the shell with colour via a wiggling snake-like cursor.

You are reading a book sample. This rest of this section is available in the full book.

4.2 Advanced command line input

You are reading a book sample. This rest of this section is available in the full book.

4.3 Using STDIN, STOUT & STDERR

You are reading a book sample. This rest of this section is available in the full book.

4.4 Partial GUI elements - dialogs

You are reading a book sample. This rest of this section is available in the full book.

4.5 Dialogs invoked from the shell

You are reading a book sample. This rest of this section is available in the full book.

4.6 Windows dialogs

You are reading a book sample. This rest of this section is available in the full book.

4.7 Static HTML output

You are reading a book sample. This rest of this section is available in the full book.

4.8 Complete graphical interfaces (GUIs)

Many users expect full graphical user interfaces (GUIs) these days, with very good reason. GUIs, when done right, are good for discoverability and ease of interaction. They can provide intuitive human-friendly ways of presenting data and information and are ideal for event based programming.

Most GUI programs are written to use “Widget Toolkits” (also known as GUI Toolkits). These are toolkits or frameworks that provide code for the building blocks of GUIs; windows, forms, buttons, lists, mouse interactions, menus, events and more. There are a large number of widget toolkits, some are low-level and platform specific such as the Windows API for Windows or Carbon for Mac OS X, some are higher level and cross platform like GTK+ and QT, and some are language specific, such as Swing for Java and LCL for Object Pascal. There is a fairly comprehensive list on Wikipedia.

Further Reading

Widget Toolkits on Wikipedia
http://en.wikipedia.org/wiki/List_of_widget_toolkits

Two approaches exist in PHP for using these toolkits to make graphical interfaces. The first is via direct bindings - your PHP script invokes the toolkit directly via a library or PHP extension. The second is via a helper application - your PHP script tells the helper application what it wants to display using an intermediate language like HTML or XUL, and the helper application deals with calling the necessary elements of the toolkit (or its own code) and displays the interface for you. The former is the traditional way of writing graphical applications, the latter is more akin to the web approach (where the browser is the helper application to which your scripts send HTML). Both approaches have pros and cons, below we will look at some of the current implementations of both methods.

4.9 Understanding GUI and event-based programming

It’s worth spending a few moments at this point talking about one of the main differences between GUI apps and, for instance, command line programming. Most GUI programming is event-based programming, which can sometimes take a while to get your head around if you’ve not programmed using this style before.

With a GUI program, you typically start programming “sequentially” as normal by opening a window or form and populating it with buttons, text, images, data or whatever.

At this stage your program then goes into a waiting loop, usually waiting for the user (or sometimes the system) to do something. That may be waiting for them to click a button, enter some text, select an option or wait for a new item of data to arrive. Each of these things is called an event, and you typically can’t predict in which order they will happen. So your code will bind these events to functions or methods, and call these as the relevant events occur.

This means that your code is often executed out of sequence, so keeping abreast of state becomes much more nuanced than in command line scripts and even web scripts, which run sequentially from top to bottom. The most common way of dealing with event based programs is to use Object-Oriented (OO) programming techniques, and indeed the rise of GUI software drove the rise in OO programming (or followed on from it, depending on who you talk to). Its still perfectly possible to use traditional “imperative” style programming of course, particularly if you are careful around issues such as state and scope, but if you intend to do a lot of GUI programming and aren’t familiar with OO, you may be doing yourself a favour if you pick up an OO primer and have a quick flick through.

Further Reading

Object-oriented Programming on Wikipedia
http://en.wikipedia.org/wiki/Object-oriented_programming

“Introduction to PHP OOP” by Lorna Mitchell
http://www.lornajane.net/posts/2012/introduction-to-php-oop

“Object-Oriented PHP for Beginners” by Jason Lengstorf
http://net.tutsplus.com/tutorials/php/object-oriented-php-for-beginners/

Web programming is of course event-based in a sense, you typically present an HTML page to the user and then wait for them to click a button or link, and handle that “event” with a different HTML page (or another run through of the same script with different parameters). Each of your HTML pages (or the PHP scripts that generate them) is in some-way equivalent to the individual functions or methods called in our GUI scripts, and your web server (Apache etc.) is equivalent to the waiting loop in our GUI program that holds things together and reacts to our events. The difference is that in web based programming, with PHP in particular, we operate on a shared-nothing (or almost nothing) basis - each script execution or HTML page fetch is deliberately separate from another unless we otherwise act to share some state. In GUI programming, we are typically operating from within the same script set under one process, and thus it is a share-(almost)-everything architecture. Once you’ve got your head around this concept, you will find it much easier to plan and map out your software.

Now lets look at some of the GUI toolkits available.

You are reading a book sample. This rest of this section is available in the full book.

4.10 wxPHP

You are reading a book sample. This rest of this section is available in the full book.

You are reading a book sample. This rest of this section is available in the full book.

Let’s have a look at some sample wxPHP code. This will help you understand how a GUI application is typically structured in PHP and how it differs from a typical web application. Although the code below is wxPHP specific, many GUI toolkits at least follow the same kind of Object-Oriented, event based structure. The following code was written by, and is reproduced with the kind permission of, the wxPHP project. The inline comments are mine.

  1 <?php
  2 
  3 # Each frame or window is designed by extending the wxFrame class and
  4 # adding graphical elements like buttons, menus, text boxes and so on,
  5 # as well as any functions to react to "events" like mouse clicks and 
  6 # window closes. 
  7 
  8 # We'll create a class "MainFrame" that describes our application's window
  9 
 10 class MainFrame extends wxFrame
 11 {
 12 
 13 	# We'll add a function that destroys the frame object when we quit.
 14 
 15 	function onQuit()
 16 	{
 17 		$this->Destroy();
 18 	}
 19 
 20 	# We'll add a function to display an "about" dialog to display some
 21 	# information about the application
 22 
 23 	function onAbout()
 24 	{
 25 		# "wxMessageDialog" is one of the many components or "widgets" 
 26 		# available in the toolkit. This saves you having to create a 
 27 		# new frame/window to display your message.
 28 
 29 		$dlg = new wxMessageDialog(
 30 			$this,
 31 			"Welcome to wxPHP!!\nBased on wxWidgets 3.0.0\n\n".
 32 			"This is a minimal wxPHP sample!",
 33 			"About box...",
 34 			wxICON_INFORMATION
 35 			);
 36 
 37 		# Show the dialog box we create above. 
 38 
 39 		$dlg->ShowModal();
 40 	}
 41 
 42 	# Add a constructor function. This function is run when we create our
 43 	# application window by creating a new object from this class.
 44 
 45 	function __construct()
 46 	{
 47 		# This calls the constructor function from the wxFrame class that
 48 		# we have extended, creating a frame with the title 
 49 		# "Minimal wxPHP App" in the default position on screen, with
 50 		# the initial size of 350 x 260 pixels. Note that this frame is
 51 		# not visible by default, it's just created in memory at the 
 52 		# moment. This means that we can add things to it and fully 
 53 		# prepare it before we show it to the user, rather than the 
 54 		# user seeing a blank window that then suddenly fills with 
 55 		# buttons etc.
 56 
 57 		parent::__construct(null, null, "Minimal wxPHP App", 
 58 			wxDefaultPosition, new wxSize(350, 260));
 59 
 60 		# We're going to add menus to our window with various options,
 61 		# which means first adding a menu bar into which we put the menus. 
 62 
 63 		$mb = new wxMenuBar();
 64 
 65 		# Now we add the menus. First a "File" menu with a "Quit" option
 66 
 67 		$mn = new wxMenu();
 68 		$mn->Append(2, "E&xit", "Quit this program");
 69 		$mb->Append($mn, "&File");
 70 
 71 		# And now a "Help" menu with an "About" option.
 72 
 73 		$mn = new wxMenu();
 74 		$mn->AppendCheckItem(4, "&About...", "Show about dialog");
 75 		$mb->Append($mn, "&Help");
 76 
 77 		# Note the menu and options above all have "&"" symbols in. This
 78 		# comes before the letter that should be used for keyboard
 79 		# shortcuts. Using a widget toolkit like this means that you don't
 80 		# have to write your own code for managing things like keyboard
 81 		# shortcuts, saving you time and effort and creating a consistent
 82 		# experience for your users.
 83 
 84 		# Finally add the menu bar to the frame.
 85 
 86 		$this->SetMenuBar($mb);
 87 
 88 		# Lets add a source-code editing box to the frame, which is 
 89 		# another one of the available widgets in the toolkit and has 
 90 		# functionality like syntax highlighting, smart indentation etc.
 91 
 92 		$scite = new wxStyledTextCtrl($this);
 93 
 94 		# The final widget we're going to add is a status bar at the 
 95 		# bottom of the window.
 96 
 97 		$sbar = $this->CreateStatusBar(2);
 98 		$sbar->SetStatusText("Welcome to wxPHP...");
 99 
100 		# At the start of this class we defined a couple of functions, one
101 		# to show an about box, and one to quit the app. On their own
102 		# they won't do anything, we need to connect them to the menu
103 		# options we created earlier. More specifically, to the 
104 		# "wxEVT_COMMAND_MENU_SELECTED" event which is called when the 
105 		# user selects something from the menu.
106 
107 		$this->Connect(2, wxEVT_COMMAND_MENU_SELECTED, 
108 			array($this,"onQuit"));
109 		$this->Connect(4, wxEVT_COMMAND_MENU_SELECTED, 
110 			array($this,"onAbout"));
111 	}
112 }
113 
114 # We've now designed our frame and populated it with widgets and functions
115 # but at this stage in the code it doesn't yet exist. We need to create
116 # a new object using our class, which will bring it to life and call 
117 # the constructor function above.
118 
119 $mf = new mainFrame();
120 
121 # The frame now exists, it is populated with widgets and the functions
122 # are all hooked up to the events. However it is hidden, so we need
123 # to make it visible.
124 
125 $mf->Show();
126 
127 # At this point, we need to let wxWidgets take over and run the show.
128 # Calling wxEntry lets wxWidgets manage the application, wait for and 
129 # react to events and call the functions that we've previously specified.
130 # As you can see, we need to have specified all of our applications code
131 # before we get to this point.
132 
133 wxEntry();  
134 
135 # If we reach this point, it means that our application has quit (either
136 # the user has closed it or something in our code has closed it), and 
137 # we can either do any tidy-up necessary or just quit.
138 
139 ?>

You are reading a book sample. This rest of this section is available in the full book.

4.11 PHP-GTK

You are reading a book sample. This rest of this section is available in the full book.

4.12 Local web server & browser

One general technique that has been employed with varying degrees of success when creating local PHP apps is to deploy the whole web stack locally on each PC. This means installing a copy of PHP and Apache (or Nginx, or similar) and accessing the PHP webpages over a local port (e.g. http://127.0.0.1:80) in a web browser.

Pros:

  • Re-use existing web code and web skills, mostly as-is
  • Cross platform

Cons:

  • Heavy resource overhead for the web-server
  • Non-native experience
  • Must be secured to stop external access
  • Web servers can be temperamental if not properly tuned to the system it’s on
  • Large maintenance overhead
  • Larger vector for security exploits
  • Performance hit of using the verbose HTTP protocol for UI->backend interaction
  • Cross-browser compatibility issues occur in the same way as the web, unless a particular browser is deployed or required.

In general this is definitely one to avoid if at all possible, certainly for public distribution of software. It may be worth considering where you have existing web applications you need to deploy in short-order on local machines that you have responsibility for and control over.

If you are going to go down this route, it is worth considering deploying an existing stack “solution” which have already ironed out some of the issues involved in local deployment of web stacks. A handy list of “LAMP” ( LinuxApache/Mysql/(PHP|Perl|Python) ) type stacks can be found on Wikipedia, and likewise a comparison of WAMP (Windows/AMP) stacks can be found there too. Remember that while the solution is generally cross-platform, the set-up and fine-tuning of the web stack can vary a lot across different OSes, depending on exactly what you are trying to achieve and the complexity of your application.

Further Reading

List of AMP (inc LAMP & WAMP) type stacks on Wikipedia
http://en.wikipedia.org/wiki/List_of_Apache%E2%80%93MySQL%E2%80%93PHP_packages

4.13 PHP’s Built-in testing server

Since v5.4, PHP comes equipped with a built-in web server, primarily designed for testing purposes. It is intended to be used locally by single users rather than on the public web, so lacks the performance, security and resource management controls a fully-fledged web server like Apache has, and is not extensible by means of modules and the like. Nevertheless, a lightweight server like this makes more sense for local apps than the Apache based solution described above, where these extra facilities aren’t generally required. That said, it still has a longer than desirable list in the “Cons” section.

Pros:

  • Re-use existing web code and web skills, mostly as-is
  • Cross platform
  • No extra server to deploy beyond PHP itself

Cons:

  • Non-native experience
  • Must be secured to stop external access
  • The PHP developers have explicitly stated that it was designed specifically for the testing/development environment.
  • Performance hit of using the verbose HTTP protocol for UI->backend interaction
  • Cross-browser compatibility issues occur in the same way as the web, unless a particular browser is deployed or required.
  • Not all features of servers like Apache are included, so some re-writing of the web app may be required if these are relied upon.
PHP Built In Web server
   
  PHP’s own built-in test web server
   
  Main website : http://php.net/manual/en/features.commandline.webserver.php
   
  Installation info : Installed as part of standard PHP install
   
  Main documentation : http://php.net/manual/en/features.commandline.webserver.php
   
  Tutorial
   
  “Taking Advantage of PHP’s Built-in Server” by Vito Tardia
  http://www.sitepoint.com/taking-advantage-of-phps-built-in-server/

4.14 Web sockets & browser

A variation on the web server/browser scenarios above is using Web Sockets, part of the evolving HTML5 specification designed to allow 2-way communication and “push” type data flows in the browser. LAMP type stacks and the PHP Built in Web Server don’t, by default, handle Web Socket connections. The specification is quitep new and browser support varies, and you’ll need to deploy a dedicated web socket server or a PHP web socket server library (usually based on spawning PHP CLI processes to handle communications). Beyond that, the pros and cons are roughly the same as those discussed for traditional web server communications. Due to the “push” ability of sockets, communications may be quicker and less frequent.

Ratchet
   
  Popular PHP WebSocket library. Uses ReactPHP.
   
  Main website : http://socketo.me/
   
  Installation info : http://socketo.me/docs/install
   
  Main documentation : http://socketo.me/docs
whippy.php
   
  A pure PHP WebSocket server
   
  Main website : https://github.com/rthrfrd/whippy.php
Web Socket Service
   
  A PHP package to handle Web socket accesses using child processes
   
  Main website : http://www.phpclasses.org/package/7259-PHP-Handle-Web-socket-accesses-using-child-processes.html
Web Socks
   
  A Web Socket server written in PHP. It implements the version 76 handshake.
   
  Main website : http://code.google.com/p/web-socks/

4.15 SiteFusion

SiteFusion is a GUI solution based on the Mozilla XULrunner. XULrunner is the Mozilla technical platform on which applications like Firefox and Thunderbird are built, and it is a general purpose XUL/HTML/Javascript runtime. Rather than providing a totally local solution, SiteFusion focuses on the server-client scenario. A local client helper “XULrunner” application in installed on the client PCs, but the PHP application code lives on the server running under custom SiteFusion server software. It is possible to install the client and server on the same machine, however many of the “cons” listed in “Local web server & browser” apply to this configuration. SiteFusion exposes XUL as the primary method of building the interface, which although similar to HTML still has a learning curve. HTML can of course be used as XUL has the browser element, however SiteFusion doesn’t provide any abstraction of the HTML/DOM to assist working with the contents of the browser element. Some HTML tags can be used directly within XUL code (outside of browser element), however Mozilla advise against this for various reasons. SiteFusion’s main market target and the area in which it is definitely worth considering is with client-server apps, where central control over the application is desired and it is deployed on a local network within one organisation.

Pros:

  • Native experience
  • Cross-platform
  • Designed for client-server applications
  • Stable, mature project with ongoing development

Cons:

  • Responsiveness can be subject to network delays
  • Not ideal for local-only installs
  • XUL is less common than HTML, so less documentation, support, toolkits etc., although HTML components can be run in the browser element and some Javascript tools/components will operate in/on the XUL interface.

Comprehensive tutorials and documentation can be found on the SiteFusion.org website.

SiteFusion
   
  XUL based client-server PHP GUI system
   
  Main website : http://sitefusion.org/
   
  Installation info : http://sitefusion.org/10
   
  Main documentation : http://sitefusion.org/tutorials

4.16 Winbinder

Winbinder provides PHP direct bindings for the Windows API. Thus, it only works on MS Windows based platforms (or under Windows compatibility layers like Wine on Linux). The current status of the project is unknown, the website is still functioning and the files are available for download. However the community forum has been closed down, there are no news posts and the system only appears to support older Win32 style interfaces.

Pros :

  • Provides direct bindings to the Windows API
  • PECL package available

Cons :

  • Questionable project status/activity/future
  • Not cross-platform
  • Out of date interfaces
WinBinder
   
  Windows API based GUI toolkit
   
  Main website : http://winbinder.org/
   
  Main documentation & Installation info : http://winbinder.org/manual.php

4.17 Adobe AIR

An alternative to a web browser for LAMP stack or PHP test server deployments, Adobe AIR lets you create local HTML/Javascript applications that run using the Adobe Integrated Runtime (or AIR). While Adobe envision you creating your whole application in HTML and Javascript, and allow privileged access to the file system, off-line storage and more, you can easily hook up your “web” application to PHP scripts in the same way a browser would. In essence, the AIR app is your browser. This provides a better visual environment than a browser, but still has most of the same draw-backs listed above. Adobe have also recently withdrawn support for Linux, although they do support mobile and e-reader platforms. In the latter case you may not be able to run the PHP portion of your app locally.

Adobe AIR
   
  Runtime supporting HTML & Javascript apps that can replace a browser
   
  Main website : http://www.adobe.com/products/air.html
   
  Main documentation & Installation info : http://www.adobe.com/devnet/air/documentation.html
   
  Commercial video course : http://my.safaribooksonline.com/video/programming/air/01220110006si

4.18 NW.js (formerly node-webkit)

Similar in concept to Adobe AIR, NW.js allows you to create HTML & Javascript apps with elements of the Chrome browser (namely the scripting and rendering engines). You can use this to create a custom browser for your local or remote PHP app. As an open project based on an actively developed browser, it may be a safer and more standard option than Adobes offering.

NW.js
   
  Runtime supporting HTML & Javascript apps that can replace a browser
   
  Main website : http://nwjs.io/
   
  Main documentation & Installation info : https://github.com/nwjs/nw.js

4.19 Atom Shell

A new contender to NW.js, Atom Shell is the Javascript APP runtime developed by Github to power their Atom editor. Like NW.js it uses parts of Chrome, but instead of the Node version of the Javascript engine it uses io.js, a fork of Node which is now more actively developed. Atom Shell itself is newer and less mature than NW.js, but is rapidly proving itself.

Atom Shell
   
  Runtime supporting HTML & Javascript apps that can replace a browser
   
  Main website : https://github.com/atom/atom-shell
   
  Main documentation & Installation info : https://github.com/atom/atom-shell/tree/master/docs#guides

4.20 Titanium

Titanium is similar in concept to Adobe Air, and essentially the pro’s, con’s and usage of both is the same. However this could easily have been so different, as the early versions of Titanium had integrated support for PHP as a first class language. That means that you could use PHP within your HTML, in the same way you used Javascript. No server. This meant that you could run PHP code on your page, directly access the page DOM and do everything that PHP does. However as of v2 Appcelerator withdrew that functionality to focus on Javascript only. Although older versions of the opensource core product are still available with the PHP functionality, this entry is more of a historical note on what could have been.

Appcelerator Titanium
   
  Runtime supporting HTML & Javascript apps that can replace a browser
   
  Main website : http://www.appcelerator.com/
   
  Main documentation & Installation info : http://docs.appcelerator.com/
   
  Now removed PHP functionality : http://matthewturland.com/slides/titanium/
   
  Appcelerator Licensing Controversy : http://arstechnica.com/information-technology/2012/09/when-free-isnt-developer-accuses-tool-vendor-of-extorting-customer/

4.21 PHP-Qt

PHP-Qt is an extension to provide PHP bindings for the popular cross-platform QT widget toolkit. This project appears however to have last released code in 2007 and been abandoned in 2009. It is mentioned here only for completeness, the code is still available for download and may be of interest for someone attempting to develop a similar solution.

PHP-Qt
   
  Defunct project to provide bindings for the QT toolkit.
   
  Information : http://en.wikipedia.org/wiki/PHP-Qt

4.22 PHP/TK

PHP is a project last updated in 2004 proving bindings for the TCL/TK X-windows interface toolkit. As with PHP-Qt above, it is mentioned here only for completeness.

wxPHP
   
  Bindings for the TCL/TK toolkit.
   
  Main website : http://php-tk.sourceforge.net/
   
  Using PHP/TK with Delphi/Lazarus : http://web.fastermac.net/~MacPgmr/PhpTk/PhpTkStatus.html