include() and require_once() Issue - php

I have this situation:
/
index.php
/init (folder)
init.php (of course inside this file i use require_once for db/function/and whatever you want to put inside)
/layout_parts (folder)
header.php (and others common parts are inside this folder)
/my_space (folder inside layout parts)
my_file.php
another_file.php
/your_space (folder inside layout parts)
your_file.php
another_file.php
/third_space (folder inside layout parts)
third_file.php
another_file.php
For the index i have no problem it all works fine, but if i include header.php in one of the subfolder files my require_once(init/init.php); that is on the top of header.php won't work.
(Warning message says no such file in the directory (OF COURSE THE FILE EXIST) and it write down the subfolder directory that is not the path i expected).
I tried echo $SERVER['DOCUMENT_ROOT]; to see the whole path, echo __DIR__; to see wich is the right path to the directory, no way out.
I know is such a dummy question but if some kind heart could help me it would be great. Thanks :)

The best way to handle this would be to use absolute paths instead of relative ones. When you use relative paths, you have to worry each time about how many levels deep you are and then have that many ../ etc. This is messy and difficult to manage, for eg, if you move a file to a different location, you have to update the includes again, based on where you are now. This is why absolute paths are helpful.
So create something like this:
$appRoot = "/path/to/root/folder/";
This is the path where the index.php file is located. It is the "application root", if you will.
Now, in ANY file where you want to include init.php add the following line:
include_once($appRoot."init/init.php");
Ideally the $appRoot should be created in a global config located in root. If you do not have a structure where a univeral config can be added, it can still be messy and you might need to add absolute paths into individual files (which is not a good idea)

Related

Linking CSS file with PHP throgh all folders

INTRO
I am new to php. I love that it allows me to change one header.php file and it updates all over the site.
IF all - index.php, header.php, style.css, article.php, homework.php files are in the ROOT folder, everything works like magic, I like it. I use:
<?php include_once "header.php"; ?>
at the top of index.php, article.php and homework.php and the header appears.
to load css a regular =
<link href="style.css" rel="stylesheet" type="text/css">
is enough to have in my header.php file, because all the files are in the same directory.
MY PROBLEM
When the amount of articles becomes too large and I decide I want to put those articles in different folders, that is when stuff gets confusing and I would like to know a proper way to solve it.
New website folder structure
C:\xampp\htdocs\articles\homework.php
C:\xampp\htdocs\views\header.php and style.css
C:\xampp\htdocs\index.php
C:\xampp\htdocs\articles.php
Now please help me how to make homework.php file to load the css from the header.php? I manage to load the header itself with
<?php include_once "..\views\header.php";?>
BUT the css file doesn't load for some reason.
I read something about "basenames", "site roots", but don't know how to properly set them up.
The perfect scenario
The perfect scenario would be if I could have a basename variable that I can change, so when I make my server live I can just change the basename to the appropriate new server directory and because all the header.php and other blog files were linked to that basename, everything would change automatically. I have done too many manual directory rewriting to do it once again, please tell me a way to automate it :)
Thank you a lot!
p.s!!!!!! Before I even post this question I realized that the header.php is trying to load views/style.css, which doesn't make sense, because the style.css file is in the same folder as header.php now.. Somehow basenames, site roots are a must here I believe...
You can specify relative paths such as ../css - means up one folder then look in css folder or ../../ - means up 2 levels then look in css folder.
../../main/css/style.css - would mean up 2 levels then look in main/css for the file style.css.
The problem with using / or ../ etc is that if you decide to change the location of the resource you still have to change all your paths. Using a var you can simply change it to reflect the new location.
with PHP you can also getcwd() and dirname() and realpath() to get a string representing a location, you can then set a base variable for your files and 'path' down from it.
This way you can use the same variable to locate a file rather than different relative paths depending on the level of the file calling it.
DIRECTORY_SEPARATOR is also useful for avoiding errors between / and \ with linux and windows OS. However I believe Windows and Linux will both resolve /
Personally I like to set path locations to commonly used files such as /includes in config.php then I can use that setting from anywhere
In summary you are just either discovering a path using PHP or setting a path as a variable
$path = 'c:/htdocs/mysite/includes/';
then using the variable as part of the path name when you access the file
$_SERVER['DOCUMENT_ROOT']
can also be useful to identify your site home folder

PHP and paths - relative to file and not including code

I am really confused about PHP and the path system.
I have this structure:
- Includes
- Login
- View
* Secure
These are all directories on my site. Now, if i place files in the "View" folder, i can access files in my Includes folder with:
"../Includes/file.php"
If i want to include the same file from the Secure directory, i would do:
"../../Includes/file.php"
This is all fine, but here is where it gets tricky for me.
If the file i try to import (the file.php in the Includes directory) ALSO includes a file, it will throw everything off. Say that file will include a file in "Login", it would have to be ONE of these 2 includes, all depending on if the code that includes it is in the Secure or View directory:
"../Login/file.php" -> if it was included from the View directory
"../../Login/file.php" -> if it was included from the Secure directory.
Obviously this problem only gets worse and worse. Maybe what i am after, is a way to have the path be relative to the FILE itself, and NOT the including code?
On another note, i guess what i am really after is how to handle all this include "hell" in PHP? I feel that i bind my structure tightly together and that i can't change much without everything breaking. So any advise on how to handle this is greatly appreciated.
There are two types of paths: relative, and absolute. Absolute paths start with a /.. (or C:/.. or however that works on Windows) and always unequivocally point at one specific file.
Relative paths (not starting with /) are relative to the include_path variable. That's a variable that contains a bunch of folders, where PHP will look for your relative path. That include_path also includes ., the current directory. The "current" directory depends on which file was the "first" to be executed. So it varies depending on which file starts to include others.
You can set your include_path to some specific, unchanging directory, so you always have a fixed path to include to relatively.
Better: construct absolute paths:
include __DIR__ . '/../Login/file.php';
This is always relative to the directory the file is in.

Trying to use one include file on multiple subdirectories

I have a header.php that I'd like to include on all pages of the script I'm making. It has the nav bar and header.php includes auth.php which is some basic authentication you'd expect a header page to have.
The problem I am having is relative paths vs absolute paths. My directory structure looks like the below
/root
-index.php (contains include ('inc/header.php');)
-auth.php
/inc
-header.php (contains include ('auth.php);)
Now this works perfectly well. However when I add some functionality and get the following directory structure things start to break
/root
-index.php (contains include ('inc/header.php');)
-auth.php
/inc
-header.php (contains include ('auth.php);)
/newFunctionality
-newStuff.php (contains include('../inc/header.php') but breaks because of relative paths fidning auth.php
I've played around with things like $fullPath = dirname(__FILE__); and I believe that this is most likely how I'm going to fix this problem.
I've seen very similar questions with answer like this. I'd like for this script to be independent of the index however. Is there a way to make this happen?
I've alway found it easiest to set a base path constant and include my top level scripts base on that
define ('APP_ROOT', '/path/to/application/root');
include(APP_ROOT."/libs/MyFile.php");
Normally I would put this (along with any other site constants) in an include file and include it relative to the either the document root
include($_SERVER["DOCUMENT_ROOT"]."/config/site.php");
or specify the location of the file in my .htaccess
SetEnv APP_CONFIG /path/to/application/config.php
then in php
include ($_SERVER["APP_CONFIG"]);

PHP 'include' issue - cannot seem to get include to work correctly

I'm having a spot of bother with php includes. I have the following file structure
htdocs
index.php
login.php
php_includes
db_conx.php
check_user_status.php
within the db_conx.php file i've creates a variable $number = 10; for testing.
The db_conx file is included in the check_user_status.php file with the following code:
include_once("db_conx.php");
and that is working fine - i.e. i can echo $number and get 10.
However, I'm including the check_user_status.php file at the top of login.php with this code:
include_once("php_includes/db_conx.php");
and on this page I'm unable to echo out $number on this page (check_user_status.php).
I'm going to need this script included in many pages (since it checks whether the user is logged in or not). Am I doing something strange with the paths?
For relative paths you need to do this.
include_once("../php_includes/db_conx.php");
To break this down.
Your Current working directory is initially going to be htdocs/ if your hit that file in your browser.
the .. back you up one directory level (so the directory that contains both htdocs and php_includes)
then you want to follow down php_includes to get to db_conx.php.
This will become a problem when you do a file in a subdirectory. Assuming you and a page2.php to a htdocs/subpages/
Now if we follow those same steps we are not going to arrive at the same location.
A better approach is to get the path relative to an absolute location. I like using the document root (htdocs in your case), so:
include($_SERVER["DOCUMENT_ROOT"]."/../php_includes/db_conx.php");
will refer to the same place on the file system regardless of where it is used.
I think you can use __DIR__ magic constant
The directory of the file. If used inside an include, the directory of the included file is returned. This is equivalent to dirname(FILE). This directory name does not have a trailing slash unless it is the root directory. (Added in PHP 5.3.0.)
This will help you with nested included files, infact the file path will be always set automatically and you don't have to deal with absolute paths.
If your file structure is correct, assuming that php_includes is NOT a directory within htdocs, you would need to do:
include_once("../php_includes/db_conx.php");

PHP: require doesn't work as it should

I have a directory root:
index.php
includes/
template.php
testfile.php
phpFiles/
processInput.php
testfile.php
index.php:
require_once("includes/template.php");
template.php:
require_once("includes/phpFiles/processInput.php")
processInput.php:
require_once("testfile.php")
require_once("../testfile.php")
This code will work when you run index.php, of course it will not work when you run template.php.
As you can see, index.php includes template.php like normal. But in template.php, you have to include like if you are in the directory that index.php is in. But then, in processInput.php, you include as if you are in the directory that processInput.php is in.
Why is this happening, and how can I fix it so that the include path is always the directory of the file that the require is done in? The second included file have the same include path as the requested file, but the next one does not.
Thanks for your help!
EDIT: The strange thing is that I've included classes in a class folder. And it included other files as it is supposed to, even though the paths are relative. WHY does this happen, and how can I fix it?
VERY IMPORTANT EDIT: I just realized that all this is because in my example, the inclusion in includes/phpFiles/processInput.php includes a file in the same directory: require_once("file in same dir.php"); This is the reason. If you are including a file with out specifying anything more than the filename, the include_path is actually the dir where the file the require is written in is in. Can anyone confirm this?
Use an absolute path.
require_once($_SERVER['DOCUMENT_ROOT']."/includes/phpFiles/processInput.php");
Use a similar form for all your required files and they will work no matter where you are.
You can do this in a few ways, amongst others:
Use set_include_path to control the directories from where to perform require() calls.
Define a common absolute base path in a constant that you define in index.php and use that in every require() statement (e.g. require(BASEPATH . '/includes/template.php')).
Use relative paths everywhere and leverage dirname(__FILE__) or __DIR__ to turn them into absolute paths. For instance: require(__DIR__ . '/phpFiles/processInput.php');
By default, the current working directory is used in the include path; you can verify this by inspecting the output of get_include_path(). However, this is not relative to where the include() is made from; it's relative to the main executing script.
You're using relative paths. You need to use absolute paths: $_SERVER['DOCUMENT_ROOT'].
When you include/require, you are basically temporarily moving all code from one file, to another.
so if file1.php (which is located in root) contains:
require("folder/file.php");
and you include file1.php in file2.php (which is in a different location (say folder directory for example):
file2.php:
require("../file1.php");
Now all of file1.php code is in file2.php. So file2.php will look like this:
require("../file1.php");
require("folder/file.php");//but because file2.php is already in the `folder` directory, this path does not exist...
index.php:
require_once("includes/template.php");
template.php:
require_once("includes/phpFiles/processInput.php")
Your directory structure is off. The file inclusion is being seen from the file you're using it from. So, "template.php" is looking for an "includes/" folder in its current folder (/includes/).
As others are saying, use absolute paths, which will make sure you're always going at it from the file system root, or use:
require_once("phpFiles/processInput.php")
In your template.php file (which is far more likely to break if you ever move things around, which is why others all recommend using absolute paths from the file system root).
BTW, if you're using "index.php" as some kind of framework system, you can consider defining a variable that stores the address of common files such as:
define('APPLICATION_PATH', realpath(dirname(__FILE__));
define('PHPFILES_PATH', APPLICAITON_PATH . '/includes/phpFiles/');

Categories