I come across an application using this method to include all class files by using this code
foreach(glob("class/*.php") as $file)
{
include_once "$file";
}
It actually works, but do not know this way to include all files at once would cause any problems later? Is this method to include many files at once recommended?
Thanks
I think autoloading would be better.
Check out here http://php.net/manual/en/language.oop5.autoload.php
One simple example from the document could be tweaked to suit your case
<?php
function __autoload($class_name) {
include 'class/'. $class_name . '.php';
}
$obj = new MyClass1();
$obj2 = new MyClass2();
?>
This will create a lot of unnecessary overhead if any of the classes aren't used. Each file will have to be parsed which will be unnecessarily time consuming. I agree with #Liangliang Zheng 100% in that you should use __autoload. As for the suggestion of #lbu and your original solution, it is recommended to not use the _once versions, they are more costly than just using include and require.
Related
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).
I have a command interpreter in php. It lives inside the commands directory and needs access to every command in the command file. Currently I call require once on each command.
require_once('CommandA.php');
require_once('CommandB.php');
require_once('CommandC.php');
class Interpreter {
// Interprets input and calls the required commands.
}
Is there someway to include all of these commands with a single require_once? I have a similar problem many other places in my code (with factories, builders, other interpreters). There is nothing but commands in this directory and the interpreter needs every other file in the directory. Is there a wildcard that can be used in require? Such as:
require_once('*.php');
class Interpreter { //etc }
Is there any other way around this that doesn't involve twenty lines of include at the top of the file?
foreach (glob("*.php") as $filename) {
require_once $filename;
}
I'd be careful with something like that though and always prefer "manually" including files. If that's too burdensome, maybe some refactoring is in order. Another solution may be to autoload classes.
You can't require_once a wildcard, but you can programmatically find all the files in that directory and then require them in a loop
foreach (glob("*.php") as $filename) {
require_once($filename) ;
}
http://php.net/glob
Why do you want to do that? Isn't it a better solution to only include the library when needing it to increase speed and reduce footprint?
Something like this:
Class Interpreter
{
public function __construct($command = null)
{
$file = 'Command'.$command.'.php';
if (!file_exists($file)) {
throw new Exception('Invalid command passed to constructor');
}
include_once $file;
// do other code here.
}
}
You can include all files using foreach ()
Store all files name in array.
$array = array('read','test');
foreach ($array as $value) {
include_once $value.".php";
}
It's 2015 now, so you're most likely running PHP >= 5. If so, as mentioned a couple of times above, PHP's autoload capability is a good solution, probably the best. It was created specifically so you won't have to write a utility function for auto loading. However, as mentioned in the PHP docs, __autoload is no longer recommend and may be depreciated in future versions. As long as you're using PHP >= 5.1.2, use spl_autoload_register instead.
Just wondering if there is anyway to have PHP just run a certain class given the name of the file (controller.php)?
I don't want to require, include or see any signs of it in the controller.php. I just want it to be there.
EDIT: Ok. What I mean by run is in some file hidden away from me I say something like... $class = new Class(); This way I can use $class in my controller.php
ALSO: I'm running PHP 5.3 - So I have namespaces and whatnot.
Anyway of doing this??
Thanks!
Matt Mueller
I'm going to take a big guess at what you really mean. I think you simply want to separate your class PHP file away from your main file without making any obvious includes.
If so, you might want to use the __autoload() function:
<?php
function __autoload($class_name) {
require_once $class_name . '.php';
}
$obj = new MyClass1();
$obj2 = new MyClass2();
?>
This will notice that MyClass1 and MyClass2 haven't yet been defined and will call the autoload function with their class names as the parameter. So then MyClass1.php and MyClass2.php will be require_once'd.
You can autoload the Class file, you will still have to instantiate the Class by hand at some point. Or you will have to include a script that instantiates it for you. Or you re-architect your application so your actual script is included by another script, which pre-instantiates the Class for you.
In short: including the file can be automated, instantiating the Class not so much.