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!
Правила за определяне на имена
Имената се определят съгласно следните правила за определяне:
-
Съгласно текущите правила за внасяне, всички определени имена
се преобразуват по време на компилация. Например, ако е внесено
пространството от имена A::B::C, извикването на
C::D::e()се преобразува доA::B::C::D::e(). -
Съгласно текущите правила за внасяне, неопределените имена на класове се
преобразуват по време на компилация (краткото внесено име се заменя с пълно име).
Например, ако е внесено пространството от имена A::B::C,
кодът
new C()ще се преобразува доnew A::B::C(). - В тялото на пространство от имена, извикванията на неопределени функции, дефинирани в текущото пространство от имена (и известни по време на анализа на извикването), се интерпретират като извиквания на функции на това пространство от имена, по време на компилация.
-
В пространството от имена (да кажем A::B), извикванията към неопределени функции,
които не са дефинирани в текущото пространство от имена, се определят по време
на изпълнение. Ето как се определя извикване на функция foo():
- Търси се функция от текущото пространство от имена: A::B::foo().
- Прави се опит да се намери и извика вградената функция foo().
-
В тялото на пространство от имена (примерно A::B), обръщенията
към неопределени имена на класове се определят по време на
изпълнение. Ето как се определя извикване към
new C():- Търси клас от текущото пространство от имена: A::B::C.
- Прави опит да намери и извика вградения клас C.
- Прави опит автоматично да зареди A::B::C.
new ::C(). -
Извикванията на определени функции се разрешават по време на изпълнение. Ето как се определя извикване на A::B::foo():
- Търси функция foo() в пространството от имена A::B.
- Търси клас A::B и извиква статичния му метод foo(). Ако е необходимо ще зареди класа автоматично.
-
Определените имена на класове се разрешават по време на компилация,
като класове от съответното пространство от имена. Например
new A::B::C()сочи към клас C от пространството от имена A::B.
Example #1 Примери за определянето на имена
<?php
namespace A;
// извиквания на функции
foo(); // първо се прави опит за извикване на "foo", дефинирана в пространството от имена "A"
// след това извиква вътрешната функция "foo"
::foo(); // извиква функция "foo", дефинирана в глобалната област на действие
// референции към класове
new B(); // първо се прави опит за създаване на обект от клас "B", дефиниран в пространството от имена "A"
// след което създава обект от вътрешния клас "B"
new ::B(); // създава обект от клас "B", дефиниран в глобалната област на действие
// статични методи/функции на пространството от имена от друго пространство от имена
B::foo(); // първо се прави опит за извикване на функция "foo" от пространството от имена "A::B"
// след това извиква метод "foo" от вътрешния клас "B"
::B::foo(); // първо се прави опит за извикване на функция "foo" от пространството от имена "B"
// след това извиква метод "foo" от клас "B" на глобалната област на действие
// статични методи/функции на пространството от имена от текущото пространство от имена
A::foo(); // първо се прави опит за извикване на функция "foo" от пространството от имена "A::A"
// след това се прави опит за извикване на метод "foo" от клас "A" от пространството от имена "A"
// след това се прави опит за извикване на функция "foo" от пространството от имена "A"
// след това извиква метод "foo" от вътрешния клас "A"
::A::foo(); // първо се прави опит за извикване на функция "foo" от пространството от имена "A"
// след това извиква метод "foo" от клас "A" на глобалната област на действие
?>
Правила за определяне на имена
rangel
31-Jul-2009 07:48
31-Jul-2009 07:48
rangel
31-Jul-2009 07:47
31-Jul-2009 07: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!
