처음 실행 된 스크립트의 절대 경로 가져 오기


247

나는 높고 낮은 것을 검색했으며 절대 경로를 얻기 위해 정보를 포함하는 다양한 솔루션과 변수를 얻었습니다. 그러나 그들은 어떤 조건에서는 작동하지만 다른 조건에서는 작동하지 않는 것 같습니다. PHP에서 실행 된 스크립트의 절대 경로를 얻는 방법은 하나입니까? 나에게 스크립트는 명령 줄에서 실행되지만 Apache 등에서 실행되는 경우에도 솔루션이 작동해야합니다.

설명 : 솔루션이 코딩 된 파일 일 필요는 없지만 처음 실행 된 스크립트입니다.


진실로 mathheadinclouds. 스크립트가 하나만 있었을 때 오래 전에 그것을 받아 들였고 그것은 나를 위해 일했습니다. 초기 문제를 해결하지 못한다는 것을 분명히하기 위해 허용 된 답변을 제거했습니다. 스크립트에서 실행이 시작될 때 FILE 상수를 저장하는 것은 한 가지 방법이지만 이상적인 것은 아닙니다.
innovm at

요청한 스크립트는 원하는 것입니다. 현재 스크립트 =이 솔루션 코드
Bitterblue

답변:


33

올바른 해결책은 다음 get_included_files기능 을 사용하는 것입니다.

list($scriptPath) = get_included_files();

다음과 같은 경우에도 초기 스크립트의 절대 경로를 제공합니다.

  • 이 기능은 포함 된 파일 안에 있습니다
  • 현재 작업 디렉토리가 초기 스크립트 디렉토리와 다릅니다
  • 스크립트는 상대 경로로 CLI를 사용하여 실행됩니다.

다음은 두 가지 테스트 스크립트입니다. 기본 스크립트와 포함 된 파일 :

# 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

이 솔루션은 효과가 있지만 설명서를 읽으면 처음 실행 된 스크립트 경로가에서 반환 된 배열 의 첫 번째 항목 이라는 언급은 없습니다 get_included_files(). 나는 제안 가게에 __FILE__처음 실행하는 의미 스크립트의 시작 부분에 상수로.
Paolo

270

__FILE__ 상수는 현재 파일의 절대 경로를 제공합니다.

업데이트 :

현재 실행중인 스크립트 대신 처음 실행 된 스크립트를 검색하는 방법을 묻도록 질문이 변경되었습니다. 이를 수행하는 유일한 (??) 신뢰할 수있는 방법은 debug_backtrace함수 를 사용하는 것입니다.

$stack = debug_backtrace();
$firstFrame = $stack[count($stack) - 1];
$initialFile = $firstFrame['file'];

전면 컨트롤러 패턴을 사용하는 경우 시겠습니까 __FILE__의 index.php의 위치 또는 포함 된 파일의 위치를 반환? index.php의 위치는 어떻게 알 수 있습니까?
CMCDragonkai

그럼 __FILE__현재 스크립트의 경로에 포인트를한다. 그러나 현재 index.php의 경로를 보여줄 것이 없습니다.
CMCDragonkai

1
@CMCDragonkai는 : 후 별도의 질문
zerkms

2
주의 : 스크립트가 apache2 가상 디렉터리에 있으면 반환 된 정보는 실제 서버의 실제 경로 위치를 제공하지 않습니다. 디버그 목적으로 이것을 원했고 $ _SERVER 변수조차 이것을 제공하지 않습니다. 예를 들어 index.php가 / var / www / vpath1 / html 및 / var / www / html / 및 / var / www / vpath2 / html에 존재하고 각각이 실제로 / var / www / html에 매핑 된 경우, 그러면 어떤 가상 서버를 사용하든 / var / www / html이 표시됩니다.
마크 리차드

1
@ChristofferBubach 당신은 그것을 던질 필요조차 없습니다 : 예외 객체는 생성 중에 스택 추적을 수집합니다.
zerkms

262

답변이 여기로 이동되었습니다-https: //stackoverflow.com/a/26944636/2377343


1
스크립트의 현재 폴더를 얻으려면str_replace( basename(__FILE__) , '',str_replace($_SERVER["DOCUMENT_ROOT"],'',str_replace('\\','/',__FILE__ ) ) ) === /folder1/folder2/
Salem

2
이것은 인터넷 전체에서 본 파일 경로의 일부 또는 전부를 얻는 방법에 대한 가장 포괄적 인 예제 목록입니다.
Sean the Bean

241
echo realpath(dirname(__FILE__));

이 파일을 포함 된 파일에 넣으면이 포함 경로를 인쇄합니다. 부모 스크립트의 경로를 얻으려면, 교체 __FILE__와 함께 $_SERVER['PHP_SELF']. 그러나 PHP_SELF는 보안 위험이 있습니다.


1
이것은 내가 원하는 것을 정확하게이었다
inquam

13
여기서 realpath를 어떻게 사용합니까?
당신의 상식

11
@안부. Shrapnel : "PHP 4.0.2부터는 __FILE__항상 심볼릭 링크가 해결 된 절대 경로가 포함되어 있지만 이전 버전에서는 일부 환경에서 상대 경로가 포함되었습니다." plus "dirname ()은 입력 문자열에서 순진하게 작동하며 실제 파일 시스템 또는 '..'와 같은 경로 구성 요소를 인식하지 못합니다.
rik

6
아 4.0.2. 지난 세기?
당신의 상식

2
@ 릭 : 또한 어떤 보안 문제가 발생할 수 있습니까 PHP_SELF??
zerkms

38
__DIR__

에서 수동 :

파일의 디렉토리 포함 내부에서 사용되면 포함 된 파일의 디렉토리가 리턴됩니다. 이는에 해당합니다 dirname(__FILE__). 이 디렉토리 이름은 루트 디렉토리가 아닌 한 슬래시가 없습니다.
__FILE__ 이전 버전 (4.0.2 이상)에서는 일부 환경에서 상대 경로가 포함 된 반면 항상 심볼릭 링크가 해결 된 절대 경로를 포함합니다.

참고 : __DIR__PHP 5.3.0에서 추가되었습니다.



8
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/


7

아래에서 사용하십시오 :

echo __DIR__;

1
Sry, 아이디어는 첫 번째 스크립트를 얻는 것입니다. c.php 에서 체크 하면 포함 트리가 a.phpa.php->b.php->c.php 의 경로 가 되어야합니다 . 신뢰할 수있는 유일한 방법은 debug_backtrace () 함수 를 사용하는 것입니다.
innovm

5
`realpath(dirname(__FILE__))` 

슬래시없이 현재 스크립트 (이 코드를 넣은 스크립트) 디렉토리를 제공합니다. 결과에 다른 파일을 포함하려는 경우 중요합니다


그러나 아이디어는 A.php에 포함되어 있다면 B.php 내부에서도 "발사 스크립트"A.php의 절대 경로를 얻을 수 있다는 것입니다. 나중에 액세스 할 수 있도록 초기 스크립트를 저장하여 수행 할 수는 있지만 문제는 그렇게하지 않고 얻을 수 있는지 여부입니다.
inquam

4

서버 루트에 상대적인 절대 경로를 찾고 있다면 이것이 잘 작동한다는 것을 알았습니다.

$_SERVER['DOCUMENT_ROOT'] . dirname($_SERVER['SCRIPT_NAME'])

다른 서버에 대해이 솔루션을 검사 할 때 항상 호스트 OS (Windows 및 Linux)에 관계없이 dir separator와 같은 Linux 경로를 제공했습니다. 나에게 그것은 이점이다.
Bronek

3

여기에 이것을 위해 작성한 유용한 PHP 함수가 있습니다. 원래 질문에서 알 수 있듯이 현재 스크립트가 아닌 파일이 아니라 초기 스크립트가 실행 된 경로를 반환합니다 .

/**
 * 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;
}


1
realpath($_SERVER['SCRIPT_FILENAME'])

웹 서버에서 실행되는 스크립트의 $_SERVER['SCRIPT_FILENAME']경우 초기에 호출 된 스크립트의 전체 경로를 포함하므로 아마도 index.php입니다. realpath()이 경우에는 필요하지 않습니다.

콘솔에서 실행되는 스크립트 $_SERVER['SCRIPT_FILENAME']에는 현재 작업 디렉토리에서 처음 호출 된 스크립트의 상대 경로가 포함됩니다. 따라서 스크립트 내에서 작업 디렉토리를 변경하지 않으면 절대 경로로 해석됩니다.


1

이것이 내가 사용하는 것이며 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']);
}

1

간단한 방법은 절대 경로를 갖도록 초기 실행 스크립트를 해당 스크립트, 포함 된 임의의 다른 스크립트 include, require, require_once이용하는 것이다 전율 과의 시작 부분이 현재 스크립트 경로를 저장하는 메인 스크립트 :

define( 'SCRIPT_ROOT', __FILE__ );

위의 솔루션 include은 대부분의 웹 응용 프로그램에서와 같이 필요한 모든 다른 스크립트를 포함하는 단일 "주"스크립트가있는 경우에 적합 합니다.

그렇지 않은 경우 여러 "intital scripts"가있을 경우 재정의를 피하고 상수 내에 올바른 경로를 저장하기 위해 각 스크립트는 다음과 같이 시작할 수 있습니다.

if( ! defined( 'SCRIPT_ROOT' ) ) {
    define( 'SCRIPT_ROOT`, __FILE__ );
}

(현재) 허용되는 답변 에 대한 참고 사항 :

대답은 처음에 실행 된 스크립트 경로가에서 반환 한 배열의 첫 번째 요소임을 나타냅니다 get_included_files().

이것은 영리하고 간단한 솔루션이며 작성 당시 (우리는 PHP 7.4.0에 있습니다) 작동 합니다.

그러나 설명서 를 보면 처음에 실행 된 스크립트가 에서 반환 된 배열 의 첫 번째 항목 이라는 언급은 없습니다 get_included_files().

우리는 읽기만

원래 호출 된 스크립트는 "포함 된 파일"로 간주되므로 include 및 family가 참조하는 파일과 함께 나열됩니다.

" 원래 " 라는 스크립트 를 작성할 당시에는 배열의 첫 번째 스크립트 이지만 기술적 으로는 앞으로 이것이 변경되지 않을 것이라는 보장은 없습니다.


메모에 대한 realpath(), __FILE__그리고 __DIR__:

기타 대답에서의 사용을 제안 __FILE__, __DIR__, dirname(__FILE__), realpath(__DIR__)...

dirname(__FILE__)동일하다 __DIR__(PHP 5.3.0 도입)이므로 바로 사용할 __DIR__.

모두 __FILE____DIR__항상 절대 경로 그래서 realpath()필요하지 않습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.