Birinin bu hatayla karşılaşmasının birçok nedeni vardır ve bu nedenle öncelikle neyin kontrol edileceğine dair iyi bir kontrol listesi önemli ölçüde yardımcı olur.
Aşağıdaki satırda sorun giderdiğimizi düşünelim:
require "/path/to/file"
Kontrol Listesi
1. Dosya yolunda yazım hatası olup olmadığını kontrol edin
- manuel olarak kontrol et (yolu görsel olarak kontrol ederek)
tarafından çağrılan ne olursa olsun veya taşıma require*
veya include*
kendi değişkene, kopyalamak ve bir terminal onu erişmeyi deneyin, bunu yankı:
$path = "/path/to/file";
echo "Path : $path";
require "$path";
Sonra bir terminalde:
cat <file path pasted>
2. Dosya yolunun göreli ve mutlak yolla ilgili hususlar açısından doğru olup olmadığını kontrol edin
- eğik çizgi "/" ile başlıyorsa, web sitenizin klasörünün kökünden (belge kökü) değil, sunucunuzun kökünden bahsetmektedir.
- örneğin, web sitenizin dizini
/users/tony/htdocs
- eğik çizgi ile başlamıyorsa, içerme yoluna dayanır (aşağıya bakın) veya yol görecelidir. Göreli ise, PHP geçerli çalışma dizininin yolunu göreceli olarak hesaplar .
- bu nedenle, web sitenizin kök yoluna veya yazdığınız dosyaya göre değil
- bu nedenle her zaman mutlak dosya yolları kullanın
En iyi uygulamalar:
Bir şeyleri hareket ettirmeniz durumunda komut dosyanızı sağlam hale getirmek için, çalışma zamanında mutlak bir yol oluştururken 2 seçeneğiniz vardır:
- kullanın
require __DIR__ . "/relative/path/from/current/file"
. __DIR__
Sihirli sabit akım dosyanın dizinini döndürür.
bir SITE_ROOT
sabiti kendiniz tanımlayın :
- web sitenizin dizininin kökünde bir dosya oluşturun, ör.
config.php
içinde config.php
, yaz
define('SITE_ROOT', __DIR__);
site kök klasörüne başvurmak istediğiniz her dosyada config.php
, SITE_ROOT
sabiti ekleyin ve istediğiniz yerde sabit kullanın :
require_once __DIR__."/../config.php";
...
require_once SITE_ROOT."/other/file.php";
Bu 2 uygulama, uygulamanızı daha taşınabilir hale getirir, çünkü içerme yolu gibi ini ayarlarına dayanmaz.
3. Dahil etme yolunuzu kontrol edin
Ne görece ne de tamamen mutlak olarak dosyaları dahil etmenin bir başka yolu, içerme yoluna güvenmektir . Bu genellikle Zend çerçevesi gibi kütüphaneler veya çerçeveler için geçerlidir.
Böyle bir içerme şöyle görünecektir:
include "Zend/Mail/Protocol/Imap.php"
Bu durumda, "Zend" olan klasörün dahil etme yolunun bir parçası olduğundan emin olmak istersiniz.
Dahil etme yolunu aşağıdakilerle kontrol edebilirsiniz:
echo get_include_path();
Klasöre aşağıdakilerle bir klasör ekleyebilirsiniz:
set_include_path(get_include_path().":"."/path/to/new/folder");
4. Sunucunuzun bu dosyaya erişimi olup olmadığını kontrol edin
Hep birlikte, sunucu işlemini (Apache veya PHP) çalıştıran kullanıcının bu dosyadan okuma veya yazma iznine sahip olmaması olabilir.
Sunucunun hangi kullanıcıyı çalıştırdığını kontrol etmek için posix_getpwuid kullanabilirsiniz :
$user = posix_getpwuid(posix_geteuid());
var_dump($user);
Dosyadaki izinleri bulmak için uçbirime aşağıdaki komutu yazın:
ls -l <path/to/file>
ve izin sembolik notasyonuna bakın
5. PHP ayarlarını kontrol edin
Yukarıdakilerin hiçbiri işe yaramadıysa, sorun muhtemelen bazı PHP ayarlarının bu dosyaya erişmesini yasaklamasıdır.
Üç ayar alakalı olabilir:
- open_basedir
- Bu ayarlanırsa, PHP belirtilen dizinin dışındaki herhangi bir dosyaya erişemez (sembolik bir bağlantı üzerinden bile olsa).
- Ancak, varsayılan davranış ayarlanmaması içindir, bu durumda herhangi bir kısıtlama yoktur
- Bu, çağrılarak
phpinfo()
veya kullanılarak kontrol edilebilir.ini_get("open_basedir")
- Php.ini dosyanızı veya httpd.conf dosyanızı düzenleyerek ayarı değiştirebilirsiniz.
- güvenli mod
- bu açıksa kısıtlamalar uygulanabilir. Ancak, bu PHP 5.4 kaldırıldı. Hala güvenli modun desteklenmesini destekleyen bir sürümdeyseniz, hala desteklenmekte olan bir PHP sürümüne yükseltme yapın .
- allow_url_fopen ve allow_url_include
- Bu, yalnızca yerel dosya sistemine dosya eklemeye çalışırken değil, http: // gibi bir ağ işlemi yoluyla dosya eklemek veya açmak için geçerlidir
- bu ile kontrol edilebilir
ini_get("allow_url_include")
veini_set("allow_url_include", "1")
Köşe dolapları
Yukarıdakilerin hiçbiri sorunu teşhis etmeyi etkinleştirmediyse, olabilecek bazı özel durumlar şunlardır:
1. Dahil etme yoluna dayanan kütüphanenin dahil edilmesi
Göreli veya mutlak bir yol kullanarak bir kitaplık, örneğin Zend çerçevesi dahil edebilirsiniz. Örneğin :
require "/usr/share/php/libzend-framework-php/Zend/Mail/Protocol/Imap.php"
Ama yine de aynı tür bir hata alıyorsunuz.
Bunun nedeni, (başarıyla) eklediğiniz dosyanın kendisine başka bir dosya için bir include deyimi olması ve bu ikinci include deyiminin söz konusu kitaplığın yolunu ekleme yoluna eklediğinizi varsayması olabilir.
Örneğin, daha önce bahsedilen Zend çerçeve dosyası aşağıdakileri içerebilir:
include "Zend/Mail/Protocol/Exception.php"
ne göreceli yolun ne de mutlak yolun içerdiği bir şeydir. Zend çerçeve dizininin dahil etme yoluna eklendiğini varsayar.
Böyle bir durumda, tek pratik çözüm dizini içerme yolunuza eklemektir.
2. SELinux
Security-Enhanced Linux çalıştırıyorsanız, sunucudan dosyaya erişimi reddederek sorunun nedeni olabilir.
SELinux'un sisteminizde etkin olup olmadığını kontrol etmek için sestatus
komutu bir terminalde çalıştırın . Komut yoksa, SELinux sisteminizde değildir. Varsa, size uygulanıp uygulanmayacağını söylemelidir.
SELinux politikalarının sorunun nedeni olup olmadığını kontrol etmek için geçici olarak kapatmayı deneyebilirsiniz. Ancak dikkatli olun, çünkü bu korumayı tamamen devre dışı bırakacaktır. Bunu üretim sunucunuzda yapmayın.
setenforce 0
SELinux ile ilgili sorununuz artık kapalıysa, bu temel nedendir.
Bunu çözmek için SELinux'u buna göre yapılandırmanız gerekecektir.
Aşağıdaki bağlam türleri gerekli olacaktır:
httpd_sys_content_t
sunucunuzun okuyabilmesini istediğiniz dosyalar için
httpd_sys_rw_content_t
okuma ve yazma erişimi istediğiniz dosyalar için
httpd_log_t
günlük dosyaları için
httpd_cache_t
önbellek dizini için
Örneğin, httpd_sys_content_t
bağlam türünü web sitenizin kök dizinine atamak için şunu çalıştırın:
semanage fcontext -a -t httpd_sys_content_t "/path/to/root(/.*)?"
restorecon -Rv /path/to/root
Dosyanız bir giriş dizinindeyse, boole'yi de açmanız gerekir httpd_enable_homedirs
:
setsebool -P httpd_enable_homedirs 1
Her durumda, SELinux'un politikalarınıza bağlı olarak bir dosyaya erişimi reddetmesinin çeşitli nedenleri olabilir. Yani bunu sorgulamanız gerekecek. İşte bir web sunucusu için SELinux'u yapılandırmakla ilgili özel bir öğretici.
3. Symfony
Symfony kullanıyorsanız ve bir sunucuya yükleme yaparken bu hatayı yaşıyorsanız, uygulamanın önbelleği app/cache
yüklenmiş olmadığı için önbelleğin sıfırlanmamış olması veya önbelleğin temizlenmemiş olması olabilir.
Aşağıdaki konsol komutunu çalıştırarak bunu test edebilir ve düzeltebilirsiniz:
cache:clear
4. Zip dosyası içinde ACSII olmayan karakterler
Görünüşe göre, bu hata zip->close()
zip içindeki bazı dosyalar dosya adlarında "é" gibi ASCII olmayan karakterlere sahip olduğunda da çağrılabilir.
Olası bir çözüm, utf8_decode()
hedef dosyayı oluşturmadan önce dosya adını girmektir .
Fran Cano'ya bu konuya bir çözüm bulup önerdiği için verilen krediler