Get the name of the called file from include ()

I want to get the name of a file that includes another file from the embedded file.

I know that the magic constant __FILE__ , but this does not help, since it returns the name of the included file, not the one that includes it.

Is there any way to do this? Or is this not possible due to the interpretation of PHP?

+6
source share
4 answers

This is actually just a special case of what PHP templates do. Consider this function:

 function ScopedInclude($file, $params = array()) { extract($params); include $file; } 

Then A.php can include C.php as follows:

 <?php // A.php ScopedInclude('C.php', array('includerFile' => __FILE__)); 

In addition, B.php can include C.php in the same way without any problems.

 <?php // B.php ScopedInclude('C.php', array('includerFile' => __FILE__)); 

C.php can know its included by looking at the $ params array.

 <?php // C.php echo $includerFile; 
+4
source

So, this question is quite old, but I was looking for an answer and, leaving unsatisfied here, I came across $_SERVER['SCRIPT_FILENAME']; Of course, this works if the php file making the inclusion is a web page.

This gives you the full path to the "including file" on the server. e.g. /var/www/index.php. so if you want just a file name like index.php you will need to use basename () like

basename($_SERVER['SCRIPT_FILENAME']);

So, if in your index.php you have the following line:

<?php include("./somephp.php"); ?>

but in some way php.php do you have

echo "this is the file that included me: " . basename($_SERVER['SCRIPT_FILENAME']);

You'll get

this is the file that included me: index.php

output to the browser. This also works if the user accesses your file without explicitly specifying the file name in the URL, for example www.example.com instead of www.example.com/index.php .

+23
source

Decision

Knowing that the functions used to include files are include , include_once , require and require_once , also knowing that they are reserved words in PHP, which means that it will not be possible to declare user-defined functions using the same name and based on the idea of ​​wedgwood Using debug_backtrace , you can really decide which file the include was called from.

What we are going to do is iterate over the return line until we find the most recent call to any of the four include functions and the file where it was called. The following code demonstrates the technique:

 function GetIncludingFile() { $file = false; $backtrace = debug_backtrace(); $include_functions = array('include', 'include_once', 'require', 'require_once'); for ($index = 0; $index < count($backtrace); $index++) { $function = $backtrace[$index]['function']; if (in_array($function, $include_functions)) { $file = $backtrace[$index]['file']; break; } } return $file; } 

The above code will return the absolute path to the file in which the last inclusion occurred, if it was not included, it will return false. Please note that a file can be included from a file that was included from another file, the above function works only for the deepest inclusions.

With a simple modification, you can also get the last included file:

 function GetIncludedFile() { $file = false; $backtrace = debug_backtrace(); $include_functions = array('include', 'include_once', 'require', 'require_once'); for ($index = 0; $index < count($backtrace); $index++) { $function = $backtrace[$index]['function']; if (in_array($function, $include_functions)) { $file = $backtrace[$index - 1]['file']; break; } } return $file; } 

Observations

Note that __FILE__ not an included file, but the current file. For instance:

A.php file:

 <?php function callme() { echo __FILE__; } ?> 

B.php file:

 <?php include('A.php'); callme(); ?> 

file index.php:

 <?php include('B.php'); ?> 

In the example above, in the context of the B.php file, the B.php file is included (and the included file is index.php), but the output of the callme function is the callme path because __FILE__ is in A.php.


Also note that $_SERVER['SCRIPT_FILENAME'] will provide the absolute path to the script requested by the client. If $_SERVER['SCRIPT_FILENAME'] == __FILE__ means that the current file is requested, and therefore there probably were no inclusions ...

The above method checks if the current file is requested, but not if it was not included (below is an example of how to include the requested file). The actual solution for checking if there were any inclusions could be checking count(get_included_files()) == 1 .


The requested file may be an included file as follows:

file x.php

 <?php $var = 'something'; include('index.php'); ?> 

file index.php

 <?php if (!isset($var)) { include('x.php'); exit; } echo 'something'; ?> 

In the above example, the index.php file will include x.php, then x.php will include index.php back, subsequently index.php displays "something" and returns control x.php, x.php returns control to index.php and it reaches the exit;

This shows that even if index.php was the requested script, it was also included from another script.

+5
source

I cannot find an easy way to cover this. But if including one is really important to you, you can hack it with some global variable and your own include function.

eg.

 <?php $g_including_files = array(); function my_include($file) { $bt = debug_backtrace(); global $g_including_files; $g_including_files[basename($file)] = $bt[0]['file']; return include($file); } 

Maybe you will be useful :)

+4
source

Source: https://habr.com/ru/post/913825/


All Articles