PHP dosyaya veya çağıran koda göre yollar içeriyor mu?


111

PHP göreli ekleme yollarıyla ilgili kural setini anlamakta güçlük çekiyorum. A.PHP- dosyasını çalıştırırsam ve A.PHP dosyası, C.PHP dosyasını içeren B.PHP dosyasını içerirse, C.PHP'ye giden göreceli yol B.PHP'nin konumu veya A'nın konumu ile ilişkili olmalıdır. .PHP? Yani, içerme dosyasının hangi dosyadan çağrıldığı veya yalnızca geçerli çalışma dizininin ne olduğu ve geçerli çalışma dizinini ne belirlediği önemli mi?


Bence kabul edilen cevaptan daha doğru: stackoverflow.com/a/23902890/1636522 .
yaprak

Yanıtlar:


132

Ana betiğe bağlıdır, bu durumda A.php. include()Şu anda çalışan betiğe sadece kod eklediğini unutmayın .

Yani, içeriğin hangi dosyadan çağrıldığı önemli mi?

Hayır.

İsterseniz yapmak olsun onu ve bir B.php göreli dahil yapın kullanmak __FILE__sabit (veya __DIR__PHP 5.2 IIRC beri) literal geçerli dosyaya her zaman noktası kod satırı bulunur olacağı.

include(dirname(__FILE__)."/C.PHP");

@ Pekka- harika- tam da aradığım şey. Daha fazla bilgi için stackoverflow.com/questions/2184810/…
Yarin

7
Ayrıca __DIR__tam olarak bu amaç için kullanabilirsiniz .
Nick Bedford

1
Bu cevap biraz aşırıdır : GEREK YOK include(dirname(__FILE__)."/C.PHP");, çünkü include("C.PHP");yeterli (Evet! C.PHP, B.PHP ile aynı dizinde olabilir) Sadece projenizde iki C.PHP dosyası olduğunda başarısız olabilir.
Johnny Wong

Daha açık hale getirmek için: include yolunda "./" veya "../" öneki yoksa hem B.php hem de A.php ile ilişkilidir. Aşağıdaki cevabıma bakın.
Johnny Wong

21

@Pekka beni oraya götürdü, ama sadece öğrendiklerimi paylaşmak istiyorum:

getcwd() yürütmeye başladığınız dosyanın bulunduğu dizini döndürür.

dirname(__FILE__) o anda yürütülen kodu içeren dosyanın dizinini döndürür.

Bu iki işlevi kullanarak, ihtiyaç duyduğunuz şeye göre her zaman bir dahil etme yolu oluşturabilirsiniz.

örneğin, b.php ve c.php bir dizini paylaşıyorsa, b.php, c.php'yi şu şekilde içerebilir:

include(dirname(__FILE__).'/c.php');

b.php'nin nereden çağrıldığı önemli değil.

Aslında, fazladan kod PHP'yi hedef dosyayı bulma girişiminde include_path ile yineleme yapmak zorunda kalmadığından göreceli yollar oluşturmanın tercih edilen yolu budur.

Kaynaklar:

Getcwd () ve dirname (__ FILE__) arasındaki fark nedir? Hangisini kullanmalıyım?

Neden dirname kullanmalısınız (__ FILE__)


Bir şey eklemek istiyorum, csb.php adında bir dosyam vardı, bir klasörden bir işlev dosyası ekledim ve işlevler dosyası, işlevler dosyasıyla aynı klasörden t.php adlı bir dosya içeriyordu. t.php klasöründen csb.php adlı dosya, işlevler dosyasını çağıran aynı csb.php'yi içermeye başladı, ancak ikinci csb.php'yi csbe.php olarak değiştirdiğimde hemen çalışmaya başladı. Öyleyse, ilk klasörü, ardından ikinci dahil etme klasörünü önceliklendiriyor gibi görünüyor!
Miguel Vieira

18
  1. Dahil etme yolu ./veya ile başlamıyorsa ../, örneğin:

    include 'C.php'; // precedence: include_path (which include '.' at first),
                     // then path of current `.php` file (i.e. `B.php`), then `.`.
  2. Dahil etme yolu ./veya ile başlıyorsa ../, örneğin:

    include './C.php';  // relative to '.'
    
    include '../C.php'; // also relative to '.'

.Ya da .., yukarıda göre olan getcwd()giriş yolu için varsayılan olarak, .phpdosya (örneğin A.php).

PHP 5.4.3'te test edilmiştir (Derleme Tarihi: 8 Mayıs 2012 00:47:34).

(Ayrıca chdir()çıktısını değiştirebileceğini unutmayın getcwd().)


Sonuç olarak, A.php'nin yolu önce C.php için aranır, ardından include'de './' veya '../' öneki yoksa B.php'nin yolu aranır. (Varsayılan PHP ayarını varsayın)
Johnny Wong

chdir(__DIR__)Sorunu çözmek için kullanmam için bana ipucu verdiğiniz için teşekkürler .
HartleySan

[...] getcwd(), varsayılan .php dosyasının yolu [...] - mutlaka doğru değildir. PHP'yi komut satırında çalıştırırsam getcwd(), hangi .phpdosyayı çağırdığımdan bağımsız olarak, kabuğun geçerli çalışma dizinine başvurur. Yine de, PHP bir web sunucusu ortamında çalıştırılırsa, ortamın giriş .phpdosyasına mevcut çalışma dizinini başlattığını hayal edebiliyorum . Homebrew aracılığıyla PHP 7.2.2 yüklenmiş olarak macOS üzerinde test edilmiştir.
herzbube

17

Pekka'nın kabul ettiği cevap eksik ve genel bağlamda yanıltıcıdır. Dosya göreceli bir yol olarak sağlanmışsa, çağrılan dil yapısı includeonu aşağıdaki şekilde arayacaktır.

İlk olarak, include_pathile ayarlanabilen ortam değişkeninin yollarından geçecektir ini_set. Bu başarısız olursa, çağıran betiğin kendi dizininde dirname(__FILE__)( __DIR__php> = 5.3 ile) arayacaktır. Bu da başarısız olursa, ancak o zaman çalışma dizininde arayacaktır! Sadece, varsayılan olarak, ortam değişkeninin şu anki çalışma dizini olan include_pathile başladığı ortaya çıktı .. Mevcut çalışma dizininde ilk olarak arama yapmasının tek nedeni budur. Bkz. Http://php.net/manual/en/function.include.php .

Dosyalar, verilen dosya yoluna göre dahil edilir veya hiçbiri belirtilmezse, belirtilen include_path. Dosya include_path içinde bulunamazsa, include sonunda başarısız olmadan önce çağıran komut dosyasının kendi dizinini ve geçerli çalışma dizinini kontrol eder.

Dolayısıyla, sorunun ilk kısmının doğru cevabı, dahil edilen arama komut dosyasının nerede olduğunun önemli olmasıdır. Sorunun son kısmının cevabı , bir web sunucusu bağlamında ilk çalışma dizininin, PHP tarafından işlenirken diğerlerinin tümünü içeren, çağrılan betiğin dizini olmasıdır. Bir komut satırı bağlamında, ilk çalışma dizini, çağrılan betiğin bulunduğu dizin olmak zorunda değil, php komut isteminde çağrıldığında olduğu gibi olur. Geçerli çalışma dizini Ancak PHP fonksiyonu ile işletilen anda değiştirilebilir chdir. Bkz. Http://php.net/manual/en/function.chdir.php .

Bu paragraf, diğer cevaplara yorum yapmak için eklenir. Bazıları, güvenmenin include_pathdaha az sağlam olduğunu ve bu nedenle ./pathveya gibi tam yolların kullanılmasının tercih edildiğini belirtmişlerdir __DIR__ . /path. Bazıları, çalışma dizininin .kendisine güvenmenin güvenli olmadığını, çünkü değiştirilebilir olduğunu söyleyecek kadar ileri gitti . Bununla birlikte, bazen çevre değerlerine güvenmeniz gerekir. Örneğin, include_pathboş ayarlamayı isteyebilirsiniz , böylece çağıran betiğin dizini, mevcut çalışma dizininden önce bile arayacağı ilk yer olur. Kod zaten harici kaynaklardan düzenli olarak yazılmış ve güncellenmiş olabilir __DIR__ve kod her güncellendiğinde öneki yeniden eklemek istemezsiniz .


"Eğer bu başarısız olursa, dirname(__FILE__) (__DIR__)php> = 5.3 ile çağıran betiğin kendi dizininde arayacaktır .)" Emin misiniz? Nerede belgeleniyor? Ben yanılıyorsunuz umut ve PHP gelmez değil kullanmak __FILE__ve __DIR__için bu amaçla, bu kadar derhal gelen "kardeş" komut dahil kıracak sembolik olarak olanlar! : -o (Neyse ki, 7.1 kurulumumda burada iyi çalışıyor gibi görünüyor.)
Sz.

6

Kısa cevap: dahil edilen betiğe bağlıdır.

TFM bunu doğru bir şekilde açıklıyor:

Dosya include_path içinde bulunmazsa, include çağıran komut dosyasının dizinini ve geçerli çalışma dizinini kontrol eder.

Yani, eğer /app/main.php diyor include("./inc.php")olduğunu göreceksiniz /app/inc.php .

./ kesinlikle gerekli değil ama include_path üzerinde herhangi bağımlılığını kaldırır.

Birinin onu değiştirmesi durumunda mevcut çalışma dizinindeki include dosyalarını bulmaya güvenmem chdir().


Öyleyse dizeyi ile başlatırsanız, ./önce çağıran betiğin dizinini mi yoksa geçerli çalışma dizinini mi kontrol eder?
Pacerier

2
@Denis Howe Hayır, içerme yolunuz ile başlıyorsa, zaten mevcut çalışma dizinine bağlısınızdır ./. yani chdir ("/ app / diğer") include("./inc.php")başarısız olacaktır . Bu nedenle, include("inc.php")bu durumda güvenli olmak için kullanın .
Johnny Wong

@Pacerier, dizge ./ veya ../ ile başlıyorsa, yalnızca geçerli çalışma dizinini kontrol eder. (include_path ve çağıran betiğin dizini (B.php) yok sayılır). Daha fazla ayrıntı için cevabıma bakın.
Johnny Wong

-2
dir
-> a.php
-> c.php

- dir2 
-> b.php

Dahil etmek için ade byapmanız gerekenlerinclude("../a.php");

Dahil etmek için bde cyapmanız gerekenlerinclude("dir2/b.php");


4
@ Olli- Sorunun noktasını kaçırıyorsunuz- Kapsar zincirlendiğinde göreceli yolların nasıl belirlendiğini soruyordum.
Yarin
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.