The text of this proposal, test code, and updates live at
petermoulding.com/class. I place it here for discussion of the best
approach before people build code.

Class PHP

An invention for a classier PHP.

This invention uses PHP classes as Web pages. The invention can be
implemented as a wrapper around PHP or as an enhancement to PHP. In
Apache 2, the invention can be implemented as a filter to precede PHP. I
will give a quick outline of the requirement, then sketches of
implementations, then detailed examples prototyped using PHP.

The invention is named class. An Apache implementation could be a module
named class. If you write code to implement this invention, suffix the
project name with your name as in class_John.

To prevent a rapacious company copyrighting this invention using the
excuse that it is a business process or anything else they can
copyright, I declare my copyright on everything in this invention and
any processes derivable from this. Please make your code implementations
GPL, www.gnu.org/copyleft/gpl.html, and mention my page at
petermoulding.com/class.

Invention Requirement
The main requirement is to replace PHP's page input with invented input. 

Here is a file named any_class.class that containing a PHP class named
any_class:
<?php
class any_class
    {
    function any_class()
        {
        /* code to build a Web page. */
        }
    }
?>

Here is a Web page containing a PHP script to build the entire page
using the PHP class any_class:
<?php
include_once("any_class.class");
$any_class = new any_class();
?>

The invention makes PHP initiate any_class.class as if any_class were
included and instantiated by the example Web page.

PHP Wrapper

The invention could be implemented as a module for Apache or another Web
server by writing a wrapper for PHP. The wrapper would accept a call
from Apache then pass the call on to PHP so PHP could perform 100%
unaltered as if PHP were called direct from Apache.

The module would look for class requests with a page of the form *.class
then intercept the URL and prepare to pass invented input to PHP. The
Apache configuration parameters can ensure all requests for class go to
class and only requests for class to class. In a mixed class/PHP
environment, the requested class can go to class and the PHP requests
can go direct to PHP. There could also be a check in class for a class
file so that all requests are directed to class and class processes just
those with a matching class file.

When class finds a valid class request, class builds a PHP Web page that
includes the class file and initiates the class. To make PHP read the
invented Web page, you could trap PHP's Web page read and substitute the
invented page. As PHP has to access files within the constraints of a
Web server, the access technique could vary from release to release and
across Web servers. I will describe two quick implementation
possibilities.

If PHP reads files via Apache's file read functions (or an equivalent on
other web servers), class gets to view all file requests from PHP to
Apache and monitor all replies. Class can then pass the invented page
back to PHP without the request reaching Apache. PHP remains untouched
by class.

Where a Web server does not provide file access functions or PHP chooses
to not use those functions, class would need a modification to PHP to
intercept file reads. The interception depends on the exact compilation
of PHP and would be in the form of a wrapper around a file access
routine in PHP. The wrapper (or interception layer) needs to be at a
level where the code can see file names and subvert the whole file read
process. Interception at this level requires PHP release dependent
coding and is a step toward the PHP enhancement described next.
PHP Enhancement
A PHP enhancement would be an implementation of the invention direct
within PHP's code so that PHP can react to class requests in conjunction
with an external process or without an external process. The ultimate
enhancement would be to incorporate the whole invention within PHP so
there are no additional installation steps required.

A PHP enhancement could use a wrapper as described in PHP Wrapper or the
Apache 2 filter described next but use those devices just to trigger
class processing then perform the whole processing within PHP. This
approach has the advantage that the processing is independent of the
trigger method and the trigger method is free from processing code.

The PHP enhancement could discover the need for class processing by
whatever method suits the web server environment. The enhancement would
then verify the action is valid within constrains specified in php.ini,
verify a class file is available, and invoke the class file as if from
an invented Web page of the same name as the class file.
Apache 2 Filter

To implement this idea as an Apache 2 filter, you need a link to PHP
that lets PHP know your code will provide the Web page input. Your code
then invents a Web page of the same name as the class file and passes
the invented page to PHP. The Apache Notes field looks like a good
vehicle for passing the invented page. 

PHP has to discover the Web page will arrive in the Notes field or via
another mechanism of your invention. That means a modification to PHP
and something in php.ini to prevent accidental use of the modification
in sites not using your code. The least PHP dependent method would be to
invent the page in your code and enhance PHP with a single trigger to
make PHP read the input Web page from your mechanism. The approach
minimises changes to PHP but makes the process Web server dependent. The
PHP enhancement described in a previous page is more PHP dependent but
less Web server dependent.

Allow for other filters using the Apache Notes field. Wrap your invented
page in a simple XML tag that PHP can recognise within the Notes field.

Detailed Example

Here is a file named any_class.class that containing a PHP class named
any_class:
<?php
class any_class
    {
    function any_class()
        {
        /* code to build a Web page. */
        }
    }
?>

This class contains a constructor that builds the whole Web page using
any combination of code, functions and classes valid within PHP classes.
I copied all the Web site construction code from one Web site in to a
class/function wrapper and initiated Web page construction without
error. In other tests there were some global variables that needed
mention in a global statement within the outside function. If the global
communication within an application is a variable named $site, the above
example becomes:
<?php
class any_class
    {
    function any_class()
        {
        global $site;
        /* code to build a Web page. */
        }
    }
?>

As the authors switch to 100% class based coding, global variables
disappear in favour of a structure of variables with the class
structure.

Now for a more detailed look. The following code is a PHP implementation
of a PHP wrapper built by pointing the Web server at pages of type .html
which then contain a script to call the appropriate class from a
parallel file of type .class. In this version there is no code within
the Web server so there has to be two files. Once the example is
translated to C and added to a Web server as a module, the example code
becomes the content of a virtual Web page that is passed to PHP but not
stored on disk.

The first part of the code simply extracts the page name from PHP_SELF
and saves the name in $class_new_page. There are many ways to derive the
page name from server variables. Your technique will vary depending on
the Web server, the release of PHP and the options in php.ini. The
example happens to work on all the variations of PHP and Web servers I
currently use. The example also lets me remove the file type for known
file names while leaving in name parts that happen to contain dots.

The second part of the code prepares variables for use in the
constructor class. I used a class that does not know about URL or form
variables so I copy them in to an array for the class. This code is not
needed if your class knows it will be initiated as the start of a page.
You only need this type of code if you want to use the class as both the
start of a page and as a class within other code.

You could pass URL variables to the class in the order read from the URL
but you do not control the URL order. You could leave all the variables
out and let the class find the variables but the class would have to
know where to look, in the parameters of the constructor function or in
external variables. I use this part of the code to translate external
variables to a form the class understands and will later convert the
class to read direct. A better approach would be to enhance PHP to read
named parameters.

The third part of the code initiates the class. Initiation includes both
class file inclusion and class instantiation. I use include_once() to
prevent multiple inclusions. Your Web server module should use
include_once() for version of PHP that have include_once().

The variables are prefixed $class_new to reduce clashes with existing
code. That means I can mix this code with legacy PHP code on sits during
conversion. In your Web site module the variables are external to PHP so
do not clash with anything within the class or subsequent code.

<?php
// Extract page name:
$class_new_parts_page = explode(".", array_pop(explode("/",
    str_replace("\\", "/", $HTTP_SERVER_VARS["PHP_SELF"]))));
if(in_array($class_new_parts_page[count($class_new_parts_page) - 1],
    array("html", "php")))
    {
    array_pop($class_new_parts_page);
    }
$class_new_page = implode(".", $class_new_parts_page);

// Prepare variables:
$class_new_variables = $HTTP_GET_VARS;
foreach($HTTP_POST_VARS as $class_new_key => $class_new_value)
    {
    $class_new_variables[$class_new_key] = $class_new_value;
    }

// Initiate the class:
include_once("./" . $class_new_page . ".class");
$$class_new_page = new $class_new_page($class_new_variables);
?>

The function initiation can be implemented in a function so all
subsequent classes are initiated in a similar fashion. I use the
following simple function because it works with existing classes on a
development site. Once the existing site and classes are redeveloped,
the "./" prefix and ".class" suffix will be replaced by named constants.
At that point the function will serve little purpose so will be dropped.
in some other sites the function may be expanded to extract dynamic
classes from content databases. A logical extension of this invention is
to add code extraction from an XML database, something I describe in
another document.

// A function to initiate a class:
function class_new($class_new_class, $class_new_variables,
    $class_new_prefix = "./", $class_new_suffix = ".class")
    {
    global $$class_new_class;
    include_once($class_new_prefix . $class_new_class .
$class_new_suffix);
    $$class_new_class = new $class_new_class($class_new_variables);
    }
?>

Implications

By now you realise the class will have the same name as the page so will
not suit sites based on many pages with different names. It is also of
no interest to people to write HTML pages then insert small portions of
PPH code. This invention is for sites using pages generated by PHP code
so suits sites using dynamic content management. It suits sites that
have a small number of pages presenting varied data.

Your site might have one page for registration, another for logging in
then a single page/script that provides a shopping system while another
single page/script provides a search facility. Make the search a class
and use this invention to initiate the class.

Once you develop dynamic content management, your sites end up as a list
of scripts delivering what looks like a series of intelligent pages. The
HTML pages execute PHP scripts and add nothing. This invention removes
HTML layer between your class based scripts and the Web server.

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to