PHP Conference Japan 2024

getcwd

(PHP 4, PHP 5, PHP 7, PHP 8)

getcwd取得目前的工作目錄

說明

getcwd(): string|false

取得目前的工作目錄。

參數

此函式沒有參數。

傳回值

成功時傳回目前的工作目錄,失敗時傳回 false

在某些 Unix 變體中,如果任何父目錄沒有設定可讀或可搜尋模式,即使目前目錄有,getcwd() 也會傳回 false。有關模式和權限的更多資訊,請參閱 chmod()

範例

範例 1 getcwd() 範例

<?php

// 目前的目錄
echo getcwd() . "\n";

chdir('cvs');

// 目前的目錄
echo getcwd() . "\n";

?>

上面的範例將會輸出類似於以下內容

/home/didou
/home/didou/cvs

注意

注意

如果 PHP 直譯器是使用啟用 ZTS (Zend Thread Safety) 編譯的,則 getcwd() 傳回的目前工作目錄可能與作業系統介面傳回的不同。依賴於目前工作目錄的外部函式庫(透過 FFI 呼叫)將會受到影響。

參見

新增筆記

使用者提供的筆記 18 筆筆記

45
dave at corecomm dot us
20 年前
getcwd() 會傳回 URL 中引用的「主要」腳本的路徑。

dirname(__FILE__) 會傳回目前正在執行的腳本的路徑。

我寫了一個腳本,需要從同一個目錄中的多個類別定義腳本。它會根據檔案名稱比對來擷取它們,並使用 getcwd 來判斷它們的位置。

當我需要從不同目錄中的新檔案呼叫第一個腳本時,就沒那麼順利了。
10
hodgman at ali dot com dot au
18 年前
我使用這段程式碼在 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 來「還原」目錄變更。
11
znupi69NOSPAMHERE at gmail dot com
16 年前
當在命令列上執行 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';
?>
花了一些時間思考這個問題,也許可以幫助到某人:)
2
CXJ
7 年前
getcwd() 看起來會對路徑呼叫 PHP 的 realpath() 等效函式。它永遠不會傳回符號連結,而總是傳回目前工作目錄路徑中的實際目錄名稱。
5
marcus at synchromedia dot co dot uk
19 年前
「在某些 Unix 變體中,如果任何父目錄沒有設定可讀或可搜尋模式,即使目前目錄有,getcwd() 也會傳回 FALSE。」

只是讓您知道,MacOS X 是其中一種變體(至少 10.4 對我來說是如此)。您可以對您的站點資料夾向上套用 'chmod a+rx' 來使其正常運作。
3
Anonymous
2 年前
假設有連結
/some/link->/some/location/path

使用 Linux bash,
如果在連結的抽屜 /some/link 中
cd .. 會前往上層連結 /some/
cd -P .. 會前往上層目的地 /some/location/

使用 php
fopen ("../file") 會向上層目錄尋找 /some/location/file

有些人評論了以下取得路徑的方法。

我發現使用 $_SERVER['DOCUMENT_ROOT'] 比較幸運
來重新建立絕對路徑。
10
ash at ashmckenzie dot org
16 年前
當使用 CLI 工具時,PHP5 的功能似乎與 PHP4 有所不同。以下是一個範例:-

cd /tmp

cat > foo.php << END
<?php
print getcwd() . "\n";
?>
END

cd /

php -q /tmp/foo.php

PHP4 回傳 /tmp
PHP5 回傳 /

這點需要注意。
6
mark dot phpnetspam at mhudson dot net
18 年前
此函數經常與 basename() 一起使用,例如:
https://php.dev.org.tw/manual/en/function.basename.php
6
troy dot cregger at gmail dot com
17 年前
如果要在位於相同目錄樹之外的腳本中包含(使用 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() 函數的檔案的路徑。
6
memandeemail at gmail dot com
18 年前
有些伺服器具有封鎖 getcwd() 的安全性選項

替代選項

str_replace($_SERVER['SCRIPT_NAME'],'', $_SERVER['SCRIPT_FILENAME']);
4
Craig
8 年前
當在包含符號連結的目錄中呼叫 getcwd() 時,請注意。

getcwd() 等同於 shell 命令 "pwd -P",它會解析符號連結。

shell 命令 "pwd" 等同於 "pwd -L",它會使用環境變數 PWD 而不解析符號連結。這也等同於呼叫 getenv('PWD')。
6
leonbrussels at gmail dot com
16 年前
這是一個將路徑轉換為像這樣的函數

/home/www/somefolder/../someotherfolder/../

轉換為正確的目錄路徑

<?php

function simplify_path($path) {

//將我們目前的工作目錄儲存到變數中
$oldcwd = getcwd();
//將目錄變更為要轉換的目錄
//$path是要轉換(清理)的目錄,作為字串傳遞給函數

chdir($path);
return
gstr_replace('\\', '/', getcwd());

//將 cwd 變更回舊值,以免干擾腳本
chdir($oldcwd);

}

如果您想比較兩個不一定處於"清理過"狀態的檔案路徑,這個函數非常有用。它在 *NIX WINDOWS 中都適用

?>
7
Anonymous
14 年前
正如您在
https://php.dev.org.tw/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 風格的路徑中建立一組作業系統風格路徑的陣列
// (如果您使用設定檔等,這會很方便):
foreach( $unix_style_pathes as $unix_style_path )
$os_independent_path[] = str_replace( '/' , DIRECTORY_SEPARATOR , $unix_style_path );

?>
7
bvidinli at gmail dot com
15 年前
如果您將 php 連結到 /bin/linkedphp,而您的 php 位於例如 /home/actual.php

當您在檔案系統的某處執行 linkedphp 時,
getcwd 回傳 /bin 而不是工作目錄,

解決方法:改用 dirname(__FILENAME__)
4
znupi69NOSPAMHERE at gmail dot com
16 年前
針對我自己的回應:該函數不適用於以下情況
/usr/bin$: /home/johndoe/Work/script.php
所以這裡有一個更好且更簡單的方法(我認為這個方法適用於所有情況)
<?php
function get_file_dir() {
global
$argv;
return
realpath($argv[0]);
}
?>
放手去做吧:)
3
manux at manux dot org
20 年前
小心
工作目錄,因此
getcwd ()
在註冊的關機函數中為 "/" !!!
2
ab5602 at wayne dot edu
17 年前
如果在 Solaris 中使用 NFS 掛載的子目錄時,getcwd() 沒有回傳任何內容,您可能遇到了 Solaris 10 最近版本中據說已修正的作業系統錯誤。這個相同的作業系統錯誤也會影響 include() 和 require() 函數。
1
vermicin at antispam dot gmail dot com
19 年前
如果您的 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 編寫命令列腳本,這可能會讓您感到困惑。您可以將 -C 加入到 php 呼叫中來覆蓋 CGI 行為

#!/usr/local/bin/php -Cq

然後 getcwd() 的行為就如同 CLI 編譯的版本。
To Top