I have a directory in my project which contains 10 php files.
files/
file1.php
file2.php
file3.php
.
.
.
I want to add the following line to all of those 10 php files:
require_once('/config.php');
I can open them manually and add this ^ line into all of them. But in that case, if the path of config.php changed, then I have to modify all those 10 php files.
Anyway, Isn't there any better manner to include that line into all files of a directory? I suspect it may be possible by using autoloader. Am I right?
Autoloaders are not intended to load files, but to load class definitions (which just happen to be inside of a file.
Therefore, whether you can use autoloader to load those files or not, will depend on what those files actually contain.
As for how autoloader would work, you can look up the PHP's manual or PSR-4 doc. If those are what you are looking for, in that case it would be actually easier to just use the autoloader, that is bundled with composer instead of making your own.
It's always better to have a single entry point for your scripts so that all the common files can be included there. You can use 'autoloader', but even that needs to be 'included' in all these files to work fine. Try to store similar files in the same directory. For eg: keep all your controller files in the controller folder, config files in the config folder.
Related
I have a php file outside my webroot in which I want to include a file that is inside the webroot.
folder outside webroot
- > php file in which I want to include
webroot
- > file to include
So I have to go one directory up, but this doesnt work:
include('../webroot/file-to-include.php');
Include full path doesn't work either:
include('home/xx/xx/domains/mydomain/webroot/file-to-include.php');
How can I accomplish this?
Full path should be:
include('/home/xx/xx/domains/mydomain/webroot/file-to-include.php');
Or you should set the path like:
include(__DIR__ . '/../webroot/file-to-include.php'); // php version >= 5.3
include(dirname(__FILE__) . '/../webroot/file-to-include.php'); // php version < 5.3
Have this in a common file, shared by all your php sources outside the webroot:
<?php
define('PATH_TO_WEBROOT', '/home/xx/xx/domains/mydomain/webroot');
And then use the following to include files.
<?php
include (PATH_TO_WEBROOT.'/file-to-include.php');
If the location of your webroot changes, you will only have to change that once in your code base.
You can configure php to automatically prepend a given file to all your scripts, by setting the auto_prepend_file directive. That file could for instance contain the PATH_TO_WEBROOT constant, or require_once the file which contains it. This setting can be done on a per domain or per host basis (see the ini sections documentation).
Also, consider using the autoload feature if you are using classes extensively.
Try prepending a trailing slash to your full path, so it looks like
include('/home/xx/xx/domains/mydomain/webroot/file-to-include.php');
Otherwise, it will be interpreted as a relative path.
You could also try to change the dir into the webroot and see if this works - for debuggign purposes:
chdir("/home/xx/xx/domains/mydomain/webroot");
include "your_file.php";
I put the secured data in the file named conn.txt,
and then I used the following PHP command:
$DbInfoFile = "../conn.txt";
Fast forward to the current day (2021), an alternative method is to simply add the PHP include_path directive into your php.ini (or user.ini) to point to the includes folder, wherever it is (inside or outside the public root). This method blends the ease of changing one line of code in your project without touching the the PHP code at all. I have no idea if this works on a Windows box since I'm on CentOS.
Example: include_path = ".:/home/{acct-name}/{include-path}" (this would be one level up from public_html or whatever your public folder is called)
This blended approach allows you to simply invoke include 'file-to-include.php'; in your PHP code without going through the whole hassle of defining the root, while retaining the flexibility of changing the includes file by modifying only one line of code sitewide.
By the way, you can have multiple include locations. In that case, you can separate the two locations with a colon such as include_path = ".:/home/{acct-name}/{include-path-1}:/home/{acct-name}/{include-path-2}".
This should work
$_SERVER['DOCUMENT_ROOT']/home/xx/xx/domains/mydomain/webroot/file-to-include.php
And make sure you have access to that level.
My PHP application has different config files with their different settings and their different paths. But all of them need to access to just one database connection file. I would like to avoid mention its path separately on them with many ../ and ../../. How can I write a same code and use it in all of them?
Imagine that my PHP application has this hierarchy for its config files:
root
root/config/db.php (This file is what I want to mention from all config files.)
root/admin/config/conf.php
root/users/conf.php
Actually what I need is something that detect the root path of my project and create a same directory path generally.
Use $_SERVER['DOCUMENT_ROOT'] and then path to your file.
Use PHP's class autoloading, the catch being you then need to wrap up your config information in a class, but it works.
require_once("../../config/db.php");
Include this file into "conf.php" file
Set the include_path directive as either root/ or root/config/ either by editing your php.ini file or by calling set_include_path on every page. This way, you can just include/require "db.php" on each page.
I've been writing:
include('a.php')
include('b.php')
etc. in my script to include to use functions a() and b(). It gets pretty tedious. Is there a way to set a path of a directory and have multiple files there be accessible by a script?
I tried this in my script:
set_include_path('.;C:\xampp\htdocs\myfunctionfolder');
And I set an environmental variable PATH to have this older in there.
I also in modified php.ini to include
include_path = ".;\xampp\php\PEAR;\xampp\htdocs\myfunctionfolder"
If I have many files in there, how do I access these files without having to include each individually? Setting the environmental variable definitely works in the command prompt.
Do I need to do something else for .php files to be accessible collectively under a directory?
Common practice is to have a "common.php" or "includes.php" file that includes the include/include_once calls (for the sake of simplicity). e.g.
root
[lib]
a.php
b.php
includes.php
index.php
Then includes.php contains:
<?php
include_once('a.php');
include_once('b.php');
?>
Then in any script it's a matter of including the includes.php file.
However, to answer your original question, you can only include one file at a time, per call. You can use something like opendir and readdir to iterate over all files in a specific directory and include them as found (automated so-to-speak) or write out each include yourself based on the files you're creating.
Also, all setting the include path does is set a directory to look in when an include call is made. It's not a directory where the files should automatically be loaded (which is the impression I get from your post).
Setting the include_path will not include every file in that directory, it only adds that directory to the list PHP will search when including a file.
Specifies a list of directories where the require(), include(), fopen(), file(), readfile() and file_get_contents() functions look for files.
Source
This would simplify including files in a deep structure or in a completely different section of the filesystem.
include('/var/somewhere/else/foo.php');
With /var/somewhere/else/ added to the php.ini include_path could become
include('foo.php');
Additionally, as others pointed out, there are common practices but you could look into OOPHP and autoloading classes. This will not work for functions that I know of.
Many developers writing object-oriented applications create one PHP source file per-class definition. One of the biggest annoyances is having to write a long list of needed includes at the beginning of each script (one for each class).
In PHP 5, this is no longer necessary. 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. By calling this function the scripting engine is given a last chance to load the class before PHP fails with an error.
PHP's parser is pretty efficient - you'll waste a lot more time loading a ton of individual files instead of one (or a few) more monolithic files. However, if you insist on keeping things segregated like that, you CAN create meta-include files to load sets of individual files, so you'd only include the one single meta-include file, and it does the rest for you:
meta.php:
include('a.php');
include('p.php');
...
include('z.php');
And then you simply do:
<?php
include('meta.php');
in your scripts and you've got all the individual ones loaded for you.
I have a function like this in most of my projects:
function appendToIncludePath($path)
{
ini_set('include_path', ini_get('include_path') . PATH_SEPARATOR . BASE_DIR . $path . DIRECTORY_SEPARATOR);
}
see this question:
How to include() all PHP files from a directory?
Also, in terms of best practices, you can include multiple functions in the same file if they are at all related, and I would also suggest having more descriptive names of your functions and files. For example, if your a() and b() functions both related to validation for example, name your file validation.php and put both functions in there and try to rename them to something that is related to what they do. This will allow you to remember what they do when you start piling up a huge list of functions ;)
include __DIR__ . '/../folder1/folder2/folder3/Target.php';
include __DIR__ . '/../folder1/folder2/Target.php';
It helps you go to any path.
Download latest PHP zip and extract to C drive then download composer and install it, during installation it ask for PHP path so just select extracted PHP path.
As follow below step.
Go to Computer.
Select Advance System Settings.
From system properties select Environmental Varaibles.
In Environmental Varaibles add Path in User Variable for PCNAME
In Environmental Varaibles add Path in System Variables.
Hit OK.
Restart PC.
Win + R type cmd.
type command php -v.
Vola you good to go.
PHP
http://php.net/downloads.php
Composer
https://getcomposer.org/download/
I have a site where the PHP include path is /usr/share/php
Within this path I have a sub-folder containing some utility files, e.g. /usr/share/php/utils. my_session.php is one of these utility files.
My application calls
require ("my_session.php");
and this works even though the file is actually within the utils folder.
I am trying to replicate this site in another installation and I am getting the error:
Failed opening required 'my_session.php' (include_path='.:/usr/share/php)
My question is:
Should the php include path also include files in sub-folders in the include path?
This appears to be the case on my original site and I don't know why the behaviour seems to be different on the second site.
According to PHP documentation when you try to include a file, only paths listed in the include_path directive are checked. PHP is not supposed to check their subfolders.
My guess would be that this fails because you are using a relative path for the require.
Your include_path is defined as .:/usr/share/php. That means only two folders will be checked when require('my_session.php') gets executed:
the current path
the folder /usr/share/php
I don't know your folder structure, so let's just imagine one:
my_project
- app
-- index.php
- lib
-- my_session.php
Now, if my_project/app/index.php tries to require('my_session.php') this will fail, because the current folder at the time executing the require is my_project/app/ and there is no file entry of my_session.php relative to my_project/app/ (it's relative to my_project/lib/ instead).
Long story short: Try to to use an absolute path instead of your relative one, e.g.
require('/var/www/html/my_project/lib/my_session.php');
Edit: removed and its subfolders, which was wrong. Too much __autoload in my brain^^
Two solutions:
Add /usr/share/php/utils to your include_path.
or
Include your file with require ("utils/my_session.php");
I'm in the process of setting up a php project, but am not very familiar with how to properly use php's include/require commands. My layout currently looks like this:
/public --apache points into this directory
/public/index.php
/public/blah/page.php
/utils/util1.php -- useful classes/code are stored in other directories out here
/dbaccess/db1.php
dbaccess/db1.php
require '../utils/util1.php
public/index.php
require '../dbaccess/db1.php'
public/blah/page.php
require '../../dbaccess/db1.php'
The problem is this from the php 'include' documentation:
If filename begins with ./ or ../, it is looked only in the current working directory
So public/blah/page.php fails because it includes dbaccess/db1.php which blows up when it tries to include util1.php. It fails because it's relative path is from the original script in public/blah/, not from dbaccess/
This seems pretty stupid -- db1.php has to just know where it's being included from which isn't going to work.
I've seen strategies like this:
require_once dirname(__FILE__) . '/../utils/util1.php');
That apparently works since now the path is an absolute path, but just seems really bizarre to me.
Is that normal? Should I continue down that path or am I missing something obvious here?
Usually, the standard conventions are thus: like #grepsedawk said, you'll want to define a constant that contains the root of your project folder and if you can the root of your includes folder:
define('APP_ROOT', dirname(__FILE__));
define('INCLUDE_ROOT', APP_ROOT . "/includes");
Note: the constant name needs to be a string!
Also, you'll notice I'm using dirname(__FILE__);. If you place your constants definition file in a subdirectory, you can do a dirname(dirname(__FILE__));, which is the equivalent of a ../.
Now some other caveats. While PATH_SEPARATOR is a cool constant, it is not needed. Windows accepts / or \ in path names, and since Linux only users / as a path separator, go ahead and always use a / instead of mucking up your code with repeated references to PATH_SEPARATOR.
Now that you have your root constants defined, what you'll do when you need a configuration file included is a simple:
include INCLUDE_ROOT . '/path/to/some/file.php';
You'll probably want your constant definitions (the define(...)'s above) in a bootstrap script in your root directory:
www_root/
index.php
bootstrap.php
The bootstrap will contain the defines (or an include of the constants file), as well as an include of any files that will be required by EVERY page.
And finally the last standard convention you may not use, but if you start doing object oriented programming, the most common method (the PEAR standard) is to name your classes by using an _ to separate namespaces:
class GlobalNamespace_Namespace_Class
//...
And then organizing your file structure mapping name spaces to subdirectories (literally replacing all _'s with /'s):
include_dir/
GlobalNamespace/
Namespace/
Class.php
And using __autoload() functions to load your classes, but that's another question.
Have a configuration script that sets the "INSTALL ROOT" of your project and then use absolute paths. Relative path with multiple includes is a headache in php.
DEFINE("INSTALL_ROOT", "/path/to/www/project")
require_once(INSTALL_ROOT . '/util1.php')
in my config / setup file, i do something like
define('MYAPP_BASEDIR',realpath('.'));
then i reference everything relative to that.
... if your include directory relates specifically to class files and you are able to name them so that the include file name could be derived from the class, you might like to look into spl_autoload_register().
this latter part isn't a direct answer to your question, but it's very handy if you're doing includes for each class you use.
Keep in mind, it starts in the current working directory and then looks through the include paths. If you want to reference all of your paths from some central root directory (or many) you can add that directory in the php.ini file or you can do it programatically with set_include_path( $path.PATH_SEPERATOR.get_include_path());
I suggest an abstraction strategy.
In your application page area, have a single file that all pages include.
This "local" include file has one job: find the include file that is outside the application page area. It then includes that. It can probably be as simple as <?php include dirname(__FILE__).'/../include/include.php/'; ?>
This second file is the single entry point into your library structure. It, or something else it includes, has the job of finding where everything is and including it.
This structure means you have just one file as your library's entry point and how it finds the rest of the library is not the application pages' problem. It also means you have just one file in your application area which knows how to find your library's entry point.
If you need a way for different application pages to load different things, I would suggest a modularisation approach. This can either be a global array you set before the master include, or a function you can call to request libraries by name. Yes, this is a slightly fancier way of your master library file declaring a constant of where everything is -- but it removes the temptation of doing include LIBRARY_DIR.'/utils/util.php'; which straightaway makes it unnecessarily difficult to move util.php out of utils and into misc/util at a later date.
The other advantage of the chained files is that it is then much easier to make your codebase relocatable, which makes it possible for multiple versions to be runnable. And it makes it possible to have one tree for the application and another for your library. Which means another application could use your library. In fact, you could extend the chaining a bit more if you want to help with the isolation further.
You're right, your scripts doesn't have to know the physical path where your includes are.
IMO the location where the includes are should be configured in the PHP.INI file (or .htaccess if you preffer).
Suponse your includes (utils and database are stored here /home/scott/php_includes/).
PHP.INI:
include_path=.:/home/scott/php_includes/
Now your scripts can include the libraries in this way:
dbaccess/db1.php:
require_once 'utils/util1.php';
public/index.php
require_once 'dbaccess/db1.php';
public/blah/page.php:
require_once 'dbaccess/db1.php';
A lot of people have provided good solutions, but I've just got one performance-related remark while talking about includes and requires.
If you start include'ing and require'ing a lot of files, it can be tempting to use include_once or require_once. Cachegrinds of scripts that use a lot of _once's have shown that they really slow down performance as the script has to stop what its doing to scan and make sure the file hasn't been included already. Eliminating as many of the _once's as you can will help a lot.
There was perfect solution - pecl extension called "pwee" - it allowed user define his/her own extern superglobal constants / variable using XML file. Thus you were able to use absolute path as I recomend in such form:
require_once APP_ROOT."/path/to/your/script.php";
The advantage of such solution was:
accessible from everywhere
no server load - everything in server memory
The XML file contained
<Environments>
<Application name="www.domain.com" namespace="">
<Constants>
<Constant name="APP_ROOT" value="/full/path/to/project/source" />
</Constants>
<Constants>
<Constant name="WEB_ROOT" value="/full/path/to/project/public" />
</Constants>
</Application>
</Environments>
link to pwee project
You should distinguish these cases of inclusion:
standalone library - all includes should be relative - to let user integrate it to his/her project easily
executable scripts in your public directory - contain absolute includes to project files and to standalone libraries public files (which has relative includes inside - transparent to user). Using the APP_ROOT constant is elegant way.
a,link,script, form html elemets and header forwards should use relative path when diving into tree hierarchy and absolute path when using common files from higher levels of hierarchy
In case of relative path use this form:
require_once "./relative/path/to/script.php";
Why do I use past tense? Because the project is not more supported - works only with Php4. If anyone knows similar solution with support, please let me know.
The best way to do that is to build flexible autoload system.
Simple map of classnames and proprietary patches. Then any internal require_* or include_* is not needed.
There is of course matter of relative/absolute path for autoloader. Well, absolute is most system-efficient, so in the array I mentioned before u can prepend some kind of variable {I have used Phing-style variable} e.g.
<map>
<path classname="MyClass">${project_directory}/libs/my_classes/MyClass.php</path>
<path classname="OtherClass">${project_directory}/libs/some_new/Other.php</path>
<!-- its so flexible that even external libraries fit in -->
<path classname="Propel">${project_directory}/vendors/propel/Propel.php</path>
<!-- etc -->
</map>
This is xml (think about ini or yaml as well) file and requires compile to php during first start, but after that any path is absolute.
Oh, as you can see no file naming convention or file layout is mandatory - its huge advantage.
Cheers, Alan.
It seems that every time I move my simple scripts from one server to another I have to redefine where things are.
I set up a test environment at home, built a few things, and deployed them to a shared host. The result was that the $_server['DOCUMENT_ROOT'] was two folders higher than the public_html folder on one server, and on another server it was one folder higher.
That skewed all my references. So I tried $_server['WEB_ROOT'] and failed again. I was thinking that the web root was a reference to the root of publicly-accessible folders on the server, but I was wrong.
I have one to throw in the pile that did something really simple without adding a lot of code I don't understand (I don't understand a lot of this code either, I just kept adding as I read rules and got it to work).
This gave me a reference to the publicly-accessible web root on all three servers I tried it on. Now I can move my folder anywhere and it just works, no config file necessary!
pub-doc-root.php:
<?php
//You only need to paste the following line into your script once,
//and it must come before you reference the public document root of your website.
//Use $pubroot.'/path_from_public_document_root_to_file/filename.php
$pubroot = (str_replace(($_SERVER['PHP_SELF']), '', (str_replace('\\', '/', (realpath(basename(getenv("SCRIPT_NAME"))))))));
//uncomment the next line to show the calculated public document root
//relative to the document root.
//echo ("$pubroot");
?>
My test environment:
php 5.3.1
Apache 2.2.14 (Win32) mod_ssl 2.2.14 OpenSSL 0.9.8k
ZendServer-CE-5.0.0GA_RC181-5.3.1-Windows_x86
Why not require it based on it's full path?
For example, /sharedhost/yourdomain.com/apache/www is your document root, so why not use
require('/sharedhost/yourdomain.com/apache/www/dbutils.php');
This also has the advantage of you being able to store your includes outside of your wwwroot so they are far less likely to be inadvertenly exposed via the web.
You could also set up a global variable equal to the /sharedhost/yourdomain.com/apache/ part of it so you can move the site around.
require(WWWROOT . '/dbutils.php');
I use
require '../path/to/file.ext';
without problems.
Also require is a statement not a function so it should be used as
require '/path/to/file.ext';
not
require('/path/to/file.ext');