I am writing an HTML/CSS/JS project on my localhost.
The project root is found at http://localhost/projects/project1/.
I want to know if it is possible to make the HTML files treat my project
root as its' base URL so that referencing the same javascript/css files
doesn't depend on the path of the HTML file(unless I reference relative to
current directory).
Here is my project structure:
projects
project1
index.html
pages (directory)
page1.html
page2.html
apps(directory)
app1(directory)
index.html
style.css
app.js
deps(directory)
jquery.js
As you can see, to refer to jquery.js inside my /projects/project1/index.html,
I have to write:
<script src="deps/jquery.js"></script>
To refer to jquery.js inside /projects/project1/pages/index1.html,
I have to write
<script src="../deps/jquery.js"></script>
To refer to jquery.js inside http://localhost/projects/project1/apps/app1/index.html,
I have to write
<script src="../../jquery.js"></script>
At which point I am not sure I wrote the correct number of ../s and can easily
cause errors.
Worse, If i reorder my directories around or rename them, it means I have to deal with
rewriting the paths again, which can be very daunting.
I have thought of various ways to address them none of which are appealing(although option 3 comes close).
Thoughts/Attempts:
I tried playing with .htaccess RewriteEngine/RewriteBase but nothing worked.
I could just create a new server for each project as NodeJS makes it really easy to do so.
This way, each server has the directory as its' static path and is '/'.
The problem with this approach is that this managing
many servers up at once on different ports which can be confusing.
I could set an absolute path variable in .htaccess via
SetEnv PROJECT_PATH /projects/project1/
However doing this means I have to open .htaccess each time I move the folder
or rename it and change the PROJECT_PATH. This may seem simple but if you
give the project to somebody else and they don't know how .htaccess works,
it is very painful to explain how to find this path, and how to change it,
and even more problematic if the .htaccess is longer than one line.
Ideally, I want this SetEnv to figure out the folder it is inside by itself,
but I don't know how to accomplish this. This also has a problem that the pathing becomes dependent on the PHP preprocessing which makes it painful to move to another server that does not have .htaccess or PHP such as NodeJS(which can still invoke php but even then it needs to deal with .htaccess).
I want to know if it is possible to either
Make .htaccess file create an environment variable containing deduced path
of this particular .htaccess file so that php files inside this directory can
do pathing relative to $_ENV{PROJECT_ROOT}. This way if the project is moved or shared, it will still work without needing to modify .htaccess.
Make .htaccess to force HTML files contained in the same or lower directories that all "/" references treat this directory as the root.
Or if there are other things to address this issue that I have not thought of.
Thanks ahead of time.
Dmitry, you can try this:
1) In your file httpd.conf, add the following line at the end:
Redirect permanent /deps http://localhost/projects/project1/deps/
2) Restart apache service
3) Refresh your index page(/projects/project1/pages/index1.html)
I have used something like this:
<html>
<head>
<script src="/deps/jquery.min.js"></script>
</head>
</html>
<?php
echo "welcome to index"
?>
How do I access a directory outside of my document root?
This explain how to give users access to a directory that is outside of your directory root on Windows.
Assuming that your directory is located at C:/www/newfolder/ then you would create the following in your httpd.conf file.
Alias /newfolder/ "C:/www/newfolder/"
<Directory "C:/www/newfolder">
Options Indexes MultiViews
AllowOverride AuthConfig
Order allow,deny
Allow from all
</Directory>
Now, when a user goes to www.domain.com/newfolder/ then they see the folder that is outside your document root and it appears in the browser to be a directory contained below the document root..
One thing to consider is that if you have virtualhosts, then an alias works for every virtualhost, so try to use uncommon names for your alias.
Hope this helps
Related
This might be hard to explain but I am looking for the best method of having one or a group of config files so if I need to update something its a little easier to do.
I have wrote a PHP application that has a sub folder for the admin side off the root folder and includes folder that is sub folder off the root folder as well .(see below)
the include folder has database config files, loads common variables and so forth. the problem is the path for the admin files that call for the database connection are obviously different than the files in the root folder.
so I started this but now I wonder if there is a better method than the route I am going.
`if($adminfile=="yes")
{
require('../includes/database/connect.db.php');
}
else{
require('includes/database/connect.db.php');
}`
I would really appreciate some advice, should I scrap this idea and have 2 location for the config file? Part of me hates to include in all the standard code $adminfile="no" I keep thinking is there a better way.
How do others solve this problem?
Check the value of your include_path in php.ini or your local config (via .htaccess for apache is another way to do it. If you add the path to demo to the include_path setting, then:
include('includes/database/connect.db.php');
or
require_once('includes/database/connect.db.php');
Will work from any file or sub folder.
Another way to do this is to include a single bootstrap file that has all the settings (i.e. not just your database ones) in your scripts.
A better way to do this is to route all your requests through a Front Controller that does anythign setup/teardown you need on every request. See PHP Front Controllers
you can define a constant in every file ... which defines the root folder you have
define('root', 'demo/');
and do
require(root.'includes/database/connect.db.php');
and this will work fine with any file you want to require
Most of my website is in my root directory. And In that directory there is "css", "functions", "images" folder. Everything works fine when I include php files within index.php or any other root file. It includes it fine and executes it fine.
But problem occurres when I made folder "blog". So this is totally new and separate root folder with CMS and its own "root" files. And I try to include css from main root directory or some php files from "functions" folder in main root directory, Everything breaks down. I know I have to include it as ../functions/myfile.com. But this files includes some other files so it just wont work properly and won't be able to include other files properly.
Is there any idea how to fix this problem?
You can get to the root from within each site using $_SERVER['DOCUMENT_ROOT']. For testing ONLY you can echo out the path to make sure it's working, if you do it the right way. You NEVER want to show the local server paths for things like includes and requires.
Site 1
echo $_SERVER['DOCUMENT_ROOT']; //should be '/main_web_folder/';
Includes under site one would be at:
echo $_SERVER['DOCUMENT_ROOT'].'/includes/'; // should be '/main_web_folder/includes/';
Site 2
echo $_SERVER['DOCUMENT_ROOT']; //should be '/main_web_folder/blog/';
The actual code to access includes from site1 inside of site2 you would say:
include($_SERVER['DOCUMENT_ROOT'].'/../includes/file_from_site_1.php');
It will only use the relative path of the file executing the query if you try to access it by excluding the document root and the root slash:
//(not as fool-proof or non-platform specific)
include('../includes/file_from_site_1.php');
Included paths have no place in code on the front end (live) of the site anywhere, and should be secured and used in production environments only.
Additionally for URLs on the site itself you can make them relative to the domain. Browsers will automatically fill in the rest because they know which page they are looking at. So instead of:
<a href='http://www.__domain__name__here__.com/contact/'>Contact</a>
You should use:
<a href='/contact/'>Contact</a>
For good SEO you'll want to make sure that the URLs for the blog do not exist in the other domain, otherwise it may be marked as a duplicate site. With that being said you might also want to add a line to your robots.txt file for ONLY site1:
User-agent: *
Disallow: /blog/
Other possibilities:
Look up your IP address and include this snippet of code:
function is_dev(){
//use the external IP from Google.
//If you're hosting locally it's 127.0.01 unless you've changed it.
$ip_address='xxx.xxx.xxx.xxx';
if ($_SERVER['REMOTE_ADDR']==$ip_address){
return true;
} else {
return false;
}
}
if(is_dev()){
echo $_SERVER['DOCUMENT_ROOT'];
}
Remember if your ISP changes your IP, as in you have a DCHP Dynamic IP, you'll need to change the IP in that file to see the results. I would put that file in an include, then require it on pages for debugging.
If you're okay with modern methods like using the browser console log you could do this instead and view it in the browser's debugging interface:
if(is_dev()){
echo "<script>".PHP_EOL;
echo "console.log('".$_SERVER['DOCUMENT_ROOT']."');".PHP_EOL;
echo "</script>".PHP_EOL;
}
If I understand you correctly, You have two folders, one houses your php script that you want to include into a file that is in another folder?
If this is the case, you just have to follow the trail the right way.
Let's assume your folders are set up like this:
root
includes
php_scripts
script.php
blog
content
index.php
If this is the proposed folder structure, and you are trying to include the "Script.php" file into your "index.php" folder, you need to include it this way:
include("../../../includes/php_scripts/script.php");
The way I do it is visual. I put my mouse pointer on the index.php (looking at the file structure), then every time I go UP a folder, I type another "../" Then you have to make sure you go UP the folder structure ABOVE the folders that you want to start going DOWN into. After that, it's just normal folder hierarchy.
i had the same issue and found a code on https://css-tricks.com/php-include-from-root/ that fixed it
<?php
$path = $_SERVER['DOCUMENT_ROOT'];
$path .= "/common/header.php";
include_once($path);
?>
None of the above answers fixed this issue for me.
I did it as following (Laravel with Ubuntu server):
<?php
$footerFile = '/var/www/website/main/resources/views/emails/elements/emailfooter.blade.php';
include($footerFile);
?>
Try to never use relative paths. Use a generic include where you assign the DocumentRoot server variable to a global variable, and construct absolute paths from there. Alternatively, for larger projects, consider implementing a PSR-0 SPL autoloader.
I created initialize.php to define my project's root directory.
defined('DS') ? null : define('DS', DIRECTORY_SEPARATOR);
defined('SITE_ROOT') ? null : define('SITE_ROOT', DS.'works'.DS.'myproject');
I include it with something like this from any directory.
require_once("../includes/initialize.php");
and I include other files easier. I am going to upload the files to server, then I should only change the initialize.php file.
It works. But, when I use user friendly URL's, and call ajax files from it, I don't know my directory hierarchy to include initialize.php.
I don't want to do this:
require_once("/works/myproject/includes/initialize.php");
for every file. Because it is going to change when I upload everytime.
I don't want to use session or cookie for everyuser.
There should be a trick for this but I couldn't find. Is there a way for getting project root from anywhere while using user friendly URL's and ajax calls?
I fixed it.
when I call it with ajax it's ok. But I included it as php too for some conditions.
Because of current and the ajax files are in different folders, it crashed.
So, when I change it to only require initialize.php when called with ajax, problem solved.
If you're using Apache, you could try adding your includes directory to your include_path directive.
Find the current value by doing a phpinfo() and look for include_path and then try re-declaring it in your top-level web directory and add the absolute path to your includes directory.
So if the default value is:
include_path = ".:/usr/bin/php:/some/other/directory"
just copy-paste the same thing in your .htaccess file but add your include directory on the end, separating it with a colon.
include_path = ".:/usr/bin/php:/some/other/directory:/works/myproject/includes"
and that way you shouldn't have to reference the absolute path every time.
This all depends on the permissions your web host gives you. There are other (easier) ways to do this, but I find that most of them are usually restricted by hosting providers, and manually setting it via .htaccess is usually the most dependable way to get this done.
Here's a page listing a few different ways: Five ways to create include path for PHP
Simply doing this:
require_once("../includes/initialize.php");
is enough because PHP doesn't look at your friendly URLs. It includes whatever you give him to include relative to your script.
Also there is $_SERVER['DOCUMENT_ROOT'] that will give you an absolute path from your root directory.
It is a good approach to define all your directories in a common file as you added initialize.php. You will have to include this common file in every file on the project. User friendly url's have no effect on the file inclusion.
I am developing a web application. contents are:
root dir (/var/www/)
config.php
index.php
details.php
admin dir (/var/www/admin)
admin.php
I have included config.php file into index.php, details.php in root directory using require_once('config.php') as this file contains database passwords, styles, images directory paths..
how can i include that config files in my admin/admin.php file so that one config file can be used in anywhere(even in subdirectories) of my web application. Will it make any difference for the value of define('APP_BASE_PATH', dirname(__FILE__)); when same config file is used by all files in the web application.
if i am wrong somewhere then please get me right.
If your server properly configured, just
include $_SERVER['DOCUMENT_ROOT']."/config.php";
anywhere
You have also 2 other possible ways.
a Front controller setup, where ALL user requests going into one file. And ths one going to include all others from their subdirectories. Personally I don't like it cause this front file become a mess. Though it's widely used.
I decided not to mention it because noone would use a hardcoded full path anyway.
Update after clarification in comments: You are looking for a way to include a central configuration file from anywhere in your project's folder structure.
#Col. Shrapnel shows one way, DOCUMENT_ROOT. It's the only way to use an "absolute" path from a nested folder structure. It has the limitation I describe above, but it's fine otherwise.
If you want maximum portability (i.e. the possibility to run the app with e.g. www.example.com/myapp/version_1 as its root directory), you would have to use relative references from within your folder structure to "climb down" to the config file, e.g. ../../config.php that will work reliably too, although be a bit cumbersome e.g. if you move a script to a different folder and you have to update the relative path.
you can use the same config file every time... using "/" will take you back to the root directory... so in admin/admin.php use this:
require_once("/config.php");
you can use "../" to take you up one directory eg:
require_once("../config.php");
was this what you were looking for?
I have 2 root directories for a site, httpdocs and httpsdocs. I am sure its obvious what the 2 are for. But I want to keep things consistent through-out the site like global navigation. Right now I have two separate files for this (one in each side) and I would like to only have one. This is hard to maintain because each time I change one I have to change the other (if I remember to), it breaks the DRY rule. But if I try to include a file from one side to the other using a relative path it tells me the file path is not allowed because it goes outside the document root. If I try to include it with an absolute URL I get another error saying file access is disabled in the server configuration. (I am on a hosting account so the most I can change as far as server config is limited to .htaccess). So can anyone think of a work-around for this?
Why not put your global include file in yet another directory (lets call it library) and then have each http root have an include file that includes ../library/lib.php, then sets specific paramaters. This gives you the added benifit of your library php files not being in the document root path as well.
And actually. Updating because I just read the entry about "relative path" issues.
Could you set the "include path" php value to include that directory?
Something like this:
ini_set('include_path', realpath(dirname(__FILE__)."/../library").":".ini_get('include_path'));
require_once('lib.php');
Did a little more research - seems that changing open_basedir is not possible unless you are able to edit the httpd.conf or php.ini values. PHP Manual: open_basedir
Do you have the ability to create symbolic links between the two directories?