PHPBOM

From ProgClub
Jump to: navigation, search

PHPBOM is the ProgClub PHP web-framework and toolkit. That's the software we use to develop web applications and web services in PHP. It's a mashup of bits and pieces John thinks are useful when delivering software for the web! For other projects see projects.

Status

We use semantic versioning. Latest production version: unreleased. Latest development version: 0.9.

See tasks for work that still needs to be done.

Motivation

Why this software? Because it's a good place to store useful bits and pieces that I (we?) probably want to reuse across all the web projects that I (we?) do.

Administration

Contributors

Members who have contributed to this project. Newest on top.

All contributors have agreed to the terms of the Contributor License Agreement. This excludes any upstream contributors who tend to have different administrative frameworks.

Copyright

Copyright © 2017-2020, Contributors.

License

Licensed to Blackbrick under the MIT license and to everyone else under the GNU Affero General Public License.

Disclaimer of Warranty

THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

Limitation of Liability

IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

Resources

Downloads

There aren't any downloads yet because we're still under development on our 0.x versions. When we release 1.0 we will (hopefully!) provide tarball packages. Stay tuned.

Source code

The repository can be browsed online:

https://www.progclub.org/pcrepo/phpbom/branches/

If you want the latest version for development purposes:

https://www.progclub.org/svn/pcrepo/phpbom/branches/0.9/

Links

Links are generated with bugslist.php:

$ bugslist --all -a= -c=s -o=sk -t=s > doc/links.wiki

Specifications

Functional specification

The functional specification describes what the project does.

The software is a web framework and toolkit for delivering web applications and web services in PHP.

Frameworks

The PHPBOM code comes with a bunch of frameworks designed to help with specific usecases. Some of the main/stable frameworks are listed here.

Console framework

The console framework is in inc/framework/console.php. To use include the console framework include file and then call the run() method with an instance of your application. For example:

require_once '/path/to/phpbom/inc/framework/console.php';

class MyConsoleApp extends BomApp {

  public function run( array $argv ) { bom_stdout( "Hello, world!\n" ); }

}

run( new MyConsoleApp );

HTML framework

The HTML framework is in inc/framework/html.php.

// 2020-04-17 jj5 - TODO: document how the HTML framework works. I.e. the required constant definitions from the config file, the front-controllers, and their creation and hosting.

Test framework

The test framework is in inc/framework/test.php. To use include the test framework include file and then call the run() method with an instance of your test. For example:

require_once '/path/to/phpbom/inc/framework/test.php';

class MyTest extends BomTest {

  public function run( array $argv ) { assert( 1 !== 2 ); }

}

run( new MyTest );

Application host

The PHPBOM software can host an application for you. Usually you will "host" your own application by including an appropriate framework and then calling a run() method with an instance of your application, but we have a simple facility for hosting console applications.

Hosting console applications

The best way to host a console application is to use the console framework and then call run() with an instance of your application, but if you don't want to do things that way PHPBOM can host a console application for you. The way this works is you define a main() method and then include the PHPBOM host code. The host code will configure the environment for your console application and then invoke your main() method.

The console host is in inc/host/console.php. You can use like this:

function main( array $argv ) : int {

  bom_stdout( "Hello, world!\n" );

  return 0;

}

require_once '/path/to/phpbom/inc/host/console.php';

Note that for application hosting you put the include code at the end of your source file, not at the beginning.

Technical specification

The technical specification describes how the project works.

Bootstrapping

So bootstrapping is the process of loading a program from its pieces. Some things need to be loaded before other things, some things won't work unless other things have already been loaded, or done, and things can get tricky. So to help manage this process we have our bootstrap process. Note that PHPBOM has its bootstrap process and your application will also have its bootstrap process, part of which will be to load PHPBOM. We recommend that when you implement your application bootstrap process that you follow the same order as PHPBOM:

constant
define program constants, including version number
critical
load critical components which must be loaded early (e.g. logging); note that critical components can't rely on components that get loaded after they do, which is pretty much everything
error
define your error codes and messages
library
load any third-party libraries you wish to include (this is done early)
basic
load basic components
config
load and process your config file
data
declare application data facilities
util
load utility components
interface
load your main interfaces
traits
load your main traits
class
load your main classes
module
load your modules
app
define your application with bom_define_app(), thereby setting the APP_* constants — only one application can be defined in a process

Note that you don't have to run the full bootstrap process. If you don't need later functionality you can include just up to the bits that you need. The three levels supported by PHPBOM are:

Include file Includes up to
inc/utilities.php util
inc/modules.php module
inc/app.php app

If you include a framework it will bootstrap your utilities/modules/app to an appropriate level automatically.

Components

So in the PHPBOM library we have a "component" pattern which is implemented by:

A component is defined in a single source file and is comprised of three broad parts:

  1. a number of public functions the names of which start with "bom_" which define the interface to, and functionality of, the component;
  2. a service locator function that can manage a single application-wide instance of the component class;
  3. a class definition containing an implementation of the default functionality for the component.

The public functions do as little as possible. Basically they just defer immediately to an instance of the component class which is accessed via its service locator. A good simple example of the component pattern can be found in the data component. At the top three public functions are defined:

  • bom_get_continents()
  • bom_get_countries()
  • bom_get_languages()

The public functions defer their implementation to a method on the object returned from the service locator, e.g.:

function bom_get_continents() { return bom_data()->get_continents();  }

The "service locator" is the function called "bom_data()". If you look at the bom_data() function you will see that by default you will get an instance of the class BomData:

function bom_data( $set = false ) : BomData {
  static $instance = false;
  if ( $set !== false ) {
    $instance = $set;
  }
  else if ( $instance === false ) {
    $instance = new BomData();
  }
  return $instance;
}

The definition of the BomData class follows which includes the default functionality of the component. If you wish to modify behaviour or implementation or to intercept access you can subclass the BomData class and then configure the service locator with your new implementation, by, for example:

class MyBomData extends BomData { ... }

bom_data( new MyBomData );

Ordinarily programmers using a component will access the component through its public functions. Generally callers will not access the service locator or class methods directly, only the public functions. If you find yourself needing to access the service locator or its instance directly then perhaps you have found a situation which calls for additional public functions to help meet your goals in a clean, well documented, and supported fashion.

So why do we use the component pattern? Well it's nice when your software components present themselves as a simple set of functions, this makes them easy to discover and use. But functions alone can't manage state particularly well (you're limited to either internal static variables or external global variables, each of which can be problematic) and in PHP functions can't be replaced or overrideen after they have been declared (unlike class methods, which can be overridden). So to make for a better situation with regard to component state, and to allow for the possibility of intercepting or overriding default functionality, we implement our component as methods (and potentially fields) on a class. But then we need to manage an instance of our class and also provide a mechanism for applications to replace the default functionality with their own, thus the service locator function. So the component functions, service locator, and default class definition work together to provide simple interfaces with powerful potential for customisation and use.

Library

The PHPBOM library is composed of these pieces.

Constants

We define a bunch of constants in src/code/0-bootstrap/0-constant.php. The constants *about* the library are prefixed with "PHPBOM_", the constants *in* the library (the bulk of the constants) are prefixed with "BOM_", and constants which are meant to be joined with your own constants definitions in your programs are prefixed with "APP_".

Version number

The components used to build the PHPBOM version number are stored in the inc/version.php file which is managed by svnman.

Critical components

Critical components have minimal dependencies and are loaded early. The code is in src/code/1-critical. The critical code is mostly there to support logging and error handling.

Error modelling

Application error codes and messages are defined in src/code/0-bootstrap/1-error.php and loaded as early as possible.

Third-party libraries

PHPBOM doesn't presently rely on any third-party software.

Basic components

The basic components are loaded from src/code/2-basic.

Configuration support

Classes to help read the configuration data are in src/code/3-config.

Data component

We deliver a data component in src/code/0-bootstrap/4-data.php. This data component makes the JSON data from dat/test available to your applications (including your tests).

Database schema support

PHPBOM has support for modelling database schema and revisions thereof. The software ships with its own database schema defined in src/code/4-schema/phpbom.php.

See database patterns for info on supported database design patterns.

Utilities

There are a bunch of utility components loaded from src/code/5-util.

Interfaces

The main interfaces are in src/code/6-interface.

Traits

The main traits (if we had any) would be in src/code/6-traits.

Classes

Our main classes are in src/code/7-class.

Modules

There are various modules available from src/code/8-module.

PHPBOM applications

The PHPBOM software ships with a number of PHPBOM applications, including a bunch of command-line programs and a suite of facilities in a web application. The PHPBOM applications can be used for evaluation, development, testing, and maintenace. The web facilities can also be incorporated into your own web applications.

Tests

Unit tests are organised under src/test.

Playground

If you want to take your code for a spin, but don't want to add supported unit tests for it yet, then you can use the Developer Playground, just stick your code somewhere under src/play.

Notes

See versioning for information on our semantic version numbers.

Notes for implementers

If you are interested in incorporating this software into your project, here's what you need to know:

Grab a recent copy of the code from svn into a lib/phpbom-0.1 directory in your project. Then depending on what framework or features you want include the appropriate files. For frameworks see src/framework, for utilities see src/util, and for modules see src/module. Note that generally classes cannot be used alone, so if you want support from a class load its respective module.

Notes for developers

If you're looking to set up a development environment for this project here's what you need to know:

So you want to hack on PHPBOM? Cool! Get in touch with John and we'll take it from there!

Notes for ProgClub administrators

To release a version of this project use the pcrepo-branch-release script from the jj5-bin project:

$ pcrepo-branch-release phpbom $MAJOR.$MINOR $PATCH

Where:

$MAJOR = the major version number, presently 0
$MINOR = the minor version number, presently 1
$PATCH = the patch number for this release

See status for last production release.

Tasks

TODO

Things to do, in rough order of priority:

  • create a TODO list... :P

Done

Stuff that's done. Latest stuff on top.

  • JE 2017-02-23: created project page
  • JE 2016-12-16: created the project in svn