nasıl oluyor da ‘oluyor’ ?

php include sorunu

26 Aralık, 2006 · 8 Yorumlar

php, bildindik “include” işlemi için bir çok güzel dil komutu barındırır: include, include_once, require, require_once.

yalnız bu komutlarla ilgili bir sorunum var. kendimce bir çözüm ürettim, ve kullanıyorum. daha iyisini bulamayanlar kullanır, daha iyisini bilenler de beni haberdar eder ümidiyle burada yayınlıyorum :)

sorun şu: diyelim ki şöyle bir dizin/betik yapınız var,

/dir1/a.php
/dir1/b.php
/c.php

a.php, b.php’yi include ediyor.
c.php de, a.php’yi include ediyor.

a.php’yi talep ettiğinizde, b.php aynı dizinde olduğu için sorun yok.
ama c.php’yi talep ettiğinizde, geçerli dizin o an için / olduğundan, a.php içindeki “include b.php” komutu da o dizin içinde b.php arıyor.

asp.net’teki gibi “relative to site root” (~/dir1/b.php)  gibi bir çözüm de php’de yok, path’i “/” ile başlatabilirsiniz ama bu da tüm sistem yolunu da bilmenizi gerektiriyor: /www/domainxxx/dir1/b.php.

debug_backtrace() isimli cabbar ve vakur bir metod, o an için çalıştırılan “stack trace”i bir dizi halinde döndürüyor. bu kıyağı, php’nin “interpreted” bir dil olmasına borçluyuz :) tabii ki sorunun kendisini de :). neyse, sonuç olarak include ve file_get_contents() fonksiyonlarının yerine şu fonksiyonları kullanmaya başladım:

<?php
 
 /*
  Görkem PAÇACI
  19 Aralık 2006
  Çeşme
 */
 
 function get_caller_script($seed=0)
 {
  $backtrace = debug_backtrace();
  $callerscript = $backtrace[$seed+1]["file"];
  return $callerscript;
 }

 function realpath_safe($filename, $seed=0)
 {
  $caller_script_path = get_caller_script($seed+1);
  return dirname($caller_script_path) . “/” . $filename;
 }
 
 function include_safe($filename)
 {
  return include realpath_safe($filename);
 }
 
 function require_once_safe($filename)
 {
  return require_once realpath_safe($filename);
 }
 
 function get_contents_safe($filename)
 {
  return file_get_contents(realpath_safe($filename));
 }
 
?>

Kategoriler: Güncel

8 cevap so far ↓

  • Onur Yerlikaya // 16 Temmuz, 2007 12:23 | Yanıtla

    Selamlar,

    bunun çözümü çok basit aslında yoksa benmı yanlıs anladım ?

    dirname(__FILE__)

    iyi calısmalar,
    onur

  • Görkem PAÇACI // 16 Temmuz, 2007 12:59 | Yanıtla

    Bu da güzel bir çözüm, yalnız bildiğim kadarıyla __FILE__ sabiti bazı ortamlarda farklı davranabiliyordu. örneğin b’yi a çağırdıysa, b’nin içindeki __FILE__ sabiti a’yı gösterebiliyordu.

  • Egemen // 24 Mart, 2009 14:05 | Yanıtla

    Fonksiyonlar ve tekniğin yanı sıra, debug_backtrace çok işime yarayıverdi bir anda!
    wordpress ile cms üretmeye niyetlenmiş durumdayım, menüleri sayfasına göre renk değiştiren bir yapıda, menu.php’yi çağıranın kim olduğunu bilmek çok iyi geldi.
    Teşekkürler.

  • Egemen // 24 Mart, 2009 15:02 | Yanıtla

    Belki işinize yarar,
    şu menü olayında, çağıran dosya adına ihtiyacım olunca kendini çağıran dosyanın path’inden adını ayrıştıran bişiy yaptım;

    <?php

    function get_caller_script($seed=0)
    {
    $backtrace = debug_backtrace();
    $callerscript = $backtrace[$seed+1]["file"];
    return $callerscript;
    }

    $path = get_caller_script();

    function _strlastpos ($str, $char)
    {
    $pathLen = strlen($str);
    $charPos = 0;
    $lastPos = 0;
    while ($charPos

  • Egemen // 24 Mart, 2009 15:03 | Yanıtla

    function _strlastpos ($str, $char)
    {
    $pathLen = strlen($str);
    $charPos = 0;
    $lastPos = 0;
    while ($charPos<$pathLen) {
    $charPos = strpos($str, $char,$charPos);
    if ($charPos != NULL) {
    $lastPos = $charPos;
    $charPos ++;
    }
    else {break;}
    }
    return $lastPos;
    }

  • Egemen // 24 Mart, 2009 15:03 | Yanıtla

    $lastSlash = _strlastpos ($path, ‘\\’);
    $lastDot = _strlastpos ($path, ‘.’);
    $file = substr($path, $lastSlash+1, $lastDot – $lastSlash -1);
    echo ‘file: ‘. $file;

  • Gorkem Pacaci // 24 Mart, 2009 15:05 | Yanıtla

    tesekkurler :)

  • Egemen // 24 Mart, 2009 15:05 | Yanıtla

    sığmayınca böldüm parçaladım, admin tamir etsin! =)

Yorum Yapın