php includes that include another php file - php

I'm getting really muddled up now and my brain hurts! :( lol
Root:
index.php
Includes:
cat.php
dog.php
index includes dog: include("includes/dog.php");
dog includes cat: include("cat.php");
When I run index, for cat it says:
A link to the server could not be established
Access denied for user ...
However, if I run dog, I get no problems...
I'm guessing its the path, but i've tried ./includes/cat.php to no joy...

This is because when you include a relative path, it's relative to the entry point (the first PHP file, called by the webserver).
In dog, do
include(dirname(__FILE__) . '/cat.php'); // __FILE__ is always the name of the php file it's in

It depends on where the script you are executing lies. When you execute /index.php the path of the script set to /, so all includes start from there. This means that you can find /includes/dog.php, but it's not possible to find /cats.php. Mind that, even if you are including cats.php from your /includes/dog.php script, this doesn't change the original execuption path.
When, on the other hand, you are executing /includes/dog.php, your path is set to /includes/, which is why PHP can also find cats.php.
Read Bart's comment on how to solve this.

Another way to solve this is to set the include path of files, take a look at this.
http://ve2.php.net/manual/en/function.set-include-path.php

Thanks for this nice thread.
I used bart's answer to solve this issue. But I still have one question here.
I was surprised that it worked in my mate's system even without using dirname(__FILE__) so I did little research and compared both php.ini files. I noticed there is little difference at include_path parameter in php.ini.
In my php.ini it is set to Pear directory. So I commented out just to test and to my wonder it worked. This is when I realized we need to include some folder which I dont know or comment it out so that it takes default value.

Related

Bulletproof PHP include from project's root

Okay so I don't know if this is a "can't see the forest for the trees" situation but I'm slowly losing my patience on this.
All I want to do is find a way to include files from the project's root, no matter how nested the file, no matter where it's all hosted.
I obviously can't just do absolute paths like "/includes/file.php".
I can't use $_SERVER['DOCUMENT_ROOT'] because, as far as the servers where I'm hosting it are concerned, that's the wrong path.
I read about creating a config.php file in the root directory and defining the ROOT_DIR there, but that means I have to include that file RELATIVE in every script, which makes things unstable again. (I don't want every include to break because I moved the file somewhere else)
I can't use constants like DIR because it returns the current directory, not the absolute project root.
I tried to set the include path, which doesn't seem to work.
The only "solution" that works for me as of right now: In every file, I define a $root variable and set it to the path that I know is the correct project root.
That can't possibly be the best solution, can it?
There must be an easier way. And the fact that I can't find it drives me crazy.
The root path that works looks something like this:
"/mnt/web10145/dd3/519/5878104319/htdocs/project" (numbers changed)
Using this for includes works just fine. However, calling set_include_path($path) and then including without that path doesn't work.
Please, if anyone knows anything: Every answer is deeply appreciated.
Don't mind pointing out how stupid I am to not have thought about xyz. If it helps me solve the problem it's all good.
Thank you!

include_path behaviour not working as expected

I've just moved a load of sites to a new VPS and have a strange problem
with include_path. It's something that worked fine on the old server but
not on the new.
I'll try and explain it using a simple example...
In /home/kin/www/lib/Zend and also in /home/kin/www/ipb/_membadmin/Zend
there is a file called test1.php which simply echoes which folder it is in.
In /home/kin/www/ipb/_membadmin there is a file called test.php
It has one line....
require_once 'Zend/test1.php';
When you run it, as you would expect, it echoes the line from test1.php in
/home/kin/www/ipb/_membadmin/Zend
If you then rename /home/kin/www/ipb/_membadmin/Zend to something else (so
the 'include' statement can't find it), and run test.php again, it SHOULD
(I think) echo the file in /home/kin/www/lib/Zend because php include_path
is set to include /home/kin/public_html/lib (which phpinfo.php confirms).
... but it doesn't.
Why not? If there is an include path of /home/kin/public_html/lib then
surely
require_once 'Zend/test1.php';
should point to /home/kin/www/lib/Zend. It does on the old server!
I must be missing something obvious but I don't know what!
Any thoughts?
Thanks
After the diagnostic you just gave it now seems clear that something is overriding the environment path.
There has to be some line in your code where the set_include_path is getting called. Is any Zend specific code running that you haven't checked? That missing directory clearly paints the culprit as a rogue set_include_path()

PHP include path different on different servers

In my site, i have a place that says:
include('../tpls/header_home.php');
and it works. Now i am moving the site to another server, where i get the error:
Warning: include(../tpls/header_home.php) [function.include]: failed to open stream: No such file or directory in /home/usern/public_html/site/tpls/static/home.php on line 4
now if I replace the line with this one, it works:
include('site/tpls/header_home.php');
I could change it, but i don't know how many more places I have of broken paths all around, not only in templates, but files, uploads etc.
I would rather fix the problem generally from a setting or something else I am missing. What do I do?
HINT:
Old working server gives me CWD:
/home/ortho/public_html/site/lib
New server that is problematic gives me CWD:
/home/orthosho/public_html
why?
STRUCTURE:
/home/usern/public_html/site/tpls/static/home.php
/home/usern/public_html/site/tpls/header_home.php
PHP old server: 5.2.17
PHP new server: 5.3.8
maybe that is causing problems?
Well, you basically answered your own question.
Create a settings file where you keep all of these specific paths as variables or otherwise, and include that file wherever you need to reference the paths. That's generally how it works.
settings.inc.php:
$_CONFIG['BASE_DIR'] = "/var/www/yoursite.com/";
some_file.php:
require 'settings.inc.php';
include $_CONFIG['BASE_DIR'] . "some_dependency.php";
I assume you are trying to fix the issue having already made the entire system, without a common settings file, in which case I don't have an answer. You should really centralise things as soon as you start coding to avoid these kinds of issues.
You must have config file, which will have the abosolute path to your site, ofc it will be relative (no need to be hardcoded url) and then use it in all include calls.
Let me explain you, lets say you have a folder in your site called config and in in file called config.php. If you want you could make config class that will hold all your important variables. One of them should be
$ROOT_PATH = str_replace( '\\', '/', dirname( dirname( __FILE__ ) ) ) . '/';
That will be root path relative to your project. Then you can simply call this variable elsewhere when you include something:
require_once $ROOT_PATH . 'blabla/test.php';
Alternative to fix your broken code is to redefine include path with set_include_path()
http://php.net/manual/en/function.set-include-path.php
But for future, learn to code smart :)
Given your new information, the problem is the following:
Old server => ~/public_html/site/lib
New server => ~/public_html
Why? Well, it's because you've set it that way. How do you access the previous website? yourdomain.com/site/, or just yourdomain.com? If it's the first one, then it's bound to be that you've got different web roots.
Now, what you're trying to include is this:
Old server => ~/public_html/site/tpls/...
New server => ~/tpls/
That doesn't quite look right does it?
My guess is that you'd need to alter the document root in httpd.conf in some way.
Sometimes it helps to use dirname so its really relative to the current file. this is what I use if I make cronjobs, and its more "portable" this way
<?php
include dirname(__FILE__)."/../tpls/header_home.php";

PHP Polymorphic Root Requires

I have a directory/file tree as follows:
index.php
/frame/main_class.php
/frame/func/function_1.php
/frame/func/function_1.php
/cfg/config.php
//index.php
require('frame/main_class.php');
new main_class;
//frame/main_class.php
class main_class{
public function __construct(){
require('func/function_1.php');
require('func/function_2.php');
require('cfg/config.php');
}
}
The weird part is that it works. Maybe it is late and I am having a dumb-moment, but shouldn't "require('cfg/config');" be written "require('../cfg/config.php');" ?
And if it is using the root of index.php, then "require('func/function_1.php');" shouldn't work, right?
I have quadruple checked the remote server thinking that maybe there was a stray file or two... there isn't.
How can the two require statements have a different base path.....?
Does anyone know of a code snippet that could cause this to happen? I am working with some $_SERVER variables but I don't appear to be changing any of them....!?
"Files are included based on the file path given or, if none is given, the include_path specified. If the file isn't found in the include_path, include will finally check in the calling script's own directory and the current working directory before failing." Explicitly saying include dirname(__FILE__) . '/path/to/file.php';avoids this confusion. – DCoder
Link to PHP Manual on "dirname".
The PHP engine will look for the requested files in the current directory, but it will also look for them in the list of paths defined in INCLUDE_PATH. If the include path lists the path from where your script is running then the given code will work. If not then it wont.
For that reason amongst others it's not a good idea to rely on the include path to resolve the path of included files. You should give the full path instead.

Explanation for include/require functions behavior needed

I did a lot of reading but I cannot answer one question I have with php include behavior.
On php.net it says that it looks into the directories that are in include_path variable. After that it looks in the current directory. If I put relative path (starting with dot) or absolute path it ignores the include_path.
So far so good.
I get confused when I see examples on the internet that start with something like that:
include('LibName/SomeFile.php');
Would php take every path from include_path and append 'LibName/SomeFile.php to look for the file? What is the behavior?
It's exactly what you said it is. It checks each directory in include_path to see if 'LibName/SomeFile.php' references a file relative to those paths. If not, it tries the current directory.
PHP considers each entry in the include path separately when looking for files to include. It will check the first path, and if it doesn't find it, check the next path, until it either locates the included file or returns with a warning or an error. You may modify or set your include path at runtime using set_include_path().
You can find more info here: http://www.php.net/manual/en/ini.core.php#ini.include-path

Categories