PHX 1.3 License: BSD

A thin PHP Application Platform

By Abdallah Al Sumairi (abdallah@farashat.com)

PHX Sourceforge Website | PHX Sourceforge Forum | PHX Download

Introduction

PHX is a very thin platform to develop modular PHP web applications. PHX organizes your web application into smaller applications or modules. Each application is located in a separate directory. Each application responds to commands by executing a code, and a layout file for each command. There is a common application layout file for each application. PHX supports nested layouts by also executing layout file of parent applications, before formatting the final output.

PHX is only one file: 'phx.php', which is called with each request. A request is basically a browser GET or POST. PHX looks for the request stored in the variable "phx_c" ("phx_c" can be changed to any other name, such as "action"). An example request is the URL: "./?phx_c=phx.register". This is the "register" command issued to the root application. This is another URL: './?phx_c=phx.members.display'. This is a "display" command requested from the "members" application, which is directly located under the root application, basically a subdirectory called './members/'. You can of course have infinite number of nested applications. Notice that the request consists of words separated by dots. Command is right most word, while the left most word is always the root application.

Objective

PHX aims to minimize the time required to start new PHP web applications, by providing a "fill-the-blanks" method to develop applications. Still, one big advantage of PHX is easing the development of very complex applications. Similar to event-driven development platforms, PHX divides your project tasks into smaller applications, and divides applications into commands. Each command has its own code file and its own layout file. This achieves code/layout separation in addition to modular design of web applications.

One big advantage of this organization is making it easy for project teams to co-develop big application by letting each developer focus on certain applications or commands, or even layout and code. Another related advantage is that this modular design leads to higher maintainability and code-isolation, which means that when certain code collapses, it doesn't affect the rest of the application.

Scope

PHX objective is to take control of how you organize your files, and most importantly, how you organize your code. Each functionality you want to add is called a 'command' and: (1) exists within an application, (2) has a code file, whether a dedicated code file (the default) or a shared code file, with other commands. And (3) has a layout file. Each application has its own directory by default, and must handle at least the 'index' command. Every application can have one application layout file, common for all of its commands. And optionally can have a local configuration file, in addition to the global configuration file located in the root directory.

PHX is very thin and simple. Providing a very high performance platform with low overhead. PHX proves its high added value through simple design and high performance in addition to its objective to provide a platform to easily develop and maintain web applications. PHX is not meant to be a functionality-enhancement tool. It doesn't provide extra functionality such as APIs to send e-mails, access file system, or a set classes to encapsulate user tasks. PHX will never provide this in the future. This is because it's meant to be and stay thin, and focused to do a very defined task. Security is not in the scope of PHX. However, PHX is thin enough that anything can be built on top of it.  A plan is in place to develop a platform on top of PHX consisting of user functions and/or user classes to handle common user tasks, to use it as a RAD tool in order to develop web applications such as CMS and BB applications. This coming platform, which is layer 2 (PHX is layer 1, while raw PHP is layer 0), should handle user tasks such as e-mailing and DB functions. It should also handle security issues.

Installation

PHX framework is actually one file: "phx.php". Copy this file into your web application root, and in your index.php just include the PHX PHP file. Of course you can rename "phx.php" to "index.php". Same thing.

Concept

Where you dropped the "phx.php" file is called your root application. You can create sub-application (or modules) by creating sub-directories. Each application has its own set of "Commands". At least one command, which is the "index" command. This command may view the application homepage. For example, the application called "Forum" will have these commands: index, viewForum, viewTopic, newTopic, adminIndex, etc. PHX looks for certain files:

  1. PHX configuration file: "./phx_config.php".
  2. Global configuration file: "./app_global.php".
  3. Application configuration files: "app_local.php" files.
  4. Command code files: "cmd_<command name>.php".
  5. Command layout files: "layout_<command name>.php".
  6. Application layout files: "app_layout.php".

Developing a generic PHX

Let's quickly start with an example

  1. Copy the "phx.php" and create "index.php" which should have one statement to include "phx.php", or you can just rename "phx.php" to "index.php".
  2. You don't need the "phx_config.php" file unless you want to override default settings.
  3. Create the file "cmd_index.php" this is important because each application has the default command "index", which must be handled. So, this file is required. Put in this file, the required code when the visitor enters the application. This is the root application. If you want to create a splash screen, you can use the "index" command, and designate another command "phx.home" to view the homepage.
  4. Create the layout file for the "index" command, call it "cmd_index.php", put your layout there. You can use the "$phxContent" variable to read all the "print" and "echo" output from the code file.
  5. Optionally, you can create the default layout file for the application, "app_layout.php". This should provide you with an application template for all commands for this specific application.
  6. Optionally, you can create configuration files. Create this file: "app_local.php", this will contain application-specific settings. In this case, the settings and common code for all commands in the root directory.
  7. Optionally, you can create the global configuration file: "app_global.php", which will run before any other code. Unlike the "app_local.php" file, which is located in each directory to initialize application specific settings, the "app_global.php" is only located in the root directory to run before any other script in you web.

About PHX commands

It's very important to understand how to format and send commands to PHX. Also, you must realize the security issue when filename is extracted from the URL, and how to create custom command handling to enhance security.

First, commands are sent via GET or POST methods, using the "phx_c" variable. The command is in the format of "ApplicationName.Command". This is the default command to view the homepage: "phx.index", and this is the command to edit one article using its ID in the Articles application: "phx.articles.editArticle&id=101". PHX will run the following file: "./articles/cmd_editArticle.php?id=101". After execution of this file, the layout file will be called. PHX API function "phx_url" can be used to format URLs. It's recommended to use it because it's SES-aware and will format your URL according to your SES setting.

As you can see, code file of the current command is called, and then the layout file is called before calling the application common layout file. As we saw before the very first file to run is "phx_config.php", followed by "app_global.php", next "app_local.php", before the command is considered.

The PHX.SimpleCMS sample application

Included with PHX, is a sample application to demonstrate the usage of PHX. Please open files and read comments and code to understand how to create structured applications.

PHX API & Settings

It's useful to know the different functions and variables to use in order to control your application using PHX. The following explains this. Notice that PHX is kept very simple, thin and focused.

  1. array $phx
    The main PHX configuration and runtime container. Use it to check if PHX framework is running. Sometimes a user may call the code file directly from the URL. This variable will only be set if PHX is active. So, something like this will protect your code and layout files from being directly called:
    <?php if (!isset($phx)) exit; ?>
  2. array $phxVars
    This array contains variable values, initially it's copied from $_REQUEST, which contains all $_POST and $_GET variables and values. It's used to make your application modular. If your command file uses this array instead of $_REQUEST, then it can be safely called by the "phx_mod" function, meaning your command file can safely act as a module, which can be executed from within another command file and its output will embedded. Example:
    <?php $setting1 = $phxVar["Setting1"]; ?>
  3. boolean $phx["layout_nesting"]
    Defaults to "true". Use this to disable/enable layout nesting. If enabled, each sub-application content will be formatted using the appropriate layout files, and then the output is stored in the variable 'phxContent', and then the parent layout file is called to do further formatting. This will allow your application to nest content to create CMS-like systems for example. You can change this settings in the "./phx_config.php" file.
  4. boolean  $phx["app_level"]
    A runtime variable, it is set to "1" in current application code and layout files. It will be incremented each time to indicate the depth of layout nesting. Very useful to hide certain code and/or layout from child applications. This variable is not accessible from "phx_config.php" and "app_global.php" files.
  5. string $phx["path"]
    This variable is set to the directory containing the command code file and the layout file. It's basically the path to the current application being run. So, you can use it in "if" statements to discover the application for example. The root application will have the value of: "./".
  6. string $phx["request"]
    This variable stores the complete request, which is the application name and the command. Examples: 'phx.app.subapp.childapp.command'. Useful to discover current request and direct your layout and code files.
  7. string $phx["command"]
    This variable stores only the command name, which is the right most word in the request variable. Usually, the code file name is decided using the path of the application and this variable. However, you can override it in the local (or global) configuration file.
  8. string $phx["code_file"]
    This variable stores the default code file name, allowing you to set your custom file name for a certain command, or a group of commands. This is useful for those who wish to ensure that only certain files are executed. The default value is formatted from the command name: 'cmd_COMMANDNAME.php'. If the request is: "phx.news.current.view", then this variable will have the value of: "./news/current/cmd_view.php".
  9. string $phx["layout_file"]
    Set initially to the default layout file for the current command. You can override it in the "app_local.php" file. By default each command has its own layout file, which is going to be nested in the "app_layout.php" file.
  10. string $phx["app_layout_file"]
    Defaults to 'app_layout.php' for all commands in the current application. This means that if left to the default value, each application will have a separate layout file for all of its commands. But this can be overridden, if you need to separate and/or share layouts.
  11. string $phxContent
    In layouts, this is the most important variable you'll deal with. Because it stores the layout of the application, which is propagated from code file to layout files, and from child applications to parent applications. Because of using output-buffering, each 'echo' and 'print' statement doesn't actually send content back to the user. Instead, content is buffered and at the end of each file execution is copied to this variable and then buffer is totally cleared. And then, a call to the next code/layout file, which will have a clean buffer, but also a variable containing the previous layout, allowing content nesting.
  12. string $phx["base_url"]
    This is detected automatically from the $_SERVER["PHP_SELF"] variable. It's very important only when SES is enabled (read below). This feature has been added since version 1.1, to solve a bug with the "phx_url" function when SES is anabled. Since the value is detected automatically, you don't need to do anything about it, but you can do that by setting it in the "phx_config.php" file.
  13. boolean $phx["enable_ses"]
    This setting, which defaults to "false", can be used to enable or disable the Search Engine Safe (SES) URLs. a SES URL is formatted from a normal dynamic URL to eliminate the characters: "?", "&" and "=" from the URL and replacing them with slashes "/". This emulates a static page URL. The advantage is allowing spiders to index these pages. Usually spiders ignore dynamic pages with query strings (located after the "?" sign of the URL) . This feature can only be enabled from the "phx_config.php" file. A sample ".htaccess" file for the apache server (with mod_rewrite) to enable this feature is:
    RewriteEngine on
    RewriteRule ^(phx\.[a-z0-9]+)(.*)$ index.php?phx_c=$1$2 [NC,QSA,L]
  14. string $phx["cvn"]
    CVN = "Command Variable Name", which is recognized by PHX as the variable storing the command (default is "phx_c"). This appears in the URL as: index.php?phx_c=phx.app.command.
  15. function phx_url(string $command [, string $query_string = ""]) : string
    This API function is very useful to format the URL, which is used to call applications, and sub-applications. Provide the command in the form: "app.cmd", and the second argument is an optional query string to send with the command. Consider this example:
    $url = phx_url("phx.news.add");
    Will set $url to call the page: "./news/cmd_add.php". And:
    $url = phx_url("phx.news.view", "id=90&style=2&s=100");
    Will set url to call the page: "./news/cmd_view.php?"id=90&style=2&s=100. This API complies with SES URLs. If the "enable_ses" value is "true", it will format the previous URLs to:
    "/phx.news.add", and: "/phx.news.view/id/90/style/2/s/100", respectively.
  16. function phx_mod(string $command, array $phxVars) : void
    This function executes a command file, and prints its output, allowing you to create modules and embed their output anywhere you want in the layout. For example
    phx_mod("cart.add", array("item_no"=>1234, "quantity"=>1));
    This will execute the "phx.cart.add" command, which is located it "cart/cmd_add.php" file and prints its output (if any) in the current context.
  17. function phx_reset() : void
    Although this function runs automatically in the beginning of execution, and probably it's not a good idea to call it, but you may want to at sometime for some reason. This will reset default settings and will read the variable $_REQUEST["phx_c"], and reformats the PHX command. This will not reset the content variable 'phxContent', so it's safe to call in most cases.