Include-ception

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
User avatar
lenton
Forum Commoner
Posts: 49
Joined: Sun Jun 20, 2010 6:45 am

Include-ception

Post by lenton »

I have includes within includes:

first.php

Code: Select all

<?php
echo 'WORKED';
?>
Output: WORKED

dir1/second.php

Code: Select all

<?php
include '../first.php';
?>
Output: WORKED

dir1/dir2/third.php

Code: Select all

<?php
include '../second.php';
?>
Output: Warning: include(../first.php): failed to open stream: No such file or directory in /var/www/test/dir1/second.php on line 2 Warning: include(): Failed opening '../first.php' for inclusion (include_path='.:/usr/share/php:/usr/share/pear') in /var/www/test/dir1/second.php on line 2

dir1/dir2/dir3/forth.php

Code: Select all

<?php
include '../third.php';
?>
Output: Warning: include(../second.php): failed to open stream: No such file or directory in /var/www/test/dir1/dir2/third.php on line 2 Warning: include(): Failed opening '../second.php' for inclusion (include_path='.:/usr/share/php:/usr/share/pear') in /var/www/test/dir1/dir2/third.php on line 2

Why the hell isn't this working?!?
Last edited by lenton on Tue Jan 10, 2012 7:27 pm, edited 2 times in total.
User avatar
social_experiment
DevNet Master
Posts: 2793
Joined: Sun Feb 15, 2009 11:08 am
Location: .za

Re: Include-ception

Post by social_experiment »

What happens if you change the include inside banana.php to '../test.php' ?
“Don’t worry if it doesn’t work right. If everything did, you’d be out of a job.” - Mosher’s Law of Software Engineering
User avatar
lenton
Forum Commoner
Posts: 49
Joined: Sun Jun 20, 2010 6:45 am

Re: Include-ception

Post by lenton »

Sorry the previous example wasn't correct, please re-look at my first post.

I just don't understand why it's erroring. :banghead:
User avatar
social_experiment
DevNet Master
Posts: 2793
Joined: Sun Feb 15, 2009 11:08 am
Location: .za

Re: Include-ception

Post by social_experiment »

Code: Select all

<?php
 #change to
include '/../first.php';
 #change to
include '/../second.php';
?>
I'm guessing that once you include the file it's relative path has to change; i found this on another forum
You can use an include inside an include but keep in mind one thing... The second include is relative to the first, not the top level page.
http://tycoontalk.freelancer.com/php-fo ... to-do.html

Hth
“Don’t worry if it doesn’t work right. If everything did, you’d be out of a job.” - Mosher’s Law of Software Engineering
User avatar
twinedev
Forum Regular
Posts: 984
Joined: Tue Sep 28, 2010 11:41 am
Location: Columbus, Ohio

Re: Include-ception

Post by twinedev »

The problem is that PHP is going off of the directory that the script was called from. It reads in and processes that file as if all of it's code is in the file where the include is located. So in your "dir1/dir2/third.php" example, it is looking in dir1/dir2 for first.

To see this demonstrated even more, add the following line to each of your three files:

Code: Select all

echo "<p>RUNNING FROM: ",getcwd(),"</p>";
It is good practice to set up some constants to use in your app to always make calls from the root of the website. While there are different methods, the one I usually use is the following:

Every "called" file starts with this:

Code: Select all

<?php
    define('SCRIPT_START', microtime(TRUE);
    require_once($_SERVER['DOCUMENT_ROOT].'/inc/init.inc.php');

    // Rest of code.....
(note, I use "SCRIPT_START' as I have code in my framework that lets me turn on debug mode to track script execution times)

/inc/init.inc.php contains something along the lines of:

Code: Select all

<?php

if (!defined('SCRIPT_START')) { die ('[ERR:'.__LINE__.'] Invalid direct call to file'); }

session_start();

define('DEBUG_MODE', TRUE); // turns on error checking, advanced debugging messages and alerts

if(DEBUG_MODE) { 
    error_reporting(-1);
    // Other settings I do for error handling
}
else {
    error_reporting(0);
    // Other settings I do for error handling
}

// I put this on in case it ends up on a server not set up. sad, but happens
date_default_timezone_set('America/New_York'); 

// These are set so if a cron job runs, there are values in these when they are called 
// (cli = Command Line Interface, just my own label I give)
if (!$_SERVER['HTTP_HOST'] || $_SERVER['HTTP_HOST'] =='') { $_SERVER['HTTP_HOST'] = 'localrun.cli'; }
if (!$_SERVER['REMOTE_ADDR'] || $_SERVER['REMOTE_ADDR'] =='') { $_SERVER['REMOTE_ADDR'] = 'CLI'; }

define ('SYSTEM_NAME',     'Gregs Awesome Script'); 
define ('SYSTEM_EMAIL',    'info@gregsawesomescript.com'); 

define ('STORE_KEY', 'RANDOM_KEY_FOR_THIS_INSTALL_ONLY'); // Used as Key for DB encrypt
define ('SITE_SALT', 'RANDOM_KEY_FOR_THIS_INSTALL_ONLY'); // Used as Salt for PW's

define ('REL_MEDIA_URL',      '/media/');
define ('REL_ADMIN_URL',      '/admin/');

// SSL one set here, so for development can keep it without https:// then change when going live
define ('REG_SITE_URL', 'http://'.$_SERVER['HTTP_HOST']);
define ('SSL_SITE_URL', 'https://'.$_SERVER['HTTP_HOST']);

define ('LOCAL_PATH',            $_SERVER['DOCUMENT_ROOT'].'/');
define ('LOCAL_MEDIA_PATH',      $_SERVER['DOCUMENT_ROOT'].REL_MEDIA_URL);
define ('LOCAL_INC_PATH',        LOCAL_PATH.'inc/');
define ('LOCAL_ADMIN_PATH',      $ _SERVER['DOCUMENT_ROOT'].REL_SITE_ADMIN_URL);

require_once(LOCAL_INC_PATH.'functions.inc.php');

// END-OF-FILE: ~/inc/init.inc.php
This way, now I can do require_once(LOCAL_INC_PATH.'my_file.inc.php'); and it doesn't matter what directory I am in, it will call correctly.
I do the same for image/media:

Code: Select all

<img src="<?php echo REL_MEDIA_URL; ?>my_image.png" alt="my awesome image" />
Other notes: if the file that you need to include is something that the page will not work properly without, you should do require or require_once instead of include or include_once. Include will just give a warning that the file isn't there, require will stop execution.

Also, if it is code that is only needed once, do the require_once over require. Good habit as you get into larger sites to prevent duplicate definition of things.

-Greg
Post Reply