2015-09-30 6 views
-1

Добрый день. Я работаю над примером, чтобы точно понимать, что такое имена, и каковы их ограничения. У меня есть эта структура (окна):Использование пространств имен PHP в подзоне

D:\server\sistemas\tests\phpNS\exec.php

D:\server\sistemas\tests\phpNS\Extra\Call.php

D:\server\sistemas\tests\phpNS\Extra\exec.php --> (copy of the other one)

D:\server\sistemas\tests\phpNS\Lib\Base.php

код для каждого один:

exec.php
<?php 
spl_autoload_register(); 

$a = new Extra\Call(); 
?> 

Call.php
<?php 
namespace Extra{ 
    spl_autoload_register(); 

    class Call{ 
     public function __construct(){ 
      $inst = new \Libs\Base(); 
      var_dump($inst); 
     } 
    } 
} 
?> 

Base.php
<?php 
namespace Libs{ 
    class Base{ 
     public $dac; 
     public $doc; 
     public function __construct(){ 

     } 
    } 
} 
?> 

Если я работаю по этому сценарию, все в порядке. Проблема заключается в том, когда я исполняю EXTRA \ exec.php

Extra \ exec.php

<?php 
namespace Extra{ 
    spl_autoload_register(); 

    $a = new Call(); 
} 
?> 

Это, как предполагается, что контекст файловой системы этого файла Extra так, поэтому я использую это пространство имен, но не за работой. Я получил эту ошибку.

Fatal error: spl_autoload(): Class Extra\Call could not be loaded in D:\server\sistemas\tests\phpNS\Extra\exec.php on line 5

Тогда я помню классы PHP называются по обратной косой черты (\ итератора), так что я попробовал это тоже:

Extra \ exec.php

<?php 
    spl_autoload_register(); 

    $a = new \Extra\Call(); 

?> 

Но я получил тот же результат ... Что я делаю неправильно, и что мне делать, если я хочу использовать этот файл в этом или в любом каталоге n-depth?

+0

Помогла бы вам использовать один из компонентов «автозагрузчика»? например [Загрузчик классов PSR-4] (http://symfony.com/doc/current/components/class_loader/psr4_class_loader.html). Также: [Aura.Autoload: предоставляет полный PSR-4 и ограниченный автозагрузчик PSR-0] (https://github.com/auraphp/Aura.Autoload/tree/2.x). Оба упрощают управление «автозагрузкой» классов. Я использовал оба и в настоящее время использую 'Aura'. –

+0

Хм кажется, что он может работать. Но это означает, что мне нужно использовать symfony, чтобы получить это право? Я просто убеждаюсь, что могу использовать пространства имен на любом уровне n-depth-каталога, потому что, если мне нужно использовать функцию перезаписи htaccess из пустого index.php, и с этой проблемой я не могу перенаправить файл в структура проекта без получения ошибки загрузки класса. – Artynok

+0

Мне жаль, Райан, может быть, я что-то делаю неправильно. Я переписал свой код на exec.php (этот хороший) \t $ dir = _DIR_ _. "/ Libs/Aura.Autoload-2.x/src/Loader.php"; \t require_once ($ dir); \t $ loader = new \ Aura \ Autoload \ Loader; \t $ loader-> register(); \t $ loader-> addPrefix ('Extra \ Call', '\ Extra \ Call.php'); \t $ a = new Extra \ Call(); Я следил за инструкциями и загружал Ауру, или, по крайней мере, я думаю, что загружается, но не загружает мой класс. Можете ли вы помочь мне с этим, пожалуйста? – Artynok

ответ

2

Во-первых, не рекомендуется использовать объявления namespace в виде блоков. Предпочтительно просто объявить namespace, а затем перейти в свои классы и поместить один класс в файл. Это, как вы бы объявить \Extra\Call

namespace Extra; 

class Call{ 
    public function __construct(){ 
     $inst = new \Libs\Base(); 
     var_dump($inst); 
    } 
} 

обычно используется spl_autoload_register(); с именем вашей отзывной функции, но вы не предоставили каких-либо функций, которые могли бы действовать в качестве автозагрузчика. Функция автозагрузки должна иметь в качестве единственного аргумента имя класса, который вы пытаетесь загрузить. он должен затем найти ваш файл класса и include или require этот файл. Вот пример from the PHP docs

spl_autoload_register(function ($class) { 
    include 'classes/' . $class . '.class.php'; 
}); 
+0

Ну, это не имеет никакого смысла. Потому что я не работаю с классом Im, создающим класс внутри другого. Даже когда он работает, я все еще зависим от требования и/или включаю (_once). Потому что, если я работаю с 1000 классами, я должен загрузить 1000 классов в функции автозагрузки ... значит, мы вернулись к старым временам только с «аккуратным» кодом, но в производительности я не получу лучшего. – Artynok

+1

@Artynok Прежде всего, автозагрузка загружает только файлы по мере необходимости. Вы не можете сказать, что вам нужен 1000 классов для каждого файла. Во-вторых, вы можете настроить автозагрузку, чтобы она соответствовала вашей структуре каталогов. Наконец, это не вещь производительности, как вещь здравого смысла. Мне никогда не нужно угадывать, где найти мои занятия. – Machavity

+0

Вначале пространства имен не являются блоками? да, они могут быть использованы как блоки и показаны в [справочнике php] (http://php.net/manual/en/language.namespaces.definitionmultiple.php) Во-вторых, поскольку вы объяснили, что функция autooload использует один требуемый файл или класс ... какой happe, если мне нужно много классов или файлов для этого случая? Наконец-то вы просто ответили теорией, что никогда не использовали мое дело, чтобы попытаться объяснить, как использовать это – Artynok

0

учитывая факты, которые Machavity нужны явно Дают «более конкретный пример» здесь является результатом его ответа: , как вы сказали, что нужно использовать, чтобы зарегистрировать функцию автозагрузки внутри spl_autoload_register так что я сделал это, и он работает ... но JUST для exec.php, который находится в корневом месте.

exec.php

spl_autoload_register(function ($class) { 
    include $class . '.php'; 
}); 

$a = new Extra\Call(); 

Но это не работает для Extra \ exec.php. Мне нужно было получить базовое имя и использовать пространство имен для загрузки класса. Но он продолжает терпеть неудачу, потому что просит меня не существовать Extra \ Libs \ Base.php

Extra \ exec.php

spl_autoload_register(function ($class) { 
    $f = basename($class); 
    include __DIR__."\\".$f . '.php'; 
}); 

$a = new \Extra\Call(); 

Это означает, что мне нужно получить всю корневую структуру в зависимости от каждого местоположения и сделать много уродливых трюков. Как я уже сказал, вы никогда не использовали мое дело даже для того, чтобы получить этот вывод, поэтому я отметил, что ваш ответ не так полезен.