Get filename of file which ran PHP include - php

When using the PHP include, how can I find out which file is calling the include? In short, what is the parent's file filename?

An easy way is to assign a variable in the parent file (before the inclue), then reference that variable in the included file.
Parent File:
$myvar_not_replicated = __FILE__; // Make sure nothing else is going to overwrite
include 'other_file.php';
Included File:
if (isset($myvar_not_replicated)) echo "{$myvar_not_replicated} included me";
else echo "Unknown file included me";
You could also mess around with get_included_files() or debug_backtrace() and find the event when and where the file got included, but that can get a little messy and complicated.

$fileList = get_included_files();
$topMost = $fileList[0];
if ($topMost == __FILE__) echo 'no parents';
else echo "parent is $topMost";
I think this should give the right result when there's a single parent.
By that I mean the situation where the parent is not a required or an included file itself.

Late answer, but ...
I check the running parent filename by using:
$_SERVER["SCRIPT_NAME"] // or
$_SERVER["REQUEST_URI"] // (with query string)

You could use debug_backtrace() directly with no additional changes from within the included file:
$including_filename = pathinfo(debug_backtrace()[0]['file'])['basename'];
This will give you the name of the file that's including you.
To see everything you have access to from within the included file, run this from within it:
print_r(debug_backtrace());
You will get something like:
Array
(
[0] => Array
(
[file] => /var/folder/folder/folder/file.php
[line] => 554
[function] => include
)
)

Got this from here: https://stackoverflow.com/a/35622743/9270227
echo "Parent full URL: ";
echo $_SERVER["SCRIPT_FILENAME"] . '<br>';

I was searching same information on web for complement my online course about php and found two ways. The first was
$file = baseline($_SERVER['PHP_SELF']);
echo $file; //that outputs file name
BUT, in include or require cases it gets the final file that it's included or required.
Also found this, the second
$file = __FILE__;
echo $file; //that outputs the absolute way from file
BUT i just was looking for the file name.
So... I mix it up and it worths well!
$file = basename(__FILE__);
echo $file; //that outputs the file name itself (no include/require problems)

In the parent file, add this line before including the child file:
$_SESSION['parent_file'] = $_SERVER['PHP_SELF'];
And then in the child file, read the session variable:
$parent_file = $_SESSION['parent_file']

Related

Is there any way to know if the file was included or loaded directly?

GetCategories.php
<?php
require_once "Connection.php";
$query = mysqli_query($connection, "SELECT * FROM CATEGORIES");
$array = array();
while ($row = mysqli_fetch_assoc($query))
$array[] = $row;
//Execute this code only if was loaded directly
echo json_encode($array, JSON_NUMERIC_CHECK);
Is there any way to know if the GetCategories.php file was included or loaded directly?
I found a lot of similar questions but can't find any helpful answers.
There are many ways, bound to be a duplicate. One way if you're not using any URL rewriting, is to check the name of the file against the file that is called. Here's one way to do that:
if(basename(__FILE__) == basename($_SERVER['PHP_SELF'])) {
//direct
} else {
//included
}
__FILE__ returns the actual file path on disk of the file, such as /var/www/mysite/GetCategories.php
$_SERVER['PHP_SELF'] returns the current file loaded from the webserver, such as /includes/GetCategories.php or /index.php
If they are the same, then it was loaded directly. If they are not the same then the file from 2 above included the file from 1.
I found another solution.
$is_included = get_included_files()[0] != __FILE__;
get_included_files() returns a list of all files that were included. The very first file is always at top (index 0). If it differs from the current file (__FILE__), it is included.
The advantage over my other answer is that the line can be anywhere in the source code.
Again: I'm not sure what happens if different kinds of redirects are used.
If you place the following code at the top of each relevant file, the $is_included tells you the state:
$is_included = defined('INCLUDE_GUARD');
if (!$is_included)
define('INCLUDE_GUARD',1);

I am unable to open file with \Template::instance()->render. I am getting the following error

It is giving me the following error,
[text] => Unable to open /home/mehul/www/portal.hsua.com.au/public_html/assets/templates.html
This is the part of code which is causing the problem.
$this->f3->set('const', $constants);
ob_start();
echo \Template::instance()->render('/home/mehul/www/portal.hsua.com.au/public_html/assets/templates.html');
$renderedView = ob_get_clean();
/*foreach ($variables as $varname => $variable) {
$this->f3->clear($varname);
}*/
return $renderedView;
The file might not exist
you're opening the PHP file in your webbrowser PHP file is somewhere located in /var/www delivered by Nginx / Apache. If that's the case, your webserver probably has no access to open a file within your home directory.
I recommend you put the template files next to your PHP file to make sure your webserver has access to it.
The render() methods concatenates the given template $file with all template paths stored in the UI system variable while searching for a valid file. Therefore you either have to specify a relative path or append / as workaround.
Workaround
$f3 = Base::instance();
$f3->concat('UI', ';/');
Source/Reference
The concatination $dir.$file in base.php#L2791 is the culprit. Your error is generated a few lines below.
Update / Example
$f3 = Base::instance();
$f3->concat('UI', ';/'); // Add support for absolute paths.
echo \Template::instance()
->render(__DIR__ . '/template.html');

get a unknown file name in different dir, php

Here is my directory structure,
C:\xampp\htdocs\..
C:\download\20150923abc.xls //abc is a random value
how can I attach the file 20150923abc.xls in php?
Also, how to change the filename after I got it?
Thanks.
Use the glob ability to find references all files of type .xls and then you can use the file name references as you wish. This sidesteps the issue of you not knowing the specific file name.
$files = glob("c:/download/*.xls");
This will produce an array of all .xls files with their full filepath. If you wish to rename or attach these files then you can do this using the glob reference:
rename($files[0], "c:/download/somenewname.xls");
etc. Read more at:
PHP Glob Function
EDIT:
From Comment below:
foreach (glob( $old_folder."*.xls") as $filename)
{
$names = explode('/', $filename);
$just_file_name = end($names);
echo $just_file_name . "----\n";
$new_folder = dirname(FILE)."\\prm\\att\\";
//rename_win($old_folder, $new_folder);
rename($filename, $new_folder.$just_file_name); <== this line changed.
}
unset($filename);
To fix the above code in your comment, you need to change the incorrect variables referenced (there was no array $files[0]) to the ones used in the foreach loop.

file_exists and paths that include relative paths ("/../")

When I use file_get_contents on a path like /a/path/to/a/../file.php, it gets the content just fine. If I call file_exists first (or is_file or realpath), the return values indicate that the file does not exist. What seems to be the issue?
Edit: Here is some additional information condensed from comments to answers:
I am running Mac OS X 10.9 with php 5.5.6, so safe mode should not be an issue (it was removed in version 5.4)
I tried clearing the file cash by calling clearstatcache(true, $dir1)
The file in question is 362 bytes in size, but I reproduced this issue with several different files in a medley of locations.
open_basedir is commented out in the php.ini
The file is local (the first file I tried was in the same directory as the script)
The issue exists in the command line (phpUnit) and in the browser.
The permissions on the file in questions are -rwxrwxrwx (I sudo-chmod-777ed the file)
This is a code snippet that creates the behavior:
$dir1 = '/a/path/to/a/../file.php';
$dir2 = '/a/path/to/file.php';
echo "File content dir1:\n";
echo file_get_contents($dir1);
echo "\ndir1 exists: ".(int)file_exists($dir1);
echo "\n\nFile content dir2:\n";
echo file_get_contents($dir2);
echo "\ndir2 exists: ".(int)file_exists($dir2);
the output is:
File content dir1:
The actual content of the file. I promise!
dir1 exists: 0
File content dir2:
The actual content of the file. I promise!
dir2 exists: 1
It sounds like you have safe mode turned on and are attempting to access a file that PHP would consider unsafe when running in safe mode. From the manual:
Warning
This function returns FALSE for files inaccessible due to safe mode restrictions. However these files still can be included if they are located in safe_mode_include_dir.
EDIT: You can also reproduce this behavior if /a/path/to/a/ is not a real path. For example:
<?php
$dir1 = '/realDir/realDir2/filetoinclude.php';
echo "File content dir1:\n";
echo file_get_contents($dir1); // outputs file contents
echo "\ndir1 exists: ".(int)file_exists($dir1); // outputs 1
$dir2 = '/realDir/realDir2/realDir3/../filetoinclude.php';
echo "\n\nFile content dir2:\n";
echo file_get_contents($dir2); // outputs file contents
echo "\ndir2 exists: ".(int)file_exists($dir2); // outputs 1
$dir3 = '/realDir/realDir2/NotARealDirectory/../filetoinclude.php';
echo "\n\nFile content dir3:\n";
echo file_get_contents($dir3); // outputs file contents
echo "\ndir3 exists: ".(int)file_exists($dir3); // outputs 0
This is because file_exists needs to traverse the entire path, literally, so it looks for the missing directory and fails. I'm not sure exactly what file_get_contents does that is different, and I can't find much on Google, but it clearly does some parsing of the path that is different from what file_exists does.
I am providing the workaround that I developed with a regex, if others have this same issue. I hate to be using this hack, and I still don't understand why I am having this issue, but hopefully someone will come up with an actual solution.
Before calling file_exists I now call this function:
function resolve($path) {
$regex = "/(.?)(\/[^\/]*\/\.\.)(.*)/";
$result = preg_replace($regex, "$1$3", $path);
if ($result != $path) {
$result = resolve($result);
}
return $result;
}

creating and changing parts of the created php file

I wonder what ist he best way to do the following.
I am creating a webseite CMS. Through CMS I am creating new folders with index.php files in them. For example I have created folder with the site new_folder_name/index.php
I wonder what ist the best way to make an interaction between the created index.php files and database. For example I am creating the php file with another php file
<?php
$dir = "../new_folder_name";
$file_to_write = "index.php";
$content_to_write = '
<?php
//// php code
$foo=‘3‘:
?>
if( is_dir($dir) === false )
{
mkdir($dir);
}
$file = fopen($dir . '/' . $file_to_write,"w");
fwrite($file, $content_to_write);
fclose($file);
include $dir . '/' . $file_to_write;
?>
I am putting a variable $foo that needs to be changed with every new php file created. I could create $foo=GET(´SOEMTHING´) but this GET is making problems since this variable needs to be changed, and only for this file a unique value. I do not know if I explained it properly but I hope I did. In which way can I create a php file with specific $foo value or change the created file with php in order to get the $foo value which I want.
you can do
$content_to_write = '
<?php
//// php code
$foo=\'$_GET[\'something\']\';
?>';
this is make your new script to read $_GET['something']
OR
this example, read this script's $_GET['something'] and put it's value in script...
$content_to_write = '
<?php
//// php code
$foo=\''.$_GET['something'].'\';
?>';
since you use single quote $_GET didn't get parse with original script. If you want to use that simply concatenate it. Alternatively you can concatinate '$' in between string to make variable just variables.

Categories