开发者

How to include specific filename from multiple directories using PHP

I'm trying to include specific 'admin view' files from within a folder structure. I'm familiar with include/require or how to recursively include a folder, but all I need to do is include one filename from each directory - the admin_view.php file.

So, my dir. structure looks like this:

File to have includes is at root.

 - mods
  - type
    -- type1
       -admin_view.php
       -other files I do not need included
    -- type2
       -admin_view.php
       -other files I do not need included
    -- type3
       -admin_view.php
       -other files I do not need included

As you can see, recursively including the files wont work, and manually including them works fine,.. until we start adding and removing directories from the main 'type' folder.. then, we have to manually edit all the include codes.. so, I am hoping to find a function, or snippet, that will allow me to look through al the directories with the 'type' directory and include ONLY a specific filename (admin_view.php)

This is what I've pieced together so far, but it's not working... :(

$modulesDir = array (
    ROOT_DIR.'mods/type',

);
$view_name = "admin_view.php";

function __autoload($view_name) {
    global $modulesDir;
    foreach ($modulesDir as $directory) {
        if (file_exists($directory . $view_name)) {
                require_once ($directory . $view_name);
                return;
        }
    }
}

Thanks so much! This place is an awesome resource.. and I really appreciate all the knowledge, correction, cl开发者_运维百科arification, etc. that it provides the development community! J

EDIT:

I was able to get the view files loaded with this.. but I have a feeling that there's a better way to do this:

CLARIFICATION

I was misusing the __autoload function.. as I am NOT loading classes.. just php files to include in the main document... sorry for the error, I'm learning :)


Not sure if that's the only issue in your code, but check this out:

$modulesDir = array (
    ROOT_DIR.'mods/type',
);

if (file_exists($directory . $view_name)) { ... }

You're not ending your folder names in the $modulesDir with a /

When you do file_exists($directory . $view_name), you're actually checking for a file named

ROOT_DIR.'mods/typeadmin_view.php'

and not what you wanted

ROOT_DIR.'mods/type/admin_view.php'

Edit:

Regarding the use of __autoload($name), one thing to keep in mind is:

From PHP Documentation: Autoloading Classes:

You may define an __autoload function which is automatically called in case you are trying to use a class/interface which hasn't been defined yet.

It means that if you're not using classes or if the classes you're using are already 'included', it won't be called.

From your question, it wasn't clear at first glance if you were using classes or not, even tho it looked like your use of __autoload() wasn't appropriate.

One way or the other, your approach of using glob("/path/*/file.php") seems good.
It is simple, clear and gets the job done.
Unless you find an specific problem with it, you should be good to go.


You can use the SPL's RecursiveDirectoryIterator to iterate over all files in a directory and its subdirectories.
Then you can use a class extending FilterIterator to limit the result to specific files.

e.g.

<?php
class EndsWithFilterIterator extends FilterIterator {
  protected $s;
  public function __construct($s, $it) {
    parent::__construct($it);
    $this->s = $s;
  }

  public function accept() {
    $c = parent::current();
    return false!==stripos($c, $this->s, strlen($c)-strlen($this->s));
  }
}


$directory = 'type/';
$it = new EndsWithFilterIterator('admin_view.php',
  new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory))
);
foreach($it as $f) {
  echo $f, "\n";
  // require_once $f;
}


__autoload is used to auto load class includes.

It means everytime you create a new instance of a class that PHP doesn't know the definition yet, PHP will call the __autoload function and hope to get the class definition included.

I don't see any code creating an object in your code, if you take a look at the PHP of __autoload, they provide this sample.

<?php
function __autoload($class_name) {
    require_once $class_name . '.php';
}

$obj  = new MyClass1();
$obj2 = new MyClass2(); 
?>

If you are looking for including the view when you create the controller object something like this should work, your controller would have to be named like foobarController for this to work properly.

$modulesDir = array (
    ROOT_DIR.'mods/type',

);
$view_name = "admin_view.php";

function __autoload($class_name) {
    global $modulesDir;
    if(preg_match('/(\w+)Controller/', $class_name, $match)){
      $class = $match[1];
      // TODO: include the class definition
      // require CONTROLLER_DIR . $class_name . '.php';
      foreach ($modulesDir as $directory) {
        if (file_exists($directory . strtolower($class) . '_view.php')) {
                require_once ($directory . strtolower($class) . '_view.php');
                return;
        }
      }
    }
}

$adminController = new AdminController();
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜