Home > Software Development, php > using java style import to include files in php

using java style import to include files in php

I really like the way java handles packages and the way it import classes based on package description.
Last year while  developing  a php  based CMS application, I faced shitload of trouble when it came to file including.
The problem was if I was making a normal page request, realtive URL’s  worked this way:
“../framework/service/DataService.php” and I used

inlcude_once("../framework/service/DataService.php")

to include a script.

But for accessing files using AJAX request for some weird reason I had to use single dot at the start of the path – instead :

inlcude_once("./framework/service/DataService.php").
<pre>

And as such I hit a kind of brick-wall because say I have a script that I need to accesss normally and via AJAX call, and the file included some other files, then what do i do?  I either have to put duplicate includes one with single dot and one with double dots at the begining and there was no way I was going to do such stupid things.
So I set out to solve this truely annoying problem.
I found some scripts in the net that did what I needed, almost….
I stole a script from the net and modified to suit my need. And since then my life has been so easy  you won’t believe.
with that scrip all I had to do was import files just the way I do in good old Java.
Even better I started using the same conventions as java.

So my imports look like this nowaday:

import("com.barahisolutions.cms.model.MenuPermission");

and if I want to import all files in a package I use the same comvention as java and
and use ‘*’ instead of file name.

import("com.barahisolutions.cms.model.*");

The code looks very neat and all my scripts are neatly organised in packages and life has been good ever since.

I divide all my scripts into two main folders. One classses to hold all project specific classes and one lib to hold all my library files. and i set these folders as include path using ini_set. I just have to do one inculde_once statement to include the file that has the import function and for the rest I use import function to include the required classes and files.

Of course its not all that simple. Because relative path to the classes and lib folders may be different depending on where the page/script that uses the import function is located. so instead of using ini_set in every place I want to use the import function, I used a little trick to solve the problem. I created one more function bootstrap and used it to calculate the relative path to the classes and lib folder before doing the ini_set.
From there all I have to do is include this file as a bootstrap for my applicaitons and I was ready use the import function for all my file include needs.

Here’s a stripped down version of the bootstrap file with the required funcitons.

bootstrap.php.

// array to keep track of all the already included files
$_imports = array();

// set the include path to the classes and lib folder
function bootstrap(){

//get the current script's path  relative to the applicaiton root folder
$rel_paths=explode('/',$_SERVER['SCRIPT_NAME']);
$path="";

// calculate the depth relative to the root folder
if(sizeof($rel_paths)>2){
for($i=2; $i< (sizeof($rel_paths)-1); $i++){
$path.="../";
}
}
// set the include path for our application's library and class files
ini_set('include_path', $path.'lib' . (DIRECTORY_SEPARATOR == '/' ? ':' : ';') .
$path.'classes'.(DIRECTORY_SEPARATOR == '/' ? ':' : ';') );

}
//just execute the funciton.
bootstrap();

/**
* Import a class using the java naming syntax for a class name.
* use * to include all files in a package
* @param string $name The name of the package to be imported
* @return void
*/

function import($import) {

// if this import has already happened, don't bother,
if (isset($_imports[$import]) )
return true;

// seperate import into a package and a class
$lastDot = strrpos($import, '.');
$class = $lastDot ? substr($import, $lastDot + 1) : $import;
$package = substr($_import, 0, $lastDot);

// create a folder path out of the package name
$folder = '' . ($package ? str_replace('.', '/', $package) : '');
$file = "$folder/$class.php";

if ($class != '*') {
// add the class and it's file location to the imports array

include_once($file);

} else {
// add all the classes from this package and their file location to the imports array
// first log the fact that this whole package was alread imported
$_imports["$package.*"] = 1;
$dir = opendir($folder);
while (($file = readdir($dir)) !== false) {
if (strrpos($file, '.php')) {
include_once("$folder/$file");
}
}
}

$_imports[$import] = $import;
}

That’s all that is required.

Now if you include this file, you  can simple use the import statement to import files that you need in your script.

samle usage: (its assumed that the file that actually uses MenuController class has already included the bootstrap.php file.
class MenuController.php

//import all the required classes
import('com.barahisolutions.cms.model.Menu');
import('com.barahisolutions.cms.dao.MenuDAO');
import('com.barahisolutions.cms.dao.UserPermissionDAO');
import('com.barahisolutions.framework.menu.VerticalMenu');

class MenuController {

// your business logic here

}
Categories: Software Development, php Tags:
  1. No comments yet.
  1. No trackbacks yet.