Article
Faking Dual Inheritance Classes in PHP
Execute Universalupdater
While I designed universalupdater to allow a user to customize the tags it seeks, as long as you don't need to change the tag names, it's quite simple to execute the script. The following is all you need:
<?
error_reporting(E_ALL);
include ('universalupdater.php');
$update = new universalupdate('my_source_file.php',
'my_target_directory');
$update->Execute();
?>
You don't actually need error_reporting (E_ALL), but I like to have all warnings displayed so that if something does go wrong, I know about it. The function Execute() does give a simple progress report, but error reporting is still useful.
When the function Execute() is called, universalupdater will load the source file into memory, and then scan the target directory for any PHP files that contain the proper tags. If your source file is not in the same directory as the script calling universalupdater, make sure you specify the directory in the file path name as well.
If you are using universalupdater with more than one source file, or you need it to sort through a number of directories, simply create new instances of the class with the additional source files or target directories.
Once the universalupdater has been run, the intermediate class file, which was originally just comment tags, now appears as:
include_once ((isset($phplocation)? $phplocation.'pagecontent.php' :
'pagecontent.php'));
//parent class= pagecontent
//child class= prepagecontentadmin
//source class = universalcontentadmin
//Replacement Code Starts Here
if (!defined ('UNIVERSALADMIN_CONSTANTS'))
{
define ('UNIVERSALADMIN_CONSTANTS', 'defined');
define ('UCA_NO_VALUE', '@#784pdjas');
define ('UCA_BLANK_VALUE', '*^@adfds');
define ('UCA_EDIT', 'ucedit');
define ('UCA_DUPLICATE', 'ucdup');
define ('UCA_DELETE', 'ucdelete');
define ('UCA_CONFIRM', 'ucconfirm');
define ('UCA_UPDATE_ITEM', 'ucupdate');
define ('UCA_DISPLAY_NAME_SPLITTER', '||');
}
class prepagecontentadmin extends pagecontent
{
var $tableformat;
var $comments;
var $itemcount;
var $defaultpadding;
function prepagecontentadmin ($paramtablename)
.
.
.
<ETC>
.
.
.
}
//Replacement Code Ends Here
?>
As you can see, the class definition has been altered from "class universalcontentadmin extends universalcontent" to "class prepagecontentadmin extends pagecontent". Likewise, the constructor function has been renamed.
Use the New Intermediate Class
Hopefully, this final step will be the easiest. In the example, my final class is pagecontentadmin. Here is the beginning of the new class:
include_once ((isset($phplocation)? $phplocation.'pagecontentadminpre.php'
: 'pagecontentadminpre.php'));
define ('DEFAULTMODELPAGE', 'blank');
define ('PCA_SIMPLE_STRUCTURE', 's');
define ('PCA_SUBDIRECTORY_STRUCTURE', 'd');
class pagecontentadmin extends prepagecontentadmin
{
var $modelpage;
var $directorystructure;
function pagecontentadmin ($extrafields = array (''),
$paramtablename = 'pages', $modelpage = DEFAULTMODELPAGE,
$recordstructure = PCA_SIMPLE_STRUCTURE)
.
.
.
<ETC>
.
.
.
}
You may notice while the class name is prepagecontentadmin, I saved the file as pagecontentadminpre.php. While it is a little inconsistent, I did this so the class name would make sense in English, while the file name would allow the file to appear alphabetically with pagecontent.php and pagecontentadmin.php.
Now, pagecontentadmin has all the functions and constants of both pagecontent and universalcontentadmin. When using universalupdater, you will need to be careful about the class constructor. Remember that universalupdater will use the class constructor of the source file automatically. You may need to specify a new constructor in the final class.
Winding Up
Just as a quick review, to use universalupdater, go through the following steps:
- Take the files and create the two parent classes. In my example, the parent classes are sibling classes. While this is not necessary, remember that the parent classes need to be compatible with each other.
- Prepare the source file by adding the start and ending comment tags to it (by default they are "
//Replacement Code Starts Here" and "//Replacement Code Ends Here"). - Prepare the intermediate file by adding five comment tags to it (by default the necessary tags are: "
//parent class = my_parent", "//child class = my_child", "//source class = my_source", "//Replacement Code Starts Here" and "//Replacement Code Ends Here"). - Run a script that creates an instance of universalupdater, and calls the function Execute (
my_source_file,my_target_directory). - Use the newly-created intermediate class as a parent for your final dual inheritance class.
- Any time you need to update the source class, just run universalupdater again, and the changes will automatically be made to all the appropriate files.
Does this perfectly duplicate dual inheritance? No. While it is much more convenient that doing the copying and pasting yourself, you still have to run the script to update all the intermediate classes. Also, it's not as efficient for the server as true dual inheritance would be. Those disadvantages aside, it does truly allow you to maintain many dual inheritance children without fear of them becoming out of date.