2013-05-29 7 views
2

Я использую Propel вместе с CodeIgniter. Я сделал класс MY_Model (который расширяет CI_Model), который использует свой конструктор для загрузки Propel.Использование пространства имен в расширенном классе

В случае, если вы любопытны:

class MY_Model extends CI_Model{ 
    public function __construct(){ 
     parent::__construct(); 

     require_once '/propel/runtime/lib/Propel.php'; 
     Propel::init('/build/conf/project-conf.php'); 
     set_include_path('/build/classes'.PATH_SEPARATOR.get_include_path()); 
    } 
} 

Итак, теперь, когда я делаю новую модель CodeIgniter, он загрузит Propel для меня. Дело в том, что я добавил пространства имен в некоторые из созданных Propel моделей. Я подумал, что могу добавить строку use Reports; внутри конструктора модели, но нет.

class Reports_model extends MY_Model{ 
    function __construct(){ 
     parent::__construct(); 
     use Reports; 
    } 
} 

Это дает мне

syntax error, unexpected T_USE

Хорошо, я подумал, давайте попробуем поставить его вне конструктора:

class Reports_model extends MY_Model{ 
    use Reports; 

    function __construct(){ 
     parent::__construct(); 
    } 
} 

Теперь я получаю длинную ошибку:

syntax error, unexpected T_USE, expecting T_FUNCTION

В крайнем случае, я добавил use Reports; перед декларированием класса:

use Reports; 

class Reports_model extends MY_Model{ 
    function __construct(){ 
     parent::__construct(); 
    } 
} 

Теперь я получаю еще больше ошибок!

The use statement with non-compound name 'Reports' has no effect
Class 'ReportsQuery' not found

В другой функции в классе, у меня есть строка, которая делает $report = ReportsQuery::create();.

Итак, как я могу получить линию use Reports;? Я действительно не хочу добавлять Reports\всюду.

Как я могу сделать так, что я могу сделать:

$report = ReportsQuery::create(); 

вместо:

$report = Reports\ReportsQuery::create(); 
+0

Хороший вопрос ... и мое продолжение было бы причиной того, почему PHP не может найти пространство имен «Отчеты»? я предполагаю, что расположение класса 'Reports_model' делает так, что PHP не знает, где найти« Отчеты ». Извините, я не эксперт по пространству имен, но вы можете спросить об этом в группе Propel google, если вы не получите ответ здесь! – jakerella

+0

@jakerella: пространство имен «Отчеты» существует только в моделях Propel. Я предполагаю, что конструктор 'MY_Model' еще не был вызван, поэтому PHP не знает, где находится пространство имен. –

+0

Riiiight ... hrm. Может быть, вам просто нужно всегда начинать Propel по сравнению с конструктором модели? Другими словами, поместите его в какую-то зону запуска (не очень знакомая с CI). – jakerella

ответ

2

Видимо , ключевое слово use не делает то, что я, хотя он и сделал. Это просто говорит PHP, где искать класс.

Что мне нужно было сделать, это использовать ключевое слово namespace, чтобы объявить, что мой класс был в пространстве имен Reports. Затем я должен был сказать, чтобы он использовал MY_Model из глобального пространства имен.

namespace Reports; 
use MY_Model; 

class Reports_model extends MY_Model{ 
    function __construct(){ 
     parent::__construct(); 
    } 
} 

Я мог бы также сделать class Reports_model extends \MY_Model{ вместо use MY_Model; линии.

Проблема в том, что CodeIgniter не может найти Reports_model, потому что теперь он находится в пространстве имен Reports, а не в глобальном пространстве имен. Я нашел решение этого вопроса в другом вопросе StackOverflow (https://stackoverflow.com/a/14008411/206403).

Существует функция, называемая class_alias, которая в основном магия.

namespace Reports; 
use MY_Model; 

class_alias('Reports\Reports_model', 'Reports_model', FALSE); 

class Reports_model extends MY_Model{ 
    function __construct(){ 
     parent::__construct(); 
    } 
} 

И это прекрасно работает!

+0

Фактически вы можете просто добавить '\\' перед пространством имен и получить доступ к нему в glbal scope. Наййст, вероятно, хотел это сказать. – itachi

+0

@itachi: Я упоминаю, что в своем ответе: 'extends \ MY_Model'. Проблема в том, что я использую CodeIgniter, поэтому я не могу ее редактировать, чтобы добавить косые черты. –

0

Просто префикс все классы без пространств имен с помощью «\» в коде с пространствами имен

+0

Но как я могу заставить свой код быть * в * пространстве имен? * Это * вопрос здесь. –

+0

Код ниже "пространство имен BlahBlahBlah;" будет в пространстве имен BlahBlahBlah. Если вы определили какой-то класс там, вы сможете использовать этот класс снаружи с \ BlahBlahBlah \ MyClass Или добавить «использовать BlahBlahBlah \ MyClass;» к файлу, в котором он будет использоваться, и получить к нему доступ по имени класса без пространства имен. Обратите внимание, что в конструкции «use» вы должны указать полное имя класса с именами, php не может импортировать все классы какого-либо пространства имен таким образом. Если вы пишете «использовать» внутри класса, это будет интерпретироваться как добавление черты к этому классу, вам это не нужно. – Nayjest

Смежные вопросы