I have a list of files, wherein a file is inherting another file ion the same directory. I want to include all files of a directory, how do I do it in the order of inheritance so that I dont get any errors
Instead of calculating dependencies yourself, you might as well use auto loading using spl_autoload_register().
This way your dependencies get worked out as required. A bit like "Just-In-Time" loading :)
If your file/s have certain dependencies on other files, make sure you include the "parent" file/s first.
For example, you have a class A in a file A.php:
<?php
class A {
// .. statements
}
And you have a class B that extends A named B.php:
<?php
require_once( "A.php" );
class B extends A {
// .. statements
}
The idea is to "include"/"require" the needed files first prior to using any functions/classes/statement in that file. In PHP 5, you can use the auto-loading functions that would "automatically" add/include the file you need without the constant need of typing require functions.
You COULD use a parser to chek for dependecies but this would be a awfull lot of work and a real performance killer.
You could sort the files and prefix them with numbers
001.init.php
002.db_connect.php
003.pre_filters.php
But if you sort them manually it is rather pointles to rely on the file names.
If you have class inheritance you can combine a autoloader and require once.
Register an custom autoloader to require fles using require_once and and include all your files with a loop. If you need a class from the 8th file in your 4th file the autoloader will load the 8th file ahead of time and when your inlude loop reaches the 8th file nothing will happen because require_once will not include the file again.
But as you might already have realized:
Including files which are depending on each other in a random order from the file system is NOT a good idead.
Related
This is what I have at hand:
//Person.php
namespace Entity;
class Person{
}
User file:
//User.php
use Entity\Person;
$person = new Person;
Here, it fails if I don't include the Person.php file. If I include it, the everything works fine. Do I absolutely require to include the file even when using namespaces? If at all we need to include/require files, then how can namespaces be effectively used? Also, can we maintain folder structure by nesting namespaces?
The answer to your question is "yes and no".
Indeed the code implementing class Person has to be included, otherwise the class is not defined and cannot be used. Where should the definition come from, when the code is not included? The php interpreter cannot guess the classes implementation. That is the same in all programming languages, by the way.
However there is something called Autoloading in php. It allows to automatically include certain files. The mechanism is based on a mapping of class names to file names. So in the end it boils down to php searching through a folder structure to find a file whos name suggests that it implements a class currently required in the code it executes.
But don't get this wrong: that still means the file has to be included. The only difference is: the including is done automatically, so without you specifying an explicit include or require statement.
Yes, you need to include every file.
A very good example can be found here on effective usage of namespaces.
With PSR-0 autoloading, the namespace has to be the same as the folder in which the class is, file the filename has to be the same as the classname. This gives you very simple and effective autoloading with composer for example.
I'm trying to start using SPL Autoloader but I can't seem to grasp its importance yet.
Lets say I have a directory "classes" with sub-directories and php files in them as classes as follows.
'classes/feed/feed.php';
'classes/compose/file_upload.php';
'classes/compose/char_limit.php';
'classes/feed/postrank/postrank.php';
'classes/notifications/push.php';
Then I create a PHP file called autoloader.php inside "classes" directory with includes as follows
<?php
include_once 'feed/feed.php';
include_once 'compose/file_upload.php';
include_once 'compose/char_limit.php';
include_once 'feed/postrank/postrank.php';
include_once 'notifications/push.php';
?>
Then on every page where I want those classes I just include the autoloader.php file to include all classes of the project.
1. What problems I'm I going to face as the project grows?
2. If I were to start using SPL Autoloader how would I set it up with my current directory structure?
3. Is there a difference in loading time between using include/require compared to SPL Autoloading ?
4. Should all the classes be under one directory "classes?" or there's no problem with my file structure?
1. What problems I'm I going to face as the project grows?
You'll have to include more and more files in your autoloader.php. Plus, you'll have to include it in your every new file. More file reads. Less performance.
2. If I were to start using SPL Autoloader how would I set it up with my current directory structure?
Directory structure doesn't matter (assuming your classes tree is arranged nicely and logically). What matters is the namespace you specify inside your class. For example, if you want SPL to auto-load a class containing in your classes/feed/postrank/postrank.php file (a postrank class declaration, presumably), this file has to have a namespace declaration inside it, e.g.:
namespace classes\feed\postrank;
class postrank {
...
}
This way SPL would know how to find the declaration of the class in your application's file system.
3. Is there a difference in loading time between using include/require compared to SPL Autoloading ?
If you include everything in autoloader.php, you force PHP to read and include every single file in there. SPL only loads the classes you need, and only when you need them. The time difference could be noticeable if you have a decent number of files and classes (say, hundreds of them), depending on your application server performance.
4. Should all the classes be under one directory "classes?" or there's no problem with my file structure?
Depends on your application structure really, so it's entirely your call.
This is what I have at hand:
//Person.php
namespace Entity;
class Person{
}
User file:
//User.php
use Entity\Person;
$person = new Person;
Here, it fails if I don't include the Person.php file. If I include it, the everything works fine. Do I absolutely require to include the file even when using namespaces? If at all we need to include/require files, then how can namespaces be effectively used? Also, can we maintain folder structure by nesting namespaces?
The answer to your question is "yes and no".
Indeed the code implementing class Person has to be included, otherwise the class is not defined and cannot be used. Where should the definition come from, when the code is not included? The php interpreter cannot guess the classes implementation. That is the same in all programming languages, by the way.
However there is something called Autoloading in php. It allows to automatically include certain files. The mechanism is based on a mapping of class names to file names. So in the end it boils down to php searching through a folder structure to find a file whos name suggests that it implements a class currently required in the code it executes.
But don't get this wrong: that still means the file has to be included. The only difference is: the including is done automatically, so without you specifying an explicit include or require statement.
Yes, you need to include every file.
A very good example can be found here on effective usage of namespaces.
With PSR-0 autoloading, the namespace has to be the same as the folder in which the class is, file the filename has to be the same as the classname. This gives you very simple and effective autoloading with composer for example.
This question already has answers here:
PHP include best practices question
(10 answers)
Closed 9 years ago.
What is the best practice for including PHP files?
Is it best to include a include.php file that includes all of the project PHP files?
Or to include it in those files that need them
Right now, my project has several include files in my index.php file. Does including all of my php files in the index.php make it less efficient?
Lastly, Where should one include the session check PHP file? in all of the PHP files?
EDIT 2016
Well, 5 years since I replied this. I am still alive. A lot has changed.
Now I use autoloaders to include my files. Here is official info for autoloaders with examples.
Basically, the idea is to have a proper folder structure (PSR-4 standards for instance) and having a class within each file. This way you can use autoloaders and PHP will load your files automatically.
OLD ANSWER
Usually, I have a config file like this:
define(root, $_SERVER['DOCUMENT_ROOT']);
.... // other variables that are used a lot
include (root . '/class/database.php');
.... // other includes that are mostly called from each file, like a db class, or user class, functions etc etc...
if (defined('development'))
{
// turn error reporting on
}
else
{
// turn it off
}
etc etc... You got the point of config.
And I include the config.php on each file. I forgot how to do it right now, but apache can do the automatic include for you. Therefore, you can say to apache to include your config file by default.
Then, I have controller classes, which call the views. There in each function I call the view.
someController.php
function index() { include root . '/views/view_index.php'; }
finally, from the view, if I need to include the header and footer view I do it like this:
view_index.php
<?include root . '/view/shared/header.php';?>
<div class="bla bla bla">bla bla bla</div>
<?include root . '/view/shared/footer.php';?>
I always use include in this structure rather than include_once since the latter requires extra check. I mean, since I am pretty sure that I include files only once, I don't need to use include_once. This way, you also know which include is where. For instance, you know that crucial files like db.php, or functions.php are located in config.php. Or you know that include views are located in controllers. That's pretty useful for me, I hope that helps you, too.
Using the include.php file is a very good practice according to me, as it is very helpful in changing the included files in big projects. If the project is small then including individual files is not a problem. But it becomes a problem to manage them as the project grows big.
For the session check file it is better to attach them individually as the requirement to check session on different pages might differ.
Including files individually or including them all in a single file and then including that makes much of the difference to the performance. As ultimately all the files are going to be included. It only becomes easy to manage them if single file is used to handle them.
I don't assume you are using object oriented programming but in case you do here might be a good answer.
In php you can define a function called the autoloader, if you try to create an object of a class that has not been defined the autoloader is called. You can then use the class name to figure out where the file containing that class is stored to include it at the last moment. Here is an example..
<?php
function on_load($class)
{
if(file_exists(require_once('classes/'.$class.'.php')))
{
require_once('classes/'.$class.'.php');
}
else
{
throw new Exception('Class not found: '.$class.' in classes/');
}
}
spl_autoload_register('on_load'); // tell php to call your on_load function if the class was not defined
If you're working on a big project you might want to group your files like this
/classes/database/MySQL.php
/classes/database/PDO.php // I'm just listing random stuff
/classes/Core.php // Whatever
/classes/datastructure/HashMap.php
You can then use a special naming convention to find the right directory
class Database_MySQL{} // look in <root_dir>/database/ for MySQL.php
class Core // look in <root_dir>/ for Core.php
class Database_Driver_Adapter_Useless_MysqlAdapterThingy {} // look in <root_dir>/Database/Driver/... blabla
Or you can use the php 5.3 way and define your classes like this
<?php
namespace database\driver\adapter\useless;
use database\driver\adapter\MysqlAdapter; // Now you have to tell PHP which version of MysqlAdapter class you want to use, even if there is just one
class MysqlAdapterThingy extends MysqlAdapter {}
Now you have to use the 'use' keyword in every file you need that class. The cool thing is that the namespace is automatically added to the class-name for your autoload function so you can do something like this
function on_load($class)
{ require_once('root/' . str_replace('\\', '/' $class)); }
If you want to learn more try googeling PHP auto-loading there is tons of information on this subject. But then again. From the format of you question I do not assume you're using OOP so this answer is just for the people who found this question on google.
Edit
I would also like to add the following:
// Only include the file once even if you place this statement multiple times
require_once('bla.php');
include_once('bla.php');
require('bla.php'); // Error if file doesn't exist, php will not continue
inlcude('bla.php'); // Warning if file doesn't exist, but php will continue
Using include or require without _once means that file will get included every time the statement is executed
Use include for template or user generated files, use require_once for classes
Just think easy, and think about load as less as possible and don't include something unnecessary.
So for your PHP files. if you include same php files on different pages just create 1 PHP file with this files in it.
If you use a PHP file in 1 page or 2 only, just include them seperate.
I hope i helped you with it ;)
Include files independently, use require_once() function instead of include, as require_once allow only one inclusion of file...
In PHP are classes only seen when they are in an include file? In Java I can see them in another file without including that file in my current file. In PHP is the only way to see any given class to include it in your file? So I'm just including my class file(s) everywhere?
In PHP are classes only seen when they are in an include file?
Yes. However, in PHP 5, there is the new Autoloading feature that allows you to build a function that includes a file when a class name is invoked. That effectively makes it possible to auto-initialize classes.
The simple example in the manual (I extended it slightly) makes it clear how this works:
<?php
function __autoload($class_name) {
require_once $class_name . '.php';
}
$obj = new MyClass1(); // Autoloader will load "MyClass1.php"
$obj2 = new MyClass2(); // Autoloader will load "MyClass2.php"
?>
Advanced autoloaders like Zend Framework's Zend_Loader_Autoloader (and the Standard PHP Library's spl_autoload_register(), cheers #ircmaxell) make it even possible to add different autoloading rules for different prefixes, allowing for libraries to be loaded from varying directories with varying naming conventions.
Generally speaking, yes. However, do note that includes are cascaded--in the sense that: if you include file a.php which includes file b.php, you can now see file b.php in your current file.
Also, PHP 5 offers Autoloading Classes which I recommend you take a look at:
http://php.net/manual/en/language.oop5.autoload.php
Yes -- PHP doesn't have any visibility into code which wasn't included directly in the file using the code.
However, instead of including (or the preferred method -- requiring) .php files everywhere, many developers choose to use the PHP autoload ability (http://php.net/manual/en/language.oop5.autoload.php) to automatically load the required file when you use a particular class.
Yes, for a class in a file to be available, that file has to be included.
Including a file can be done in a number of ways, either using the following functions:
include(filename);
include_once(filename) - which only includes the file if it's not already loaded
require(filename) - equal to include, except that the script will halt if file is not available
requier_once(filename)
Files can also be autoloaded through the __autoload or spl_autoload_register functions. More info on autoloading classes on PHP.net.
Yes only in include statements will you have access to the functions in other php files. PHP is by standard a Procedural language. It works from the top order down, so if you wish to perform class like includes look at Object Oriented PHP or include the files at the top of the php page.