Pergunta

this is my third question so far on stackoverflow :D

i am defining files and their location on my first_run.php files, the files that i define here is those files containing classes, helper functions and any other files required

at early development, this first_run.php contains only a few lines of codes but the line is increasing gradually as i add some new classes or new files to be included

and since i group the file's location inside a particular folder, i figure that maybe i can scan the folder, put the name of the files retrieved into an array and then loop the require_once, so that i dont have to edit first_run.php every time i add a new file inside the folder.

my fisrt approach is using scandir()

before:

defined('INC_PATH') ? null : define('INC_PATH', SITE_ROOT.DS.'includes');
defined('MEMBERS') ? null : define('MEMBERS', INC_PATH.DS.'models'.DS.'members');

require_once(MEMBERS.DS.'member.php');
require_once(MEMBERS.DS.'phone.php');
require_once(MEMBERS.DS.'profile.php');
require_once(MEMBERS.DS.'talent.php');
require_once(MEMBERS.DS.'profile_picture.php');
require_once(MEMBERS.DS.'audio.php');
require_once(MEMBERS.DS.'video.php');
require_once(MEMBERS.DS.'gallery.php');
require_once(MEMBERS.DS.'statistik.php');
require_once(MEMBERS.DS.'inbox.php');
require_once(MEMBERS.DS.'comment.php');
require_once(MEMBERS.DS.'picked_stat.php');
require_once(MEMBERS.DS.'log.php');

after is something like:

$member_files = scandir(MEMBERS);
foreach($member_files as $member_file):
    require_once(MEMBERS.DS.$member_file);
endforeach;

i havent try the 'after' code though. is this possible?? or is there any other approach?? or should i just leave it that way (keep adding the lines without scanning the files)

thanks in advance

Foi útil?

Solução

Consider using Autoloading instead.

With autoloading, you do not have to bother with including files at all. Whenever you instantiate a new class that is not known to PHP at that point, PHP will trigger the registered autoload function. The function includes the required files then. This way, you only load what you need when you need it, which should increase performance.

Simple example with PHP5.3

spl_autoload_register(function($className) {
    include "/path/to/lib/and/$className.php";    
});
$foo = new Foo;

When you call new Foo, the registered autoload function will try to include the class from /path/to/lib/and/Foo.php. It is advisable to use a classname convention, like f.i. PEAR, to make finding files easier and to cut down on the amount of include_paths.

For additional security and speed, you can provide a more sophisticated Autoloader that uses an array to map from classname to filename, thus making sure only files that actually are part of your application can get included.

Further reading:

Outras dicas

It's possible, but not recommended, like what if somebody could create a php file on that directory, you'll end up including it, besides, you can't predict the inclusion order.

Try this instead:

$includes=array(
  'member',
  'phone',
  'profile',
  'talent',
);

foreach($includes as $fname) {
  require_once(MEMBERS.DS.$fname. '.php');

}

If you were using classes, consider using autoloading, as @Gordon suggested. And if you werent using classes, consider using them :)

At a first glance your code could work, although you have to ignore "." and ".." in the foreach loop. Plus I'd check, if the file ends with ".php":

$member_files = scandir(MEMBERS.DS);
foreach($member_files as $member_file) {
    // Ignore non php files and thus ".." & "."
    if (!preg_match('/\.php$/', $member_file) {
      continue;
    }
    require_once(MEMBERS.DS.$member_file);
}

create 2 functions

function GetFiles($directory,$exempt = array('.','..','.ds_store','.svn'),&$files = array()) {
    $handle = opendir($directory);
    while(false !== ($resource = readdir($handle))){
        if(!in_array(strtolower($resource),$exempt)){
            if(is_dir($directory.$resource.'/'))
                array_merge($files, self::GetFiles($directory.$resource.'/',$exempt,$files));
            else
                $files[] = $directory.$resource;
        }
    }
    closedir($handle);
    return $files;
  }


  function Autoload($includes = array()){
    $files = array();
    foreach($includes as $directory)
      $files[] = self::GetFiles($directory);

    foreach($files as $k=>$v){
      foreach($v as $k1=>$v1)
        require_once($v1);
    }
  }

to use it:
$includes = array(
    'C:WWW/project/helpers/',
    'C:WWW/project/lang/',
    'C:WWW/project/lib/',
    'C:WWW/project/mod/',
  );
Autoload($includes);
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top