impressum  •   email  •   sitemap


Get Firefox!
Sie sind hier: HomeDocumentationOverview

Benefits of PHPinChains

This overview is a bit hard to understand for people new to web frameworks. If you do not understand what's going on in this document, don't bother and have a look at the getting started document.
  • Intercepting Filter: Configurable filters for pre and post processing and processing pipelines.
  • Front Controller: One php file handles all requests
  • Action Controller: Code which is processed in a request is packaged in action methods which are packaged in action classes. An action class can package one or more action methods. Actions can call other action methods internally (dispatch method of action dispatcher: $this->dispatcher->dispatch()) without making a new request. Not public action methods and not public action classes are supported.
  • Module Support: For developing large applications modules are supported. Modules consist of action classes, views, bundels (for localization), custom tags (view helpers) and a configuration file (action-config.xml). They can be used for adding a package of functionality to an application.
  • Template Engine: Template Engine with custom tag support. Many standard tags are available. Templates are compiled to pure fast php code. Although normally not needed, php code is possible in the templates.
  • Localization: The Template Engine comes with special tags to operate on language bundles which are written in ini-format.
  • Form Validation: PHPinChains features powerful integrated easy-to-use Form Validation (e.g. <input pspc="h:input" name="field" validate="required" validationErrorClass="redBordered"/>).
  • Tag Overwriting: Makes custom tags browser and WYSIWYG editor friendly. You write a custom tag as an html tag and give the psp parser the name of the of the custom tag through the pspc attribute.
  • Expression Language: A simple but powerful language modeled after the Expression Language of JSPs, but in a more "phpish" way.
  • AJAX Integration: PHPinChains offers easy to use ajax forms and functions / links to update a page, without reloading it as a whole. Using an ajax form is as easy as using a normal html form. Just use ajax:form instead of h:form. If you want to handle 'load' and 'error' by yourself, specify the names of you JS function with load attribute and error attribute of ajax:form repectively. For just updating the innerHTML of an element by its id, specify the elements id with the update attribute. While using the update attribute or the jsresponse attribute, the whole validation part is acting in the same way as you would expect it using h:form. By setting jsresponse to 'true', you get the ability to update several parts of the page at the same time by using special custom tags or writing js code by hand in the corresponding view.
    Additional features of the ajax integration are ajax function, which can be used instead of links and timer controlled "javascript cron invocation" of ajax functions or hand written code.
    Ajax and dhtml integration is based on the excellent dojo framework.
  • Planned Features:
    Custom Tag based Components


Code example overview

Just to give you a feeling, about what it means to develop an application with PHPinChains and the action dispatcher architecture:

First you need a pre-configured or self-written chains config normally named app.xml which may be as simple as the following:
<conf:app>
<conf:params>
<conf:param name="lang" value="de_DE"/>
</conf:params>
<conf:filters filterPath="filter">
<conf:filter class="PathInfoActionParamFilter" match="*">
<conf:filterParam name="module" value="/"/>
</conf:filter>
<conf:filter class="ActionDispatcherFilter" match="*"
capture="false" captureAttribute="testCapture">
<conf:filterParam name="basedir" value="/Path/to/your/app"/>
<conf:filterParam name="use-compiledir" value="/Path/to/your/app/view/c"/>
<conf:filterParam name="class-extension" value=".php"/>
<conf:filterParam name="view-by-methodname" value="true"/>
</conf:filter>
</conf:filters>
</conf:app>

Now you need a configuration file for the action dispatcher which is already included in the skeleton projects. The only thing you have to do is just add new actions. You can configure PHPinChains to automatically generate the needed action classes and/or action methods while development.

You have the choice:
  • write an conf:action tag like <conf:action mapping="customer" class="CustomerAction" methodmapping="true" bypassViewMapping="true"></conf:action> for every action class (which may contains as much action methods as you like) and let PHPinChains create the file and the class for you
  • create a file and the code for the class (just class XxxAction {}) and do not configure the action with conf:action
In both cases PHPinChains will create the new action methods for you automatically.

The config file is named action-config.xml and looks as follows:
<conf:actions>
<conf:validators>
<!-- here go your additional validators -->
</conf:validators>
<conf:defaultErrorView forward="defaulterror.psp"/>
<conf:actionMappings>
<conf:defaultAction class="DefaultAction">
<conf:view mapping="default" forward="default.psp"/>
</conf:defaultAction>
<conf:defaultErrorAction class="DefaultErrorAction">
<conf:view mapping="default" forward="defaulterror.psp"/>
</conf:defaultErrorAction>
<conf:action mapping="customer" class="CustomerAction"
methodmapping="true" bypassViewMapping="true">
</conf:action>
<!-- add aditional actions here -->
</conf:actionMappings>
<conf:viewMappings>
<!-- actions which can only be called from the inside go here -->
</conf:viewMappings>
</conf:actions>
If you choose to use methodmapping="true" in an action declaration, you only have to declare the class and from now on you can access each method in this class by specifying an action to call (e.g. in a link) like mappingOfClass::methodName, as long as the method name does not start with _.

Lets look at the code of one of these actions:
class DefaultAction extends WebAction
{

function execute (& $env, & $viewmapping, & $actionform)
{
// Do something usefuls here: e.g. get data from the database
// and store it in the actionform
return 'default';
}

}
Now we have a closer look on what this tells us:
This action was declared as default action, so it will be called if no action to call was specified. If no action method was declared (this is by the way not possible for the default action and the default error action) the execute method is called. $env and $actionform are two content objects. $env wrapps the standard magic predefined variables and does a few things more. It makes compatibility with versions prior to php 4.1 possible (believe it or not, but some customers have those versions still running; although there will be a php5 only version in the near future). $actionform is much like a wrapper for the current request only. So you can store a complete action to run it again for example. It is passed by reference, because it also builds the main scope for variables in PSP views. $viewmapping is normally not needed, because the action dispatcher is doing this for you if you give it a return value. return 'default' for example is mapped to default.psp (you may use bypassViewMapping="true" , so that you do not need to configure view mapping: viewname => viemapping.psp).

So, how does a view look like in PHPinChains? First it is possible to use standard flat php files as views. But this is not the recommended way: PHPinChains comes with a template engine much like the JSP engine of java. You can programm custom tags and use an php flavoured EL (Expression Language) for accessing variables and making boolean comparisons. A so-called PSP (PHP Server Page) may look like the following:
<fmt:setLocale value="${configScope->lang}"/>
<fmt:loadBundle bundle="customer"/>
<html>
<head><title><fmt:message key="home_page_title"/></title></head>
<body>
<h1><fmt:message key="home_page_title" param1="ping" param2="5.4"/></h1>
<a href="<c:url action="customer::create"/>"><fmt:message key="link_new"/></a><br/>
<c:foreach items="${validationErrors->flip}" var="errorField">
<fmt:errorMessage key="${errorField}"/><br/>
</c:foreach>
<c:include page="includeValTest.psp"/>
<c:include page="includeValTest2.psp"/>
<c:if test="${conf1}">
${value1}
<c:elseif test="${conf2}">
${value2}
</c:elseif>
<c:else>
${value3}
</c:else>
</c:if>
<form pspc="h:form" action="note::store" method="POST">
<input pspc="h:input" name="headline" validate="required"/>
</form>
</body>
</html>
If you how JSPs you will wonder why there are no taglibs imported: this is not necessary in PSPs. The fmt tags are for formating and for internationalization. You see that there are control structures available. The ${...} expressions are EL expressions.

Is PSP just a port of JSP? NO it is not, there are some important differences:
  • You can implement a tag class, which has only two methods, one for the start and one for the end tag. It directly produces flat php code to replace the tag. Thus, it is executed only once, while the compilation of the page.
  • As mentioned above, there is no need to import a taglib, because tag handlers are loaded dynamically.
  • Of corse scriptlets are written in PHP and not in JAVA.
  • The most important difference is the tag overwriting feature: As you can see in the form example at the bottom of the shown above PSP code. There is a non-standard attribute called pspc which tells the parser, to translate the form tag each html capable application understands to a h:form tag. But why is this necessary and why is it a good thing to have?
    Because an application like a WYSIWYG html editor like most web designers use it, can not undestand a h:form or a h:input tag. Those application can not know that h:input it represents an html input tag. The other way round, the PSP engine can not correctly treat html tags as custom tags, by guessing which one should treated a custom tag and which one not.


Benutzerkommentare / User comments:

Name*:
eMail:
Titel /
Headline*:
Kommentar / Comment*:
 
copyright © 2006 synflag online agentur -- letzte änderung: 20.01.2007