If you like to declare an __autoload function within a namespace or class, use the spl_autoload_register() function to register it and it will work fine.
İsim çözünürlük kuralları
İsim çözünürlük kurallarının amaçları gereği bazı önemli tanımlar:
-
İsim alanı adı tanımları
- Nitelenmemiş isim
-
Fan gibi bir isim alanı ayracı içermeyen bir betimleyici.
- Nitelenmiş isim
-
Fan\Fin gibi bir isim alanı ayracı içeren bir betimleyici.
- Tamamen nitelenmiş isim
-
\Fan\Fin gibi bir isim alanı ayracı ile başlayan isim alanı ayraçlı bir betimleyici. namespace\Fan da tamamen nitelenmiş bir isimdir.
İsimler şu kurallara göre çözümlenir:
- Tamamen nitelenmiş işlev, sınıf ve sabit isimleri derleme sırasında çözümlenir. Örneğin, new \A\B deyimi A\B sınıfı olarak çözümlenir.
- Tamamen nitelenmemiş (nitelenmemiş ve nitelenmiş) isimlerin tamamı derleme sırasında geçerli ithal kurallarına göre dönüştürülür. Örneğin, A\B\C isim alanı C olarak ithal edilmişse bir C\D\e() çağrısı A\B\C\D\e() çağrısına dönüştürülür.
- Bir isim alanı içinde ithal kurallarına göre dönüştürülmeyen tüm nitelenmiş isimlerin önüne geçerli isim alanı ismi getirilir. Örneğin, A\B isim alanında yapılmış bir C\D\e() çağrısı A\B\C\D\e() çağrısına dönüştürülecektir.
- Nitelenmemiş sınıf isimleri derleme sırasında geçerli ithal kurallarına göre dönüştürülür (kısa ithal ismi için tam isim kullanılır). Örneğin, A\B\C isim alanı C olarak ithal edilmişse new C() deyimi new A\B\C() deyimine dönüştürülür.
-
İsim alanı içindeki (A\B olsun), nitelenmemiş işlev çağrıları çalışma
anında çözümlenir. fan() diye bir işlev şöyle çözümlenir:
- Geçerli isim alanında A\B\fan() işlevi aranır.
- Küresel fan() işlevi bulunmaya ve çağrılmaya çalışılır.
-
İsim alanı içindeki (A\B olsun), nitelenmemiş (tamamen nitelenmemiş)
veya nitelenmiş sınıf ismi çağrıları çalışma anında çözümlenir.
new C() ve new D\E() deyimlerinin
çözümlenişi aşağıda verilmiştir.
new C() için:
- Geçerli isim alanında A\B\C sınıfı aranır.
- A\B\C özdevinimli olarak yüklenmeye çalışılır.
- Geçerli isim alanı ile öncelenmiş olarak A\B\D\E sınıfı aranır.
- A\B\D\E özdevinimli olarak yüklenmeye çalışılır.
Örnek 1 - Örneklerle İsim Çözünürlüğü
<?php
namespace A;
use B\D, C\E as F;
// işlev çağrıları
fan(); // Varsa "A" isim alanında tanımlı "fan", yoksa küresel "fan"
\fan(); // Küresel alanda tanımlı "fan" çağrılır
my\fan(); // "A\my" isim alanında tanımlı "fan" çağrılır
F(); // Varsa "A" isim alanında tanımlı "F", yoksa küresel "F"
//sınıf adı çağrıları
new B(); // Varsa "A" isim alanında tanımlı "B" örneklenir
// Yoksa "A\B" sınıfı özdevinimli olarak yüklenmeye çalışılır
new D(); // ithal kuralları ile, "B" isim alanında tanımlı "D" örneklenir
// yoksa "B\D" sınıfı özdevinimli olarak yüklenmeye çalışılır
new F(); // ithal kuralları ile, "C" isim alanında tanımlı "E" örneklenir
// yoksa "C\E" sınıfı özdevinimli olarak yüklenmeye çalışılır
new \B(); // Varsa küresel alanda tanımlı "B" örneklenir
// yoksa "B" sınıfı özdevinimli olarak yüklenmeye çalışılır
new \D(); // Varsa küresel alanda tanımlı "D" örneklenir
// yoksa "D" sınıfı özdevinimli olarak yüklenmeye çalışılır
new \F(); // Varsa küresel alanda tanımlı "F" örneklenir
// yoksa "F" sınıfı özdevinimli olarak yüklenmeye çalışılır
// başka bir isim alanından duruk yöntem/isim alanı işlevleri
B\fan(); // "A\B" isim alanında tanımlı "fan" çağrılır
B::fan(); // "A" isim alanında tanımlı "B" sınıfının "fan" yöntemi çağrılır
// "A\B" sınıfı yoksa, "A\B" özdevinimli yüklenmeye çalışılır
D::fan(); // ithal kuralları ile, "B" isim alanında tanımlı "D" sınıfının
// "fan" yöntemi çağrılır; "B\D" sınıfı yoksa, "B\D"
// özdevinimli yüklenmeye çalışılır
\B\fan(); // "B" isim alanında tanımlı "fan" çağrılır
\B::fan(); // Küresel alandaki "B" sınıfının "fan" yöntemi çağrılır
// "B" sınıfı yoksa, "B" özdevinimli yüklenmeye çalışılır
// geçerli isim alanının duruk yöntemleri ve isim alanı işlevleri
A\B::fan(); // "A\A" isim alanında tanımlı "B" sınıfının "fan" yöntemi
// çağrılır; "A\A\B" sınıfı yoksa, "A\A\B" özdevinimli
// yüklenmeye çalışılır
\A\B::fan(); // "A\B" isim alanında tanımlı "B" sınıfının "fan" yöntemi
// çağrılır; "A\B" sınıfı yoksa, "A\B" özdevinimli yüklenmeye
// çalışılır
?>
kdimi
28-Oct-2010 03:35
safakozpinar at NOSPAM dot gmail dot com
22-Oct-2010 10:04
As working with namespaces and using (custom or basic) autoload structure; magic function __autoload must be defined in global scope, not in a namespace, also not in another function or method.
<?php
namespace Glue {
/**
* Define your custom structure and algorithms
* for autoloading in this class.
*/
class Import
{
public static function load ($classname)
{
echo 'Autoloading class '.$classname."\n";
require_once $classname.'.php';
}
}
}
/**
* Define function __autoload in global namespace.
*/
namespace {
function __autoload ($classname)
{
\Glue\Import::load($classname);
}
}
?>
sammaye
12-Jun-2010 01:24
I have noticed one problem with __autoload function. Say you have two namespaces, one is a sub of the other:
\Glue
\Glue\Import
Within that Import namespace you have a function auto() with the magic __autoload inside. No matter what you do that auto() will never traverse it's sub function meaning you will nevber get an __autoload function.
Even if you put the __autoload within a class within the namespace as such:
<?php
namespace Glue\Import;
class import{
private static $_AutoLoad = array();
private static $_Imported = array();
function load($sName){
if(! isset(self::$_AutoLoad[$sName]))
//throw new ImportError("Cannot import module with name '$sName'.");
echo("file with name '$sName' failed to load with path '".self::$_AutoLoad[$sName]."'");
if(! isset(self::$_Imported[$sName])){
self::$_Imported[$sName] = True;
return include_once(self::$_AutoLoad[$sName]);
}
}
function push($sName, $sPath){
self::$_AutoLoad[$sName] = $sPath;
}
function auto(){
function __autoload($sClass){
load($sClass);
}
}
}
?>
It will not work. Just something to keep in mind.
rangel
31-Jul-2009 09:48
The term "autoload" mentioned here shall not be confused with __autoload function to autoload objects. Regarding the __autoload and namespaces' resolution I'd like to share the following experience:
->Say you have the following directory structure:
- root
| - loader.php
| - ns
| - foo.php
->foo.php
<?php
namespace ns;
class foo
{
public $say;
public function __construct()
{
$this->say = "bar";
}
}
?>
-> loader.php
<?php
//GLOBAL SPACE <--
function __autoload($c)
{
require_once $c . ".php";
}
class foo extends ns\foo // ns\foo is loaded here
{
public function __construct()
{
parent::__construct();
echo "<br />foo" . $this->say;
}
}
$a = new ns\foo(); // ns\foo also loads ns/foo.php just fine here.
echo $a->say; // prints bar as expected.
$b = new foo; // prints foobar just fine.
?>
If you keep your directory/file matching namespace/class consistence the object __autoload works fine.
But... if you try to give loader.php a namespace you'll obviously get fatal errors.
My sample is just 1 level dir, but I've tested with a very complex and deeper structure. Hope anybody finds this useful.
Cheers!
rangel
31-Jul-2009 09:47
The term "autoload" mentioned here shall not be confused with __autoload function to autoload objects. Regarding the __autoload and namespaces' resolution I'd like to share the following experience:
->Say you have the following directory structure:
- root
| - loader.php
| - ns
| - foo.php
->foo.php
<?php
namespace ns;
class foo
{
public $say;
public function __construct()
{
$this->say = "bar";
}
}
?>
-> loader.php
<?php
//GLOBAL SPACE <--
function __autoload($c)
{
require_once $c . ".php";
}
class foo extends ns\foo // ns\foo is loaded here
{
public function __construct()
{
parent::__construct();
echo "<br />foo" . $this->say;
}
}
$a = new ns\foo(); // ns\foo also loads ns/foo.php just fine here.
echo $a->say; // prints bar as expected.
$b = new foo; // prints foobar just fine.
?>
If you keep your directory/file matching namespace/class consistence the object __autoload works fine.
But... if you try to give loader.php a namespace you'll obviously get fatal errors.
My sample is just 1 level dir, but I've tested with a very complex and deeper structure. Hope anybody finds this useful.
Cheers!
