Is file included?

Hi guys,

Is there a simpler way of checking whether the current script is an included file or has been called directly? What I’m doing at the moment is using get_included_files() at the top of the script and then doing a simple check and setting a constant, as follows:

$inc = get_included_files();
define('INCMODE', (in_array(__FILE__, $inc) && $inc['0'] != __FILE__) ? TRUE : FALSE);

Later on I will just do something like:

if (INCMODE === TRUE){
  // Do this
} else {
  // Do that
}

Any thoughts?

I may be off base here, why can’t you make a file that has all the various includes in a switch statement?

For example report2376.php may look like:


<?php
$pagetype = 'report';
...
?>

then your master include either has the files listed?

I am playing at the moment with:


<?php
  $title = ""; # <title> tag
  $page_title = ""; # breadcrumb text
  $addCSS = "..."; #If I need CSS for that page not in stylesheet
  # the above var build the stuff in header which holds
  # the Doctype to the main container

  include_once("header.php"); 
?>
  <!---Content Goes Here -->
<?php  
  include_once("footer.php");
?> 

TBH, for one; if an include was being run directly, I might like to just redirect to the homepage, but if included actually operate as designed. Otherwise there will just be a pile of errors relating to different classes and constants etc not being available to the file. I just like it that way

TBH, yeah, I should probably create an include file that index.php should include itself, but this single include basically does all of the loading and generation for a page, whether it be called directly without any arguments (in which case you get the home page), directly with arguments (which may give you alternative pages) or as an include to just provide the security etc. I just wanted to use a single file with maximum flexibility.

Not explaining it well, I’m sure

That’s a fair point Michael, thanks

Why? You can easily break that stuff up into there own components and call then when necessary. Or have them all at the same time. I don’t understand this “structure” as all. Not to mention this whole “detecting if I’m included…” is fragile, will it work 100% of the time? Or just ever other time?

PHP files do not have to be where apache can “see” them to work Antnee. Indeed, I’m of the opinion they shouldn’t be. This is part of my file structure for Gazelle Framework.


gazelle/
--classes/
--httpd/
--projects/
----default/
------htdocs/
--------__landing.php__
----main/
------htdocs/
--------__landing.php__

My framework adds a single line to Apache’s httpd.conf file to include the conf files found in it’s httpd directory. Those files do what other PHP frameworks use .htaccess for, establish the mod rewrite rules and set a few PHP settings for the application (turning off magic quotes and register_globals, turning short tags on). It then sets the web directory for each project to the htdocs folder of the project.

Each project only has one php file can be read, and that file does almost nothing. It defines 4 constants, requires the framework core class and starts it.

All the other files of the framework are above the webroot, so there is no URL you can give apache that would result in one of those files being executed out of context. This sidesteps the issue you seem to be trying to solve with your original question.

In practice the framework treats the htdocs directory as a cache and writes files into it. This enables a modular caching system that is out of the scope of this post. But the php code of that schema still requires the landing.php file to enter the rest of the framework.

No…I’m saying I don’t understand why you need to differentiate between being included and being accessed directly to run different code. That makes no sense to me. It sounds like a very confusing structure that I would hate to have to maintain…if I had to.

Could I ask why you’re mixing “include-only” code with code to be executed when not included? Seems like a problem with your code structure.

If you say so.

TBH, I avoid using eregi, on account of the fact that it’s deprecated as of PHP5.3.0, but is this more suitable?

$file = basename(__FILE__);
if(preg_match("/$file/", $_SERVER['SCRIPT_NAME'])){
    $included = 'no';
} else {
    $included = 'yes';
}

Using $_SERVER[‘REQUEST_URI’] caused an issue in that the file in question was index.php so it wouldn’t show in the REQUEST_URI if I just went to server/dir/ for example. Also, I’m weary if using basename() as I need to know which directory the file is in also, to ensure that there’s no confusion

Any thoughts on whether the above is a better solution?

Cheers

You mean something like:

$file = basename(__FILE__);
if(eregi($file,$_SERVER['REQUEST_URI']))
   {$included = 'yes';}
else 
   {$included = 'no';}

Why would I want to break things up? This system has many different classes etc, files that define constants, configuration settings, database functions, all in their own files. If I want to create a page called, I dunno, report.php, why the hell would I want to include every single file individually? Why would I not have a single include that provides me with the RBAC that I need, and all the rest of the functionality? The beauty of this method is that I can include that file very easily in to any other file and get the full use of the framework that is available, but I can also just call the page directly and get data from the database to generate a page. It’s a flexible system; I can create a page in a database which (without including another file) is one way to use the system, or I can just load a particular script and it would act the same way, without me needing to set it up in the database.

Not for everyone, but having been doing this for a while now this is the most flexible approach for my needs.

I’m sorry, we may be misunderstanding each other… are you telling me that you recommend that I do something like:

require_once 'config.php';
require_once 'constants.php';
require_once 'class.database.php';
$db = new database();
require_once 'class.rbac.php';

(as a quick example) on every single page, instead of just including one that does all of this for me?

Erm, just use

if (__FILE__ == $_SERVER['PHP_SELF']) {
// we hit the page directly
} else {
// we did not, or the user is being a jackass and trying to hit /path/to/self.php/some/XSS/attack/stuff
}

Just be aware that if someone goes to the page with the intent of XSS attacking the page they’ll divert to the branch of your code that treats the page as if it was included. Depending on what you do there it may or may not be a bad thing.

D’oh! Thanks :slight_smile: