Without using include_once or any include/require how can I reference functions declared in other php files in the current directory? Just like we use fopen.
Including contents of php files which contain code not in functions can be a clutter. It'd be better if function usage is linked automatically to its definition.
I've also checked How to include() all PHP files from a directory? which requires some code to do it.
I'm not able to find answer of this anywhere in internet may be because of too common search terms for this problem.
The most logical approach would be to use OOP and autoloading.
That way you would only load the classes that you actually use.
Otherwise the accepted answer from the question you linked to, is the way to go.
You can use glob to traverse the directory and then include them:
$phpfiles = glob('mydir/*.php');
foreach($phpfiles as $file)
do_something_with_the_file($file) // why not include_once $file ?
As you are referencing functions in other files, you cannot use the autoloader because the autoloader operates on classes. Autoloading classes would be a much better solution.
If you're keen on using classes and OO vs Procedural, this will include a file by the same name as the class that's being called, and will not include class files in the directory that are not needed.
Called from the root directory of the site/application.
define( "APP_PATH", dirname( __FILE__ ) ."/" );
function my_autoloader($class)
{
include 'core/classes/' . $class . '.class.php';
}
spl_autoload_register('my_autoloader');
Assuming you keep all your classes in a similar directory structure:
site/core/classes
You get the idea.
Related
Uisng spl_autoload_register for auto loading classes on my code. Example:
<?php
spl_autoload_register(function ($class_name) {
include 'my_class1.php';
include 'my_class2.php';
//...
include 'my_classN.php';
});
$obj = new MyClass1();
?>
What if I used just class MyClass1 in my code, does autoload loads all files or just my_class1.php?
Thanks in advance.
EDIT: DO NOT use above code. Now I using #Alex Howansky's code with PSR-4 autoloading specifications.
NOTE: Autoload requires to use namespaces if classes located in subdirectory relatively to basedir (see examples).
With this code, the first time you refer to any class, it will load every class. This will work, but almost certainly isn't what you want. In an autoloader, you usually just want to load only the one source file containing the one class referenced by $class_name. Something like this:
spl_autoload_register(function ($class_name) {
$filename = '/path/to/classes/' . $class_name . '.php';
require_once $filename;
});
This obviously becomes very difficult if your source file names don't match your class names or you otherwise can't determine the source file names based on the class names. This is why you should use PSR-4 naming conventions.
Just as an addition, you can use the PHP function get_declared_classes() which will list all defined classes in the current script.
The folder structure is like so:
/main.php
/lib/class1.php
/lib/class2.php
/lib/class3.php
I want to have main.php make available all the classes in lib without doing a ton of require/include. Is this possible? Is it possible to just include all files within a directory?
Create an autoloading function to load the class directly from your URL
function __autoload($class_name) {
include "/lib/".$class_name . '.php'; //Add your folder structure like this
// ^ Change the path to your specific need
}
//Then Simply
$class1_object = new Class1();
Yes, yes it is entirely possible and quite easy to do. Best way to do so would be to utilize http://uk1.php.net/autoload
I would suggest you use an autoload function like #Puciek suggested.
If you are curious about doing it yourself though, you can do something like:
$path = "lib/";
foreach(new \DirectoryIterator($path) as $lib){
if(strstr($lib->getFilename(), ".php")){
require_once $path.$lib->getFilename();
}
}
The above will use DirectoryIterator which is part of the PHP SPL.
$path = '/lib/';
$dir = new DirectoryIterator($path);
foreach($dir as $spl){
if($spl->getExtension() != 'php') continue;
include($spl);
}
Basically I looped through the directory's files, filtered out the not php files, then included them. You can feel free to add more filters like files starting with "class" as filenames.
You can also have a look to glob() function to php, which returns an array with all the files within a directory:
http://it2.php.net/manual/en/function.glob.php
The good thing about the directory iterator is that you can use a RecursiveDirectoryIterator alongside with a RecursiveIteratorIterator to iterate through a directory tree in a similar way if you want, to get all the files as well.
Autoloading would be a good option for this but that assumes there is a way to map class names to file names, if that is an option you should follow #puciek advise.
Other options would be to create a single include that includes all of the files you want for example in /lib create a file called all.php and define it as
include("class1.php");
include("class2.php");
include("class3.php");
then in your script you could just include("lib/all.php");
Another option would be to glob the files in a directory then loop through the resultant array and issue an include.
$includes = glob("lib/*.php");
foreach($inclues as $inc){
include($inc);
}
Use lazy loading rather than importing everything - http://php.net/manual/en/function.spl-autoload-register.php
function autoload($sClass) {
$sPath = str_replace('_', DIRECTORY_SEPARATOR, $sClass) . '.php';
require_once($sPath);
}
spl_autoload_register('autoload');
new My_Class();
This is a very stripped back example but it's something to build on. Ideally you would check that the file exists on the include path (http://php.net/manual/en/function.stream-resolve-include-path.php), check that the file is readable, that the require/include was successful and that the class exists at the end of the autoload
I'm a c# developer, so I'm used to simply compiling a library and including it within a project for use. I haven't really figured out the best way to load different objects within a PHP application. I don't want to keep using require. What is a good approach to take?
If you're using PHP 5.x, you probably want autoloading.
You don't need to keep using require. You can require_once() which will only parse the file if it has not already been loaded.
Also in PHP, since the includes happen at runtime you are free to require_once() in the middle of a conditional if it is appropriate.
// Only load Class.php if we really need it.
if ($somecondition) {
// we'll be needing Class.php
require_once("Class.php");
$c = new Class();
}
else // we absolutely won't need Class.php
I was C# developer in the past and I can tell you that you need to think bit different if you want to write PHP sites. You need to keep in mind that every unnecessary include will increase extra expenses of resources, and your script will work slower. So think twice before add unnecessary includes.
Back to your question you can use include, require, autoload or even phar. Probably PHAR is more close to C# libraries, you can include one PHAR libraries with a number of classes.
Put this in your config file( or any file included in all pages )
function __autoload($class_name) {
require_once "Classes" . $class_name . '.php';
}
Put every class in seperate file with its name.
replace "Classes" with your classes folder.
You can autoload classes. See:
http://us3.php.net/autoload
From that page:
<?php
function __autoload($class_name) {
include $class_name . '.php';
}
$obj = new MyClass1();
$obj2 = new MyClass2();
?>
Note that you can use spl_autoload_register() if you don't want to use the single magic __autoload function.
The autoloader will solve all your problems.
Autoloader, as others mentioned.
If you want to go step further... look at the way how Kohana (for example) solved the problem.
This question is the first Stack Overflow result from searching "php how to load classes" and other answers which provide examples for autoloading suggest the use of __autoload(). Please note that use of __autoload() is deprecated as of PHP 7.2 and its use is discouraged. Using spl_autoload_register is suggested instead.
The example snippet below is from the documentation page:
spl_autoload_register(function ($class_name) {
include 'classes/' . $class_name . '.php';
});
I currently am building my own PHP framework and am creating a lot of directories to store my classes in.
This is my current autoload function:
function __autoload($className)
{
$locations = array('', 'classes/', 'classes/calendar/', 'classes/exceptions/', 'classes/forms/', 'classes/table/', 'classes/user', 'pages/', 'templates/');
$fileName = $className . '.php';
foreach($locations AS $currentLocation)
{
if(file_exists($currentLocation . $fileName))
{
include_once ($currentLocation . $fileName);
return;
}
}
}
Now in my main class file I do have all of the necessary classes already included so that they won't have to be searched for.
Here are my questions:
Is this function efficient enough? Will there be a lot of load time or is there a way for me to minimize the load time?
Is include_once() the way that I should go about including the classes?
Is there a way that I could write the function to guess at the most popular folders? Or would that take up too much time and/or not possible?
Would namespaces help me at all? (I am reading and learning about them right now.)
This is answered very well here: autoload and multiple directories
You should probably go with require, for two reasons: a) you don't need to have PHP track if the file has been already included, because if it has it won't need to call __autoload in the first place and b) if the file cannot be included you won't be able to continue execution anyway
The answer for point 1 covers this
Not necessarily; you need some namespace-like mechanism to implement faster loading (to only look where you have to) but you can fake it if necessary without using real namespaces
For reference, the interaction between __autoload and namespaces is documented here.
I've just started to build my very own MVC framework. Feel's kind of nice to know everything from the ground up and only get the stuff that's really necessary for my app.
I come from a codeIgniter background which helped me to get into the MVC perspective of seeing things. In codeigniter, to include a file, codeIgniters very own load class is used.
This load class, when loading a file, checks if a file have previously been included, and if not includes it, which ensures that a file isn't included twice.
However this method of including files has the downside of making it impossible (?) to run tests on my files or take advantage of PHPdoc in my IDE, which I need.
Clearly, I can use the normal include & require functions in PHP forwards and backwards across my application, where a certain library would be needed, but it clearly won´t be good to possible include the same file twice...
So - what's a good solution to use in my own PHP5 MVC framework to include files?
I'm doing a similar thing to you, and I'm using autoload.
Just put this in index.php:
function __autoload($class_name) {
include $class_name . '.php';
}
or include whatever logic you need to check multiple directories.
Edit: Here's my (slightly flaky) code for checking an alternate path. It could be done a lot more cleanly if you were going to need to check multiple paths.
function __autoload($class_name) {
$path = INC_PATH . strtolower($class_name) . '.php';
if (!file_exists($path)) {
$path = MODELS_PATH . strtolower($class_name) . '.php';
}
require $path;
}
just use include_once and require_once . while CI has a load class, you're by no means required to use it.
use include_once/ require_once but the best solution would be working with a autoloader
http://php.net/manual/de/language.oop5.autoload.php
what IDE do you use?
Generally php has the built in include_once which as the name says includes the file, but only once.
Or you can use autoloading which most IDEs support (though some need a bit of a hint - depends on what IDE are you using).