getcwd() 返回 URL 中引用的“主”脚本的路径。
dirname(__FILE__) 将返回当前执行的脚本的路径。
我写了一个脚本,它需要来自同一个目录的几个类定义脚本。它根据文件名匹配检索它们,并使用 getcwd 来找出它们的位置。
当我需要从不同目录中的新文件调用第一个脚本时,它不起作用。
(PHP 4、PHP 5、PHP 7、PHP 8)
getcwd — 获取当前工作目录
此函数没有参数。
成功时返回当前工作目录,失败时返回 false
。
在某些 Unix 变体中,如果任何一个父目录没有设置可读或搜索模式,即使当前目录有,getcwd() 也会返回 false
。有关模式和权限的更多信息,请参见 chmod()。
示例 #1 getcwd() 示例
<?php
// 当前目录
echo getcwd() . "\n";
chdir('cvs');
// 当前目录
echo getcwd() . "\n";
?>
上面的示例将输出类似于以下内容
/home/didou /home/didou/cvs
如果 PHP 解释器是在启用 ZTS(Zend 线程安全)的情况下构建的,那么 getcwd() 返回的当前工作目录可能与操作系统接口返回的目录不同。依赖当前工作目录的外部库(通过 FFI 调用)将受到影响。
getcwd() 返回 URL 中引用的“主”脚本的路径。
dirname(__FILE__) 将返回当前执行的脚本的路径。
我写了一个脚本,它需要来自同一个目录的几个类定义脚本。它根据文件名匹配检索它们,并使用 getcwd 来找出它们的位置。
当我需要从不同目录中的新文件调用第一个脚本时,它不起作用。
我使用此代码在 PHP 中复制 pushd 和 popd DOS 命令
<?php
$g_DirStack = array();
function pushd( $dir )
{
global $g_DirStack;
array_push( $g_DirStack, getcwd() );
chdir( $dir );
}
function popd( )
{
global $g_DirStack;
$dir = array_pop( $g_DirStack );
assert( $dir !== null );
chdir( $dir );
}
?>
这允许您使用 pushd 更改当前目录,然后在完成后使用 popd “撤消”目录更改。
给定一个链接
/some/link->/some/location/path
使用 linux bash,
如果在链接的抽屉 /some/link 中
cd .. 上移到链接 /some/
cd -P .. 上移到目标 /some/location/
使用 php
fopen ("../file") 上移到目标 /some/location/file
有些人评论了获取下方路径的方法。
我发现使用 $_SERVER['DOCUMENT_ROOT'] 而不是
重新制作一个绝对路径。
在命令行上运行 PHP 时,如果您想包含另一个与主脚本位于同一目录的文件,只需执行
<?php
include './otherfile.php';
?>
可能不起作用,如果您像这样运行脚本
/$ /path/to/script.php
因为当前工作目录将设置为 '/',并且文件 '/otherfile.php' 不存在,因为它位于 '/path/to/otherfile.php' 中。
因此,要获取脚本所在的目录,您可以使用此函数
<?php
function get_file_dir() {
global $argv;
$dir = dirname(getcwd() . '/' . $argv[0]);
$curDir = getcwd();
chdir($dir);
$dir = getcwd();
chdir($curDir);
return $dir;
}
?>
所以你可以像这样使用它
<?php
include get_file_dir() . '/otherfile.php';
// 或者甚至..
chdir(get_file_dir());
include './otherfile.php';
?>
花了一些时间考虑这个,也许它对某人有帮助 :)
"在某些 Unix 变体中,如果任何一个父目录没有设置可读或搜索模式,即使当前目录有,getcwd() 也会返回 FALSE。"
请注意,MacOS X 是这些变体之一(至少对我来说 10.4 是)。您可以通过对从您的站点文件夹向上所有文件夹应用 'chmod a+rx' 来使其正常工作。
在使用 CLI 工具时,PHP5 中似乎出现了 PHP4 的功能变化。以下是一个示例:-
cd /tmp
cat > foo.php << END
<?php
print getcwd() . "\n";
?>
END
cd /
php -q /tmp/foo.php
PHP4 返回 /tmp
PHP5 返回 /
要注意的事情。
此函数通常与 basename() 一起使用,例如
https://php.net/manual/en/function.basename.php
如果您在需要包含(使用 include、require 或 *_once)在同一目录树之外的脚本中的文件中使用 getcwd(),请注意。
示例
<?php
// 在 /var/www/main_document_root/include/MySQL.inc.php 中
if (strpos(getcwd(),'main_')>0) {
// 设置主数据库连接的代码
}
?>
<?php
// 在 home/cron_user/maintenance_scripts/some_maintenance_script.php 中
require_once ('/var/www/main_document_root/include/MySQL.inc.php');
?>
在上面的示例中,数据库连接不会建立,因为对 getcwd() 的调用返回相对于调用脚本的路径(/home/cron_user/maintenance_scripts),而不是相对于调用 getcwd() 函数的文件。
一些服务器有安全选项来阻止 getcwd()
替代方案
str_replace($_SERVER['SCRIPT_NAME'],'', $_SERVER['SCRIPT_FILENAME']);
在包含符号链接的目录中调用 getcwd() 时要小心。
getcwd() 等同于 shell 命令“pwd -P”,它会解析符号链接。
shell 命令“pwd”等同于“pwd -L”,它使用环境中的 PWD 而不解析符号链接。这也等同于调用 getenv('PWD')。
这是一个将类似于以下路径的路径转换的函数
/home/www/somefolder/../someotherfolder/../
转换为正确的目录路径
<?php
function simplify_path($path) {
// 将当前工作目录保存到变量中
$oldcwd = getcwd();
// 将目录更改为要转换的目录
//$path 是要转换(清理)的目录,作为字符串传递给 // 函数
chdir($path);
return gstr_replace('\\', '/', getcwd());
// 将 cwd 改回旧值,以免干扰脚本
chdir($oldcwd);
}
此 函数 在您要比较两个不一定处于 "清理" 状态的文件路径时非常有用. 它在 *NIX 和 WINDOWS 中都能正常工作
?>
正如您可以在
https://php.net/manual/en/features.commandline.differences.php
中看到的那样,CLI SAPI - 与其他 SAPI 相反 - 不会自动将当前工作目录更改为启动脚本所在的目录。
一个非常简单的解决方法,可以恢复您在“普通”网页脚本中所习惯的行为,就是在脚本的开头包含类似于以下内容
<?php
chdir( dirname ( __FILE__ ) );
?>
但由于这是关于读取或“查找”路径的,如果您分享一些我在 CLI 脚本中经常使用的更复杂技巧,您可能会很感激...
<?php
// 注意:所有存储在后续变量中的路径最终都以 DIRECTORY_SEPARATOR 结尾
// 如何存储脚本被调用的工作目录:
$initial_cwd = preg_replace( '~(\w)$~' , '$1' . DIRECTORY_SEPARATOR , realpath( getcwd() ) );
// 如何无符号链接地切换到当前文件所在的文件夹:
chdir( dirname ( realpath ( __FILE__ ) ) );
// 如何将前一个文件夹存储在变量中:
$my_folder = dirname( realpath( __FILE__ ) ) . DIRECTORY_SEPARATOR;
// 如何获取一个向上一个文件夹的路径,如果 $my_folder 以 \class\ 或 /class/ 结尾:
$my_parent_folder = preg_replace( '~[/\\\\]class[/\\\\]$~' , DIRECTORY_SEPARATOR , $my_folder );
// 如何在任何情况下获取一个向上一个文件夹的路径:
$my_parent_folder = preg_replace( '~[/\\\\][^/\\\\]*[/\\\\]$~' , DIRECTORY_SEPARATOR , $my_folder );
// 如何从一个 unix 风格路径数组中创建一个 OS 风格路径数组
//(如果您使用配置文件等等,会很方便):
foreach( $unix_style_pathes as $unix_style_path )
$os_independent_path[] = str_replace( '/' , DIRECTORY_SEPARATOR , $unix_style_path );
?>
如果您将 php 链接到 /bin/linkedphp 并且您的 php 在例如 /home/actual.php 中
当您在文件系统中的某个位置运行 linkedphp 时
getcwd 返回 /bin 而不是工作目录
解决方案:使用 dirname(__FILENAME__) 而不是
回复我自己:该函数不适用于以下情况
/usr/bin$: /home/johndoe/Work/script.php
所以这里有一个更好更简单的方法(我认为这个方法适用于所有情况)
<?php
function get_file_dir() {
global $argv;
return realpath($argv[0]);
}
?>
尽情使用吧 :)
如果在 Solaris 上使用 NFS 挂载的子目录时 getcwd() 返回空值,那么您遇到了一个操作系统错误,据说该错误在最近版本的 Solaris 10 中已修复。此相同的操作系统错误也会影响 include() 和 require() 函数。
如果您的 PHP cli 二进制文件是作为 cgi 二进制文件构建的(使用 php_sapi_name 检查),则 cwd 的行为与您预期不同。
假设您有一个脚本 /usr/local/bin/purge
您在 /home/username 中
php CLI:getcwd() 给您 /home/username
php CGI:getcwd() 给您 /usr/local/bin
如果您使用 php 编写命令行脚本,这可能会让您感到困惑。您可以通过在 php 调用中添加 -C 来覆盖 CGI 行为
#!/usr/local/bin/php -Cq
然后 getcwd() 的行为与 CLI 编译版本中的行为相同。
如果您尝试在符号链接的目录中使用 getcwd(),getcwd() 会为您提供该链接的目标(类似地,当父级等为符号链接时)。可能会有更好的解决方案,但这对我有用(linux)
<? php
$cwd = exec('pwd');
?>
要获取帐户的用户名
<?php
$dir = getcwd();
$part = explode('/', $dir);
$username = $part[1];
?>
如果当前目录为 '/home/mike/public_html/',它将返回 mike。