我进行了高低搜索,得到了很多不同的解决方案和包含信息的变量来获取绝对路径。 但它们似乎在某些条件下有效,而在其他条件下则无效。 有没有一种灵丹妙药的方法可以获取 PHP 中执行脚本的绝对路径? 对我来说,脚本将从命令行运行,但是,如果在 Apache 等中运行,解决方案应该也能正常工作。
澄清:最初执行的脚本,不一定是编码解决方案的文件。
__FILE__
常量将为您提供当前文件的绝对路径。
更新:
问题改为询问如何检索最初执行的脚本而不是当前运行的脚本。 唯一 (??) 可靠 的方法是使用
debug_backtrace
函数。
$stack = debug_backtrace();
$firstFrame = $stack[count($stack) - 1];
$initialFile = $firstFrame['file'];
echo realpath(dirname(__FILE__));
如果将其放入包含文件中,它将打印该包含文件的路径。要获取父脚本的路径,请将
__FILE__
替换为 $_SERVER['PHP_SELF']
。但请注意 PHP_SELF 存在安全风险!
get_included_files
函数:
list($scriptPath) = get_included_files();
这将为您提供初始脚本的绝对路径,即使:
这里有两个测试脚本;主脚本和包含的文件:
# C:\Users\Redacted\Desktop\main.php
include __DIR__ . DIRECTORY_SEPARATOR . 'include.php';
echoScriptPath();
# C:\Users\Redacted\Desktop\include.php
function echoScriptPath() {
list($scriptPath) = get_included_files();
echo 'The script being executed is ' . $scriptPath;
}
结果;注意当前目录:
C:\>php C:\Users\Redacted\Desktop\main.php
The script being executed is C:\Users\Redacted\Desktop\main.php
__DIR__
来自手册:
文件的目录。如果在包含内部使用,则返回包含文件的目录。这相当于。该目录名称没有尾部斜杠,除非它是根目录。dirname(__FILE__)
始终包含已解析符号链接的绝对路径,而在旧版本(4.0.2 以上)中,它在某些情况下包含相对路径。__FILE__
注意:
__DIR__
是在 PHP 5.3.0 中添加的。
如果您想获取当前工作目录,请使用
getcwd()
http://php.net/manual/en/function.getcwd.php
__FILE__
将返回带有文件名的路径,例如在 XAMPP 上 C:\xampp\htdocs\index.php
而不是 C:\xampp\htdocs\
dirname(__FILE__)
将给出您要求路由的当前文件的绝对路由,即您的服务器目录的路由。
示例文件:
www/http/html/index.php;如果你将此代码放入你的index.php中,它将返回:
<?php
echo dirname(__FILE__); // this will return: www/http/html/
www/http/html/class/myclass.php ;如果您将此代码放入 myclass.php 中,它将返回:
<?php
echo dirname(__FILE__); // this will return: www/http/html/class/
只需使用以下:
echo __DIR__;
`realpath(dirname(__FILE__))`
它为您提供当前脚本(您放置此代码的脚本)目录,不带尾部斜杠。 如果您想在结果中包含其他文件,这一点很重要
这是我为此专门编写的一个有用的 PHP 函数。正如最初的问题所阐明的,它返回执行 initial 脚本的路径 - 而不是我们当前所在的文件。
/**
* Get the file path/dir from which a script/function was initially executed
*
* @param bool $include_filename include/exclude filename in the return string
* @return string
*/
function get_function_origin_path($include_filename = true) {
$bt = debug_backtrace();
array_shift($bt);
if ( array_key_exists(0, $bt) && array_key_exists('file', $bt[0]) ) {
$file_path = $bt[0]['file'];
if ( $include_filename === false ) {
$file_path = str_replace(basename($file_path), '', $file_path);
}
} else {
$file_path = null;
}
return $file_path;
}
在该脚本和包含在include
、
require
、require_once
中的任何其他脚本中获得初始执行的脚本的绝对路径的一种简单方法是使用常量并在那里存储主脚本开头的当前脚本路径:
define( 'SCRIPT_ROOT', __FILE__ );
当有一个“主”脚本
include
是所有其他需要的脚本时,上面的解决方案是合适的,就像在如果情况并非如此,并且可能有多个“初始脚本”,那么为了避免重新定义并将正确的路径存储在常量中,每个脚本可能以以下形式开头:
if( ! defined( 'SCRIPT_ROOT' ) ) {
define( 'SCRIPT_ROOT`, __FILE__ );
}
关于
realpath()
、__FILE__
和 __DIR__
的注释:
其他人在他们的答案中建议使用
__FILE__
、__DIR__
、dirname(__FILE__)
、realpath(__DIR__)
...
dirname(__FILE__)
等于 __DIR__
(在 PHP 5.3.0 中引入),所以只需使用 __DIR__
。
__FILE__
和__DIR__
始终是绝对路径,因此realpath()
是不必要的。
如果您正在寻找相对于服务器根目录的绝对路径,我发现这很有效:
$_SERVER['DOCUMENT_ROOT'] . dirname($_SERVER['SCRIPT_NAME'])
realpath($_SERVER['SCRIPT_FILENAME'])
对于在 Web 服务器下运行的脚本
$_SERVER['SCRIPT_FILENAME']
将包含最初调用的脚本的完整路径,因此可能是您的 index.php。在这种情况下不需要 realpath()
。
对于从控制台运行的脚本
$_SERVER['SCRIPT_FILENAME']
将包含从当前工作目录到最初调用的脚本的相对路径。因此,除非您更改脚本内的工作目录,否则它将解析为绝对路径。
在你的脚本上尝试这个
echo getcwd() . "\n";
这是我使用的,它可以在 Linux 环境中运行。我认为这不适用于 Windows 机器...
//define canonicalized absolute pathname for the script
if(substr($_SERVER['SCRIPT_NAME'],0,1) == DIRECTORY_SEPARATOR) {
//does the script name start with the directory separator?
//if so, the path is defined from root; may have symbolic references so still use realpath()
$script = realpath($_SERVER['SCRIPT_NAME']);
} else {
//otherwise prefix script name with the current working directory
//and use realpath() to resolve symbolic references
$script = realpath(getcwd() . DIRECTORY_SEPARATOR . $_SERVER['SCRIPT_NAME']);
}