autoloading classes in subfolders - php
In my PHP project all of the class files are contained in a folder called 'classes'. There is one file per class and as more and more functionality is added to the application the classes folder is growing larger and less organized. Right now this code, in an initialization file, autoloads classes for the pages in the app:
spl_autoload_register(function($class) {
require_once 'classes/' . $class . '.php';
});
If subfolders were to be added to the existing 'classes' folder and the class files organized within these subfolders, is there a way to modify the the autoload code so it still works?
For example - assume the subfolders within the classes folder looks like this:
DB
login
cart
catalog
I recoomend that you look at PSR standards at : http://www.php-fig.org
Also this tutorial will help you build and understand one for yourself.
http://www.sitepoint.com/autoloading-and-the-psr-0-standard/
Snippet that takes all subfolder :
function __autoload($className) {
$extensions = array(".php", ".class.php", ".inc");
$paths = explode(PATH_SEPARATOR, get_include_path());
$className = str_replace("_" , DIRECTORY_SEPARATOR, $className);
foreach ($paths as $path) {
$filename = $path . DIRECTORY_SEPARATOR . $className;
foreach ($extensions as $ext) {
if (is_readable($filename . $ext)) {
require_once $filename . $ext;
break;
}
}
}
}
My solution
function load($class, $paste){
$dir = DOCROOT . "\\" . $paste;
foreach ( scandir( $dir ) as $file ) {
if ( substr( $file, 0, 2 ) !== '._' && preg_match( "/.php$/i" , $file ) ){
require $dir . "\\" . $file;
}else{
if($file != '.' && $file != '..'){
load($class, $paste . "\\" . $file);
}
}
}
}
function autoloadsystem($class){
load($class, 'core');
load($class, 'libs');
}
spl_autoload_register("autoloadsystem");
Root
|-..
|-src //class Directory
|--src/database
|--src/Database.php // Database Class
|--src/login
|--src/Login.php // Login Class
|-app //Application Directory
|--app/index.php
|-index.php
-----------------------------------
Code Of index.php in app folder to Autoload All the Classes from The src folder.
spl_autoload_register(function($class){
$BaseDIR='../src';
$listDir=scandir(realpath($BaseDIR));
if (isset($listDir) && !empty($listDir))
{
foreach ($listDir as $listDirkey => $subDir)
{
$file = $BaseDIR.DIRECTORY_SEPARATOR.$subDir.DIRECTORY_SEPARATOR.$class.'.php';
if (file_exists($file))
{
require $file;
}
}
}});
Code Of index.php in root folder to Autoload All the Classes from The src folder.
change the variable $BaseDIR,
$BaseDIR='src';
autoload.php
<?php
function __autoload ($className) {
$extensions = array(".php");
$folders = array('', 'model');
foreach ($folders as $folder) {
foreach ($extensions as $extension) {
if($folder == ''){
$path = $folder . $className . $extension;
}else{
$path = $folder . DIRECTORY_SEPARATOR . $className . $extension;
}
if (is_readable($path)) {
include_once($path);
}
}
}
}
?>
index.php
include('autoload.php');
Here is the one I'm using
spl_autoload_register(function ($class_name) {
//Get all sub directories
$directories = glob( __DIR__ . '/api/v4/core/*' , GLOB_ONLYDIR);
//Find the class in each directory and then stop
foreach ($directories as $directory) {
$filename = $directory . '/' . $class_name . '.php';
if (is_readable($filename)) {
require_once $filename;
break;
}
}
});
Load files from "inc" subfolder using "glob"
/**
* File autoloader
*/
function load_file( $file_name ) {
/**
* The folder to where we start looking for files
*/
$base_folder = __DIR__ . DIRECTORY_SEPARATOR ."inc". DIRECTORY_SEPARATOR . "*";
/**
* Get all sub directories from the base folder
*/
$directories = glob( $base_folder, GLOB_ONLYDIR );
/**
* look for the specific file
*/
foreach ( $directories as $key => $directory ) {
$file = $directory . DIRECTORY_SEPARATOR . $file_name . ".php";
/**
* Replace _ by \ or / may differ from OS
*/
$file = str_replace( '_', DIRECTORY_SEPARATOR, $file );
/**
* Check for file if its readable
*/
if ( is_readable( $file ) ) {
require_once $file;
break;
}
}
}
/**
* Autoload file using PHP spl_autoload_register
* #param $callbak function
*/
spl_autoload_register( 'load_file' );
Related
How to use spl_autoload_register for multiple directories in PHP
Follow the code for the autoload class in multiple paths. This question is to remedy php users for correct usage of spl in various directories After a long time I elaborated this to sanitize my code. spl_autoload_register(function($class){ $paths = array( 'classes/', 'engine/' ); foreach($paths as $path){ $file = LIBRARY . $path . str_replace('\\', '/', strtolower($class)) . '.php'; if(file_exists($file)){ $files = array($file); } } foreach($files as $file){ if(is_file($file)){ include_once($file); return true; }else{ return false; } } });
Delete a folder already exist php
I have created folder based on year and month (while I upload image), eg: if I upload an pdf on February 1 2018 then I have created folder 2018 and folder 2. $filename = $_SERVER['DOCUMENT_ROOT'] . '/' . 'folder1/admin/slip' . '/' . $year . ''; $filename2 = $filename . '/' . $month; if (file_exists($filename)) { if (file_exists($filename2) == false) { mkdir($filename2, 0777); } } else { mkdir($filename, 0777); } If I again upload an pdf in February, I want to delete this folder and create it again. I use the following code rmdir($filename2) but its not working. please help me
Use this function for delete file. unlink( $filepath)
<?php delete_files('/path/for/the/directory/'); /* * php delete function that deals with directories recursively */ function delete_files($target) { if(is_dir($target)){ $files = glob( $target . '*', GLOB_MARK ); //GLOB_MARK adds a slash to directories returned foreach( $files as $file ){ delete_files( $file ); } rmdir( $target ); } elseif(is_file($target)) { unlink( $target ); } } ?>
Copying files from multiple source to destination directories using PHP recursive copy function
The purpose of this question can be served by writing independent function for each source & destination directory in an include file but I'm looking for a better approach. The following function copy files from one source directory to one destination directory. How can I use this function to copy file from another source directory to destination directory? Is array(); applicable here or explode(); shall be the right choice or none of these is applicable in this case? if (isset($_POST['submit'])) { $old_umask = umask(0); if (!is_dir($dst)) mkdir($dst, 0777); umask($old_umask); function recurse_copy($src,$dst) { $dir = opendir($src); while(false !== ( $file = readdir($dir)) ) { if (( $file != '.' ) && ( $file != '..' )) { if ( is_dir($src . '/' . $file) ) { recurse_copy($src . '/' . $file,$dst . '/' . $file); } else { copy($src . '/' . $file,$dst . '/' . $file); } } } closedir($dir); //echo "$src"; } $dir = $_POST['name']; $src = "/home/user/public_html/directory/subdirectory/source/"; $dst = "/home/user/public_html/directory/subdirectory/destination/$dir/"; recurse_copy($src,$dst); }
Autoload files when use require function
There's a magic function to autoload classes (__autoload), I want to know if there a way to load a file without a class. Something like this: require ('example_file'); // Trigger __autoloadfiles function function __autoloadfiles($filename) { $files = array( ROOT . DS . 'library' . DS . $filename. '.php', ROOT . DS . 'application' . DS . $filename . '.php', ROOT . DS . 'application/otherfolder' . DS . $filename. '.php' ); $file_exists = FALSE; foreach($files as $file) { if( file_exists( $file ) ) { require_once $file; $file_exists = TRUE; break; } } if(!$file_exists) die("File not found."); }
You can define own function for requiring: function require_file($file) { // your code } and then call it require_file('file'); I guess that there is no way to overload require function.
PHP: How to list files in a directory without listing subdirectories
This is the starting portion of my code to list files in a directory: $files = scandir($dir); $array = array(); foreach($files as $file) { if($file != '.' && $file != '..' && !is_dir($file)){ .... I'm trying to list all files in a directory without listing subfolders. The code is working, but showing both files and folders. I added !is_dir($file) as you see in my code above, but the results are still the same.
It should be like this, I think: $files = scandir($dir); foreach($files as $file) { if(is_file($dir.$file)){ ....
Just use is_file. Example: foreach($files as $file) { if( is_file($file) ) { // Something } }
This will scan the files then check if . or .. is in an array. Then push the files excluding . and .. in the new files[] array. Try this: $scannedFiles = scandir($fullPath); $files = []; foreach ($scannedFiles as $file) { if (!in_array(trim($file), ['.', '..'])) { $files[] = $file; } }
What a pain for something so seemingly simple! Nothing worked for me... To get a result I assumed the file name had an extension which it must in my case. if ($handle = opendir($opendir)) { while (false !== ($entry = readdir($handle))) { $pos = strpos( $entry, '.' ); if ($entry != "." && $entry != ".." && is_numeric($pos) ) { ............ good entry
Use the DIRECTORY_SEPARATOR constant to append the file to its directory path too. function getFileNames($directoryPath) { $fileNames = []; $contents = scandir($directoryPath); foreach($contents as $content) { if(is_file($directoryPath . DIRECTORY_SEPARATOR . $content)) { array_push($fileNames, $content); } } return $fileNames; }
This is a quick and simple one liner to list ONLY files. Since the user wants to list only files, there is no need to scan the directory and return all the contents and exclude the directories. Just get the files of any type or specific type. Use * to return all files regardless of extension or get files with a specific extension by replacing the * with the extension. Get all files regardless of extension: $files = glob($dir . DIRECTORY_SEPARATOR . "*"); Get all files with the php extension: $files = glob($dir . DIRECTORY_SEPARATOR . "*.php"); Get all files with the js extension: $files = glob($dir . DIRECTORY_SEPARATOR . "*.js"); I use the following for my sites: function fileList(string $directory, string $extension="") :array { $filetype = '*'; if(!empty($extension) && mb_substr($extension, 0, 1, "UTF-8") != '.'): $filetype .= '.' . $extension; else: $filetype .= $extension; endif; return glob($directory . DIRECTORY_SEPARATOR . $filetype); } Usage : $files = fileList($configData->includesDirectory, ''); With my custom function, I can include an extension or leave it empty. Additionally, I can forget to place the . before the extension and it will succeed.