Intercepting filters are used to preprocess requests and post process responses. They wrap and modify or transform the inputs and outputs to core application logic.
The Intercepting Filter pattern can be distinguished from ordinary pre and post processing application logic in that the filters conform to standard interface, are reusable, and are loosely coupled with core application logic and other filters.
A intercepting Filters are one of several patterns for Centralized Request Logic. Intercepting Filters work best for handling HTTP request and response logic and other logic which is decoupled from core application responsibilities.
The Java Servlet specification has defined a standard interface for Java Servlet Filters. PHP has no such standard interface.
PHP does have an output buffering capability that works well in practice for response filters. Output buffering does not buffer response headers.
A PHP intercepting filter implementation may have to deal with non-filter aware php code using the php output buffing capability.
Java Servlets define HttpServletResponse and HttpServletRequest objects which completely encapsulate response and request handling. This lends itself well to implementing intercepting filters in Java. PHP response and request handling is much more haphazard (see PHP HTTP Response Handling Summary and PHP HTTP Request Handling Summary).
Filters can be registered to wrap a specific request either explicitly or declaratively. In the explicit method, the application makes a specific call to the filter at an appropriate time. In the declarative method, an external configuration file is used to describe which filters should process which requests. The declarative method promotes filter reuse and offers more flexibility at the cost of greater complexity.
Part of registering filters is determining the sequence in which the filters should be run. Sequencing is required to manage side effects from each filter. For example, a response compression filter may have to be run after all response modifying filters.
Filters are meant to be loosely coupled with the rest of the web application, so it is inherently difficult to pass information to them outside of their standard API. Doing so decreases the filters reusability. A filter registration method must consider whether and how filters will be configured with extra parameter information.
The most basic way to register a filter in PHP is explicitly with a simple include or require statement. Request pre-processing is included before core processing occurs. Response post-processing is included after core processing occurs.
When done this way, filters cannot be added to a web application without modifying the application itself.
PHP provides a mechanism for automatically specifying files to be included before and after each request. In typical PHP special case style, a program that calls
exit() will not cause the
auto_append_files to be included.
A Filter manager could be built into a Front Controller or Page Controller ancestor class. The filter manager can be responsible for reading in a configuration file for declarative filter registration. It might also be responsable for integrating filter invocation with core logic invocation.
In one approach, the filters can be strung together in a chain and the chain of filters can be passed to the first filter. Then each filter may call the next filter on the chain when it is ready. This allows the filter to do both pre-processing and post-processing. it also allows the filter to couple the pre and post processing. If the filter decides that processing should not continue, it simply avoids calling the next filter in the chain. This is known as active invocation. Generally, the last filter in the chain is responsible for invoking the actual core application logic.
In another approach, a filter manager will call each filter in turn at the appropriate time. This is called passive invocation. It can be more difficult in this instance for the filter to specify that processing should stop, and more complicated to coordinate pre and post processing. Direct registration can lead to direct invocation, a form of passive invocation where the filters are simply applied as they are registered.
In the active invocation approach with a filter chain, a special filter can be inserted as the last filter in the chain in order to call the application logic.
auto_append_file technique can be used to automatically wrap unknowing core logic.
PHP output buffering functions with a callback function can be used to wrap unknowing core logic.