Başlangıçta çalıştırılan komut dosyasının mutlak yolunu alın


247

Yüksek ve düşük aradım ve mutlak yolu elde etmek için bilgi içeren birçok farklı çözüm ve değişken elde ettim. Ancak, bazı koşullar altında çalışıyor gibi görünüyor, diğerleri altında değil. PHP çalıştırılan komut dosyasının mutlak yolunu almak için bir gümüş kurşun yolu var mı? Benim için komut dosyası komut satırından çalışacak, ancak bir çözüm Apache vb.

Açıklama: Başlangıçta yürütülen komut dosyası, çözümün kodlandığı dosya olmak zorunda değildir.


gerçekten de matematik. Uzun zaman önce tek bir senaryom olduğu ve benim için çalıştığı zaman kabul ettim. İlk problemi çözmediğini netleştirmek için kabul edilen cevabı kaldırdım. Yürütme bir komut dosyasında başladığında FILE sabitini depolamak bir yoludur, ancak idealden uzaktır.
inquam

İstediğiniz komut dosyasıdır, şu anki komut dosyası = bu çözüm koduyla
Bitterblue

Yanıtlar:


33

Doğru çözüm, get_included_filesfonksiyonu kullanmaktır :

list($scriptPath) = get_included_files();

Bu, aşağıdaki durumlarda bile ilk komut dosyasının mutlak yolunu verecektir:

  • Bu işlev dahil edilen bir dosyanın içine yerleştirilir
  • Geçerli çalışma dizini, başlangıç ​​komut dosyasının dizininden farklı
  • Komut dosyası, göreli bir yol olarak CLI ile yürütülür

İşte iki test komut dosyası; ana komut dosyası ve dahil edilen dosya:

# 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;
}

Ve sonuç; geçerli dizine dikkat edin:

C:\>php C:\Users\Redacted\Desktop\main.php
The script being executed is C:\Users\Redacted\Desktop\main.php

Bu çözüm işe yarıyor, ancak belgelerin okunmasıyla , başlangıçta çalıştırılan komut dosyasının yolunun, döndürülen dizinin ilk öğesi olduğundan bahsetmeye değer get_included_files(). Ben başlangıçta çalıştırılması gerekiyordu betiğin başında bir sabit içine depolamak öneririz__FILE__ .
Paolo

270

__FILE__ sabit size geçerli dosyaya mutlak yol verecektir.

Güncelleme :

Soru, çalışmakta olan komut dosyası yerine ilk çalıştırılan komut dosyasının nasıl alınacağını sormak için değiştirildi. Bunu yapmanın tek güvenilir yolu debug_backtraceişlevi kullanmaktır .

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

Bir ön denetleyici deseni kullanıyorsanız. Misiniz __FILE__index.php konumu veya yer dosyanın konumunu döndürür? İndex.php'nin yerini nasıl alabilirim?
CMCDragonkai

Eh __FILE__betiğin yoluna noktasını yapar. Ancak geçerli index.php'nin yolunu gösteren hiçbir şey bulamadım.
CMCDragonkai

1
@CMCDragonkai: ayrı bir soru sor
zerkms

2
DİKKAT: komut dosyası apache2 sanal dizinindeyse, döndürülen bilgiler fiziksel sunucudaki gerçek yol konumunu SAĞLAMAZ. Bu hata ayıklama amacıyla istedim ve $ _SERVER değişkenleri bile bunu sağlamaz. Örneğin, / var / www / vpath1 / html ve / var / www / html / ve / var / www / vpath2 / html'de index.php varsa ve bunların her biri sanal olarak / var / www / html ile eşlenmişse, / var / www / html, hangi sanal sunucu kullanılırsa kullanılsın, göreceğiniz şeydir.
Mark Richards

1
@ChristofferBubach, atmanıza bile gerek yok: bir istisna nesnesi, yığın izini inşaat sırasında toplar.
zerkms

262

1
komut dosyasının geçerli klasörünü almastr_replace( basename(__FILE__) , '',str_replace($_SERVER["DOCUMENT_ROOT"],'',str_replace('\\','/',__FILE__ ) ) ) === /folder1/folder2/
Salem

2
Bu, tüm internette gördüğüm dosya yolunun bir kısmını veya tamamını elde etmenin yollarına dair en kapsamlı örnek listesidir.
Sean the Bean

241
echo realpath(dirname(__FILE__));

Bunu dahil edilen bir dosyaya yerleştirirseniz, bu dahil etme yolunu yazdırır. Üst komut dosyasının yolunu almak için __FILE__ile değiştirin $_SERVER['PHP_SELF']. Ancak PHP_SELF'in bir güvenlik riski olduğunu unutmayın!


1
Tam olarak istediğim
buydu

13
Realpath'in burada ne faydası var?
Ortak

11
@Col. Shrapnel: "PHP 4.0.2'den beri, __FILE__sembol bağlantılarının çözümlendiği her zaman mutlak bir yol içerirken, eski sürümlerde bazı durumlarda göreceli yol içeriyordu." artı "dirname () girdi dizesinde saf olarak çalışır ve gerçek dosya sisteminin veya '..' gibi yol bileşenlerinin farkında değildir.
rik

6
oh, 4.0.2. Geçen yüzyıl?
Ortak Duygunuz

2
@rik: ayrıca, hangi güvenlik sorunu neden olabilir PHP_SELF??
zerkms

38
__DIR__

Gönderen kılavuzda :

Dosyanın dizini. Bir içerme içinde kullanılırsa, eklenen dosyanın dizini döndürülür. Bu eşdeğerdir dirname(__FILE__). Bu dizin adında, kök dizin olmadığı sürece bir eğik çizgi yoktur.
__FILE__ her zaman sembolik sorunların çözüldüğü mutlak bir yol içerirken, eski sürümlerde (4.0.2'den) bazı durumlarda göreceli yol vardır.

Not : __DIR__PHP 5.3.0'da eklenmiştir.



8
dirname(__FILE__) 

rotayı talep ettiğiniz geçerli dosyanın mutlak yolunu , sunucu dizininizin yolunu verecektir .

örnek dosyalar:

www / http / html / index.php; bu kodu index.php'nizin içine yerleştirirseniz şu kodu döndürür:

<?php echo dirname(__FILE__); // this will return: www/http/html/

www / http / html / class / myclass.php; bu kodu myclass.php'nizin içine yerleştirirseniz, geri dönecektir:

<?php echo dirname(__FILE__); // this will return: www/http/html/class/


7

Sadece aşağıda kullanın:

echo __DIR__;

1
Sry, fikir ilk kovulmuţ senaryoyu almak ... beimdi olduđun biri deđil. Bir içerme ağacı Yani a.php->b.php->c.phpbir yolu olmalıdır A.php kontrol eğer c.php . Güvenilir gibi görünen tek yol, debug_backtrace () işlevini kullanmaktır.
inquam

5
`realpath(dirname(__FILE__))` 

geçerli komut dosyası (içine bu kodu yerleştirdiğiniz komut dosyası) dizini izleyen eğik çizgi olmadan verir. sonuca başka dosyalar eklemek istiyorsanız bu önemlidir


Evet, ama fikir A.php tarafından dahil edilmişse, B.php içinde bile "ateşleme komut dosyası" A.php için mutlak yol elde edebilmek. İlk komut dosyasını daha sonra erişmek için saklayarak CAN veya ders yapılabilir, ancak soru bunu yapmadan almak mümkün olup olmadığıydı.
inquam

4

Sunucu köküne göre mutlak yol arıyorsanız, bunun iyi çalıştığını gördüm:

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

Bu çözümü farklı sunuculara karşı kontrol ederken, ana bilgisayarın işletim sisteminden (Windows ve Linux) bağımsız olarak her zaman linux benzeri dir ayırıcılar ile yol verdi. Benim için bu bir avantaj.
Bronek

3

İşte bunun için yazdım yararlı bir PHP işlevi. Orijinal soru açıklandığı gibi, şu anda içinde bulunduğumuz dosyayı değil, ilk komut dosyasının yürütüldüğü yolu döndürür .

/**
 * 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'])

Web sunucusu altında çalıştırılan komut dosyası $_SERVER['SCRIPT_FILENAME']için başlangıçta adlandırılan komut dosyasının tam yolunu içerecektir, bu nedenle muhtemelen index.php.realpath()bu durumda gerekli değildir.

Konsoldan çalıştırılan $_SERVER['SCRIPT_FILENAME']komut dosyası için, geçerli çalışma dizininizden başlangıçta çağırdığınız komut dosyasının göreli yolunu içerir. Böylece, çalışma dizini betiğinizin içinde değiştirmedikçe, mutlak yola çözümlenecektir.


1

Kullandığım şey bu ve Linux ortamlarında çalışıyor. Bunun bir Windows makinesinde çalışacağını sanmıyorum ...

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

Basit bir yolu mutlak yolunu sahip olmak başlangıçta çalıştırılan komut o komut, ve içerdiği diğer herhangi komut include, require, require_oncebir kullanmaktır sabit ve başlangıç orada geçerli komut yolunu depolamak ana senaryo :

define( 'SCRIPT_ROOT', __FILE__ );

Yukarıdaki çözüm, tek bir "ana" komut dosyası olduğunda uygundur. include , çoğu web uygulamasında olduğu gibi, diğer tüm gerekli komut uygundur.

Durum böyle değilse ve birkaç "intital komut dosyası" olabilirse, yeniden tanımlamaları önlemek ve sabitin içinde doğru yolu saklamak için her komut dosyası ile başlayabilir:

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

(Şu anda) kabul edilen cevap hakkında bir not :

cevap, ilk olarak çalıştırılan kod yolunun dizinin döndürdüğü ilk eleman olduğunu belirtir. get_included_files() .

Bu akıllı ve basit bir çözüm ve -yazma zamanında- (neredeyse PHP 7.4.0'dayız) işe yarıyor .

Bununla birlikte, belgelere bakıldığında, ilk çalıştırılan komut dosyasının döndürülen dizinin ilk öğesi olduğu belirtilmez get_included_files().

Sadece okuruz

Başlangıçta komut dosyası "dahil edilen dosya" olarak kabul edilir, bu nedenle include ve ailesi tarafından başvurulan dosyalarla birlikte listelenir.

" Orijinal olarak adlandırılan komut dosyası " yazılırken dizideki ilk komuttur ancak teknik olarak bunun gelecekte değişmeyeceğine dair bir garanti yoktur.


Bir not hakkında realpath(), __FILE__ve __DIR__:

Diğerleri cevaplarında kullanımını önermiştir __FILE__, __DIR__, dirname(__FILE__), realpath(__DIR__)...

dirname(__FILE__)eşittir __DIR__(PHP 5.3.0'da tanıtılmıştır), bu yüzden sadece kullanın __DIR__.

Her ikisi de __FILE__ve __DIR__her zaman mutlak yollardır, bu yüzden realpath()gereksizdir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.