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