My favorites | Sign in
Project Logo
                
Search
for
Updated Jun 22, 2009 by blinder.dave
Labels: Featured
Documentation  
phpBoing documentation and example code

Introduction

So, what is phpBoing and why did I even bother?

Good question. It started out as a school project, well not even a school a project, more like a tool to help with a school project. Working on a masters degree in computer science, the class was assigned to build a web application. I had grown quite comfortable over the years with the Spring Framework and was wanting to use IoC/DI (Inversion of Control/Dependency Injection) for this assignment. I looked for a suitable library in PHP (the project had to be written in PHP) and found nothing to my liking. Because I hadn't any extra time, I just decided to go ahead and "port" Spring in PHP.

This system isn't meant to break new ground, but it was meant to give me the functionality of a system I already knew inside and out. I wanted the familiarity. It wasn't until I started to use boing on work project that it became clear that some other people might find this useful, so here we are.

The Application Context

The application context is a single or series of XML files that define "beans" which constitute the functional pieces of code within your application. Currently boing looks at the variable CONTEXT_XML (defined in config.php) to determine which XML file it should load.

You may define any number of XML files and simply "include" them into your main (or "master") context XML:

<import resource="some-file.xml"/>

It is within these XML files that you specify "beans" and "properties" which are in turned "called" by your code (for a quick look at how this works, look at the example.php file.)

To start, we'll look at a very simple application context XML file, and describe each line of code:

<?xml version="1.0"?>
<beans>
  <bean id="simple-class" class="org.foo.bar.SimpleClass">
    <property name="someField">
      <value>foo is bar</value>
    </property>
  </bean>
</beans>

As you can see, we don't validate our XML (yet) but Spring's format is followed rather closely. Start out with a typical XML declaration, and then move on to our root node beans. Here we define one or many beans using the bean element. The only attribute that is required is the class attribute.

The id attribute will be auto-assigned at run time if omitted. Its usually a good idea to provide an id attribute simply because this is the attribute you will use to call your bean. There are times when it doesn't make sense to have an id such as the case when you inject a bean class as a property of another bean. You wouldn't be calling that particular bean directly, and therefore you may safely omit the id attribute.

You will notice the class attribute's value uses a "dotted" notation for classes. How packaging works is very similar to that of Java's class path. In fact, you specify a CLASSPATH variable in config.php that tells boing where it should look for classes to load when parsing the application context XML.

The CLASSPATH defines the "root" of where your classes will be stored, and you are free to use directories to create packages for your classes. In the example above you would have a directory structure like:

CLASSPATH."/org/foo/bar/SimpleClass.php"

Beans

Beans are individual PHP classes that may define a particular function, unit of work, problem set, that represent a single instance in phpBoing's internal registry. A bean is often thought of as a representation of:

$foo = new Foo();

At the end of the day phpBoing is simply a registry of objects in memory that your application can use when the time is right (the "don't call us, we'll call you" concept of IoC)

Currently the only two attributes supported for beans are:

The advantage using beans (and boing in general) is that you would have something like this in your code:

$obj = new Foo();
$obj->setBar("foo");
$obj->setFoo(new FooAndBar());
$result = $obj->doSomething();

and that's just for a relatively simple object instantiation and preparation. It adds a lot of code, code that gets messy, and error prone and not terribly easy to maintain.

Now using boing, your code would then just look like:

$obj = $container->getBean("foo");
$result = $obj->doSomething();

Not only is this less code, but you've also introduced a huge amount of flexibility into the system. Lets say you don't like what "foo" does, well instead of tweaking your actual code, why not just change the bean definition?

Properties

Properties represent fields for a particular bean. We can use properties for settings, "injecting" other beans (as dependencies on the parent beans, where we get the "dependency injection" concept from). Properties can provide simple string values, to complex collections or, as stated, other beans. Below illustrates what are valid elements for properties:

Element Example
value
<property name="foo"><value>foo is bar</value>
bean

<property name="someObj">
  <bean class="some.package.beans.FooBar">
</property>
list
<property name="some_list">
  <list>
    <value>some value</value>
    <value>some other value</value>
  </list>
</property>
map
<property name="some_map">
  <map>
    <entry key="name_of_key"><value>value for this key</value></entry>
    <entry key="another_key"><value>another value</value></entry>
  </map>
</property>

It should be noted that for map and list you can use complex values (of nested maps, lists and/or beans)

In addition to hard-coding simple (string) values, you can also use the special bean: PropertyPlaceholderConfigurer which enables you to use a separate properties/configuration file using key/values pairs for your string values. An example:

<bean 
  class="org.phpbboing.util.PropertyPlaceholderConfigurer">
    <property name="locations">
      <list>
        <value>../configs/foo.properties</value>
      </list>
    </property>
</bean>

This class currently resides in the ref_app file system.

Basically this works (just as the Spring Property Placeholder Configurer) by providing a list of properties files to the configurer and then parses them (using PHP's parse_ini function) and provides the container with a symbol table of all key/value pairs it found.

To use your configuration variables within an application context XML, simply use the syntax:

${key} 

Below is an example:

----- props snippet ------
my.key = a simple value
----- end props snippet --

<bean id="my-bean" class="org.some.package.FooBar">
  <property name="my_prop">
    <value>${my.key}</value>
  </property>
</bean>

Caching

Because PHP has no notion of "static" variables, variables that live outside and beyond that of the web application, there is a mechanism in place that persists our application context registry. This is done primarily because of performance.

It would be a very bad idea for every click to parse one or many application context XML files, which is exactly what would happen if there wasn't a caching mechanism built into phpBoing.

The currently caching mechanism is that of Memcached a very simple, powerful and lightweight memory caching system. You will need to have Memcached installed and running on your machine where you intend to use phpBoing.

How this works is, located in the phpBoing distribution is the c_tools.php file which defines a Tools class. This class contains several static functions that the container uses, one series of functions are the add to, delete from and get functions for memcached. The container, once instantiated (in your code) will look to see if there's a cached version of the BEAN_CONTAINER (which is the internal registry of all beans). If one does not exist, we then parse our XML file(s) then we take the resulting registry and copy it to memcached.

Examples

As part of the distribution of phpBoing you will notice a simple example: example.php this brief example will illustrate how each of the pieces of phpBoing fit together and how you can use it in your application. The nice thing is that using boing means you do not have to re-engineer your application. You can use it as much or as little as you want, boing makes no assumptions about your application, how you built or what it does.

As part of the example.php there is also a very simple class path that makes up this example located in: classes.

Reference Application

The reference application is a full fledged MVC (Model-View-Controller) framework that attempts to show how a real world application might use phpBoing. You can use the make-site.php command-line script to create a web site shell for you, using your settings defined in my_site.ini

To create a site, simply create a site INI file (you can use the my_site.ini as a template) then execute make-site.php on the command line:

./make-site.php my_site.ini

This will create the entire file structure for your site.

Again, phpBoing is NOT a web application framework. This reference application is only included as a way to show a real world system (which is actually derived from several actual projects).

This reference application will most likely NOT be maintained in that is not the goal of this project, and may at some point in the future be dropped from the distribution all together.

Credits

Thanks go out to: the whole Spring Framework community, for making a really nice container.


Sign in to add a comment
Hosted by Google Code