Forum Moderators: coopster

Message Too Old, No Replies

How to use a variable in an include statement

         

mr_nabo

2:59 pm on Dec 10, 2009 (gmt 0)

10+ Year Member



Sorry, figured it out, sorry for jumping the gun!

CyBerAliEn

10:17 pm on Dec 10, 2009 (gmt 0)

10+ Year Member



In case someone does a search for this and finds this post... it really isn't helpful. Post the solution and spread the knowledge. ;)

See below for solution...


<?php
//Assuming the 'file' resides in the same directory as the executing script...
$file = "profile.php";
include($file); //<<< this will NOT work
include("$file"); //<<<this WILL work
?>

The first include fails because PHP essentially tries to include, '$file' (not its value). When you put the input to the include as "$file" (with the quotes), PHP parses the value, and then feeds this to the include. Hence, it works! (PHP turns the "$file" to "profile.php" and this goes into include).

mr_nabo

8:09 am on Dec 11, 2009 (gmt 0)

10+ Year Member



Hi CyBerAliEn,

You're right, that's not very useful, sorry.

While I 'found' the answer for my initial question, I'm not sure I've really found the solution for my problem.

Here's the scenario: I want to change the location of my scripts on the server (i.e. from the subdirectory1 to a subdirectory2), so it makes sense to only need to change just one variable which specifies the path.

i.e. $root = '/subdirectory1'

I'd like to be able to use that variable in two types of PHP code:

<?php include($_SERVER['DOCUMENT_ROOT'] ."$root" . "/incs/head.inc.php"); ?>

and

<img src="<?php echo $root; ?>/images/picture.jpg" />

So that I can change one variable and all the paths are set properly.

The problem I have is this: to include $root at the top of all my pages so it's available in other scripts, after moving my site to subdirectory2, I'd have to change the path to that include on all pages anyway, i.e.

<?php include($_SERVER['DOCUMENT_ROOT'] ."/subdir1/incs/rootvariable.inc.php"); ?>

To:

<?php include($_SERVER['DOCUMENT_ROOT'] ."/subdir2/incs/rootvariable.inc.php"); ?>

Is there any way around that so that $root is included at the top of all pages?

Thanks,

mn

CyBerAliEn

2:07 pm on Dec 11, 2009 (gmt 0)

10+ Year Member



I think I can help you... but could you elaborate more on how your files are setup/structured?

IE: This page is located 'here' (relative path). It does 'this' (specific code). These other files are 'here'. They do 'this'. etc

I am not entirely sure I understand your file setup.

Generally speaking... you'll usually want a "master" file included on every page (such as your 'head' file?). But without having a better understanding of what you are really trying to do, I can't really give you a good solution.

mr_nabo

3:38 pm on Dec 11, 2009 (gmt 0)

10+ Year Member



Hi,

Thanks for getting back to me. Here's an example of a typical set up where '/' refers to the root of the site (i.e. the public_html folder):

-------------------------------------------------------------------------------------

I want to include this at the top of all my pages:

/incs/head.inc.php

This include has the code:

<?php $root = '/'; ?>

I can then use it in all pages below to specify the root of my site whether it be '/' or subdirectory1'. In the latter case, I could change the $root variable to this:

<?php $root = '/subdirectory1'; ?>

-------------------------------------------------------------------------------------
Typical site structure:

The following pages have this at the top of each of them:
<?php include($_SERVER['DOCUMENT_ROOT'] . "/incs/head.inc.php"); ?>

/index.php
/section1/index.php
/section2/index.php
/section2/page2.php
/section2/page3.php
/section2/page4.php
/section3/index.php
/section3/page1.php

But if I move my site to this:

/subdir1/index.php
/subdir1/section1/index.php
/subdir1/section2/index.php
/subdir1/section2/page2.php
/subdir1/section2/page3.php
/subdir1/section2/page4.php
/subdir1/section3/index.php
/subdir1/section3/page1.php

Then I need to change the include code I put in all the pages:

<?php include($_SERVER['DOCUMENT_ROOT'] . "/incs/head.inc.php"); ?>

needs to change to:

<?php include($_SERVER['DOCUMENT_ROOT'] . "/subdir1/incs/head.inc.php"); ?>

-------------------------------------------------------------------------------------

So, is the only answer to have a folder like '/incs' in my server root (public_html) that never moves and include the head.inc.php from there? i.e. even if I moved all my pages into subdir1, I would have to leave head.inc.php in /incs/ like this?

/incs/head.inc.php

and then I could leave the php code at the top of all my pages as this:

<?php include($_SERVER['DOCUMENT_ROOT'] . "/incs/head.inc.php"); ?>

I'd like to keep all my pages and includes together, but I have a feeling I can't move the include containing my $root variable along with everything else...

coopster

4:32 am on Dec 17, 2009 (gmt 0)

WebmasterWorld Administrator 10+ Year Member



control your included files [webmasterworld.com] at the bottom of this page may be helpful.

CyBerAliEn

4:07 pm on Dec 17, 2009 (gmt 0)

10+ Year Member



What I like to do is keep my "programming" separate from my content, as much as possible. This means stripping out code from a mostly-HTML file and doing an include to a separate PHP file of pure code.

I think I understand your circumstances now. You have a single 'head' file that contains general variables, settings, functions, etc... that you use on every single page. And you have a variety of pages that include this file. But, you want the freedom to move these other files around on-the-fly without hacking away at the code each time. Right?

I would create a common "PHP place" to put all your PHP files. Such as webRoot/incs/. Then, put your head.inc.php file in there. Since this file is used EVERYWHERE and never changes, put it in one central spot.

Then, in all of your content files, just add the single code:

<?php include("{$_SERVER['DOCUMENT_ROOT']}/incs/head.inc.php"); ?>

Then, if you move the content file(s) into subdirectories, it won't be affected. I would consider this ideal, especially if the "head" file is the same for every content page.

If the head file were mostly the same, but with a little extra code for every different content page, I would separate out all the common features and put them in "head" file, and then put the page-specific code in a separate file, such as "webRoot/incs/section2.php". Then, modify the PHP code at the top of every page to reflect this. For example, if the page was "section3", do:

<?php
include("{$_SERVER['DOCUMENT_ROOT']}/incs/head.inc.php");
include("{$_SERVER['DOCUMENT_ROOT']}/incs/section3.php");
?>

^ Now all your coding stays in a common place and you can reference it accurately no matter where you move the actual content file to.

But... if your head file is VASTLY different for every single content file (none of them are similar or alike), then I would place the "head" file inside the folder with the "content" file, such as:
webRoot/section2/index.php
webRoot/section2/head.inc.php

Then, inside the content file (section2/index.php), have the head included as:

<?php include('head.inc.php'); ?>

By excluding the path, you tell PHP to look for the file inside the same file location as the PHP file. This would be ideal if the "head" file contents were very specific. This is a horrible idea if the 'head' file is exactly the same for each content file (why? because if you change something in the head file, you have to change EACH head file... this could mean hundreds or thousands of files --- it would be much easier to change it once in one place).

I would strongly recommend my first approach. It keeps your common code centralized for easy of use and easy of updating/maintaining. And it frees your content of excessive coding... just a simple include the necessary PHP file.

Now, if you need a root variable for some reason... consider these points:

(1) If your hyperlinks are "/section2/" or "/section2/posts/" (examples). And you want a 'root' variable to do something like "{$root}" or "{$root}posts/". Don't do this. Just make the hyperlinks relative to the section... the browser will appropriately determine the full hyperlink. Similar for images and other HTML source referencing.

(2) If you need the 'root' for maybe other includes inside the content/section file, similar as #1. Instead of doing an absolute file path... do a relative file path. Since your file is already in the same location as the 'root' location, you can just straight up include other files without worry of paths:

include("myNewStuff.php");
. If your file structure is...
.../section2/index.php
.../section2/banner.jpg
.../section2/myNewStuff.php

The above include example would work inside "index.php" no matter where the files are located. They could be moved to ".../zoo-animals/usa/section2/" and the include would still work.

As long as you keep your common files in one spot. And all other important files are appropriately grouped (ie: all section2 specific files are inside section2), then you should get by, by using relative includes. Really, the 'root' variable is ~mostly unnecessary with a good [consistent] site/file structure.

(3) But, if you really needed a 'root' variable to tell you the current root (such as "/" or "/subdirectoryX"), you could use a bit of string manipulation to figure it out. Consider PHP's variable PHP_SELF (code:

$currentFileAndWebPath = $_SERVER['PHP_SELF'];
). If you are visiting something like "www.example.com/section2/index.php", it would return "/section2/index.php". Notice your path in there? No matter where your files get moved (and no matter how many sub-directories), your "current root" is partially stored here. You could use some string manipulation to strip out the "index.php" part and get just the "root" (/section2/ --- or such).

Hopefully this helps get you to where you want to be. :)

rocknbil

9:47 pm on Dec 17, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Chiming in here, as I see what's possibly a common mistake in PHP (or maybe not, in your case.) In web pages, you do this,

/images/image.jpg

as this will **always** start example.com/<--- HERE, the domain root. It's a good thing to do. However, when you have a leading slash in an include, PHP is looking for the full server path. If you've never done it, echo out $_SERVER['DOCUMENT_ROOT'] sometime and see it's value, it will surprise you. It will be a full server path,

/var/www/accountname/public_html/httpdocs

Which, as you know, if called from a web page will give a 404. These two are very often confused. So when you do this,

include('/incs/head.inc.php');

you are telling it to start from the server root, not your domain root, and it will usually fail. People do all sorts of workarounds to avoid understanding this, like setting base_dir . . . which usually only serves to complicate overall development as you have to keep checking "where you are." This is further confused when you do this:

include ('incs/head.inc.php');

Which likely works, because now it's relative to the script calling it. No full path needed. Meaning, wherever you are now, look for the "incs" directory inside the current directory.

Is there any way around that so that $root is included at the top of all pages?

Anyway, these path values are not variables, they are (or at least, can be) constants throughout your program. So here is what I like to do.

create example.com/conf/config.inc.

Inside config.inc, define your constants:

<?
define('SERVER_ROOT','/var/www/example.com/public_html');
// OR this - personally I like SEEING the path.
//define('SERVER_ROOT',$_SERVER['DOCUMENT_ROOT']);
define('INCLUDE_DIR',SERVER_ROOT . '/my-includes');
// This is for writing to files with ImageMagick, etc.
define('IMAGEPATH',SERVER_ROOT . '/images');
// This is for the actual output
define('IMAGEURL','/images')
define('DB','database_name');
define('DBHOST','localhost');
define('DBUSER','database_user_name');
define('DBPASSWORD','database_user_pass');
$link = mysql_pconnect(DBHOST,DBUSER,DBPASSWORD) or die ("Could not connect server");
mysql_select_db(DB,$link);
?>

Then in your scripts, you only need to hard code the config, for the rest, use the constants.

require_once('/var/www/example.com/public_html/conf/config.inc');
// OR this, see preference above.
// require_once($_SERVER['DOCUMENT_ROOT'] . "/conf/config.inc");

From that point on, you can use the constants.

include_once(INCLUDE_DIR . "my-include.php");

echo '<img src="'. IMAGEURL . '/' . $image . '" alt="' . $alt . '">

mr_nabo

12:35 am on Dec 19, 2009 (gmt 0)

10+ Year Member



Guys, thanks for all your help on this, really appreciate it and it's interesting to hear your ways of working - it's something I don't hear much of as I work as a freelance.

Happy Christmas