Path Alias e Namespace ====================== O Yii utiliza path aliases (apelidos para caminhos) extensivamente. Um path alias, é um apelido associado ao caminho de um diretório ou arquivo. Um path alias utiliza a sintaxe de ponto para separar seus itens, similar a forma largamente adotada em namespaces: ~~~ RootAlias.path.to.target ~~~ Onde `RootAlias` é o nome de um diretório existente. Ao usar o método [YiiBase::getPathOfAlias()], um apelido pode ser traduzido para o seu caminho correspondente. Por exemplo, `system.web.CController` seria traduzido para `yii/framework/web/CController`. Ao executar o método [YiiBase::setPathOfAlias()], podemos definir novos apelidos para caminhos. Apelidos de Diretórios Raizes ----------------------------- Por conveniência, o Yii já possui predefinidos os seguintes apelidos: - `system`: refere-se ao diretório do Yii framework; - `zii`: refere-se ao diretório da [biblioteca Zii](/doc/guide/extension.use#zii-extensions); - `application`: refere-se ao [diretório base](/doc/guide/basics.application#application-base-directory) da aplicação; - `webroot`: refere-se ao diretório que contém o arquivo do [script de entrada](/doc/guide/basics.entry). - `ext`: refere-se ao diretório que contém todas as [extensões](/doc/guide/extension.overview) de terceiros. Além disso, se a aplicação utiliza [módulos](/doc/guide/basics.module), um apelido de diretório raiz (root alias) é predefinido para cada módulo, apontando para o diretório base do módulo correspondente. Por exemplo, se uma aplicação usa um módulo com ID `users`, o apelido de diretório raiz chamado `users` será definido. Importando Classes ------------------ A utilização de apelidos é muito conveniente para importar a definição de uma classe. Por exemplo, se quisermos incluir a definição da classe [CController] podemos fazer o seguinte: ~~~ [php] Yii::import('system.web.CController'); ~~~ O método [import|YiiBase::import] é mais eficiente que o `include` e o `require` do PHP. Com ele, a definição da classe que está sendo importada não é incluída até que seja referenciada pela primeira vez (Implementado pelo mecanismo auto carregamento do PHP). Importar o mesmo namespace várias vezes, também é muito mais rápido do que utilizar o `include_once` e o `require_once`. > Tip|Dica: Quando referenciamos uma das classes do Yii Framework, não precisamos importa-la ou inclui-la. Todas as classes Yii são pré-importadas. ###Usando mapa de Class A partir da versão 1.1.5, o Yii permite que as classes possam ser pré-importadas através de um mecanismo de mapeamento de classe que também é usado por classes Yii. As classes pré-importadas podem ser usadas em qualquer lugar na aplicação Yii sem ser explicitamente importadas ou incluídas. Este recurso é muito útil para uma biblioteca ou framework que é construído em cima do Yii. Para pré-importar um conjunto de classes, o seguinte código deve ser executado antes de chamar o [CWebApplication::run()]: ~~~ [php] Yii::$classMap=array( 'ClassName1' => 'path/to/ClassName1.php', 'ClassName2' => 'path/to/ClassName2.php', ...... ); ~~~ Importando Diretórios --------------------- Podemos também utilizar a seguinte sintaxe para importar todo um diretório de uma só vez, de forma que os arquivos de classe dentro dele sejam automaticamente incluídos, quando necessário. ~~~ [php] Yii::import('system.web.*'); ~~~ Além do método [import|YiiBase::import], apelidos são utilizados em vários outros locais para se referir a classes. Por exemplo, um apelido pode ser passado para o método [Yii::createComponent()] para criar uma instância da classe informada, mesmo que o arquivo da classe ainda não tenha sido incluído. Namespace --------- Não confunda um path alias com um namespace. Um namespace refere-se a um agrupamento lógico de nomes de classes para que eles possam ser diferenciadas de outros nomes das classes, mesmo que eles sejam iguais. Já um path alias é utilizado para referenciar um arquivo de classe ou um diretório. Um path alias não conflita com um namespace. > Tip|Dica: Como o PHP, antes da versão 5.3.0, não dá suporte a namespaces, você não pode criar instâncias de duas classes que tenham o mesmo nome, mas definições diferentes. Por isso, todas as classes do Yii framework são prefixadas com uma letra "C" (que significa 'class'), de modo que elas possam ser diferenciadas das classes definidas pelo usuário. Recomenda-se que o prefixo "C" seja reservado somente para utilização do Yii framework, e que classes criadas pelos usuário sejam prefixadas com outras letras. Classes com Namespace --------------------- Uma classe com namespace refere-se a uma classe declarada dentro de um espaço não-global. Por exemplo, a classe `application\components\GoogleMap` é declarada dentro do namespace `application\components`. O uso das classes com namespace requer PHP 5.3.0 ou superior. A partir da versão 1.1.5, é possível a utilização de uma classe namespaced sem incluir explicitamente. Por exemplo, podemos criar uma nova instância do `application\components\GoogleMap` sem incluir o arquivo de classe correspondente explicitamente. Isso é possível com o mecanismo de auto carregamento das classes Yii. Afim de ser capaz de carregar automaticamente uma classe com namespace, o namespace deve ser nomeado de forma semelhante a nomear um path alias. Por exemplo, a classe `application\components\GoogleMap` deve ser armazenada em um arquivo que pode ser apelidado como `application.components.GoogleMap` Então, para usar namespace personalizado começando com, por exemplo `\mynamespace` aonde as classes são localizadas em `/var/www/common/mynamespace/` a única coisa que você deve fazer é definir um path alias, como o seguinte: ~~~ [php] Yii::setPathOfAlias('mynamespace', '/var/www/common/mynamespace/'); ~~~ Controles com Namespace ----------------------- Por padrão Yii usa controladores do namespace global. Essas classes estão localizados sob `protected/controllers`. Você pode alterar esse comportamento de duas maneiras diferentes: usando `controllerMap` e usando `controllerNamespace`. O primeiro permite que você use controles com namespaces diferentes. O último requer menos configuração para definir um namespace para todos os controles. ### Usando `controllerMap` A melhor maneira de mudar o mapa do controle é usar o arquivo de configuração (`protected/config/main.php`): ~~~ // adding "mynamespace" namespace Yii::setPathOfAlias('mynamespace', '/var/www/common/mynamespace/'); return array( 'basePath'=>dirname(__FILE__).DIRECTORY_SEPARATOR.'..', 'name'=>'My Web Application', 'controllerMap' => array( 'test' => '\mynamespace\controllers\TestController', ), ~~~ Quando o usuário tenta carregar qualquer um dos controles definidos em `controllerMap`, Yii carrega as classes especificadas, ignorando o método de carregamento normal do controle. No caso de `test` o Yii irá carregar a classe `\mynamespace\controllers\TestController` localizada em `/var/www/common/mynamespace/controllers/TestController.php`. Observe que o código do controle deve ter um namespace definido: ~~~ [php] // define namespace: namespace mynamespace\controllers; // since class is now under namespace, global namespace // should be referenced explicitly using "\": class TestController extends \CController { public function actionIndex() { echo 'This is TestController from \mynamespace\controllers'; } } ~~~ ### Usando `controllerNamespace` Uma vez que a aplicação é um módulo em si, é possível utilizar a propriedade `controllerNamespace` da mesma maneira como descrita em "Módulos com namespace" logo abaixo. Módulos com namespace --------------------- Às vezes é útil utilizar namespace para o módulo completo. Por exemplo, se você quiser colocar `testmodule` em `\mynamespace\modules\testmodule` apontando para `/var/www/common/mynamespace/modules/testmodule` você deveria primeiro criar a seguinte estrutura de arquivo: ~~~ /var/www/common/mynamespace/modules testmodule controllers DefaultController.php views default index.php TestmoduleModule.php ~~~ `index.php` é mesma visão que no modulo normal. `TestmoduleModule.php` e `DefaultController.php` estão com namespace. `TestmoduleModule.php`: ~~~ [php] // define namespace: namespace mynamespace\modules\testmodule; // since class is now under namespace, global namespace // should be referenced explicitly using "\": class TestmoduleModule extends \CWebModule { // setting non-global controllers namespace (also can be done via config) public $controllerNamespace = '\mynamespace\modules\testmodule\controllers'; // usual module code } ~~~ `DefaultController.php`: ~~~ [php] render('index'); } } ~~~ Agora, a única coisa que resta é adicionar o módulo na aplicação. A melhor maneira de fazer isso é especificá-la no arquivo de configuração do aplicativo (`protected/config/main.php`): ~~~ [php] // adding "mynamespace" namespace Yii::setPathOfAlias('mynamespace', '/var/www/common/mynamespace/'); return array( 'basePath'=>dirname(__FILE__).DIRECTORY_SEPARATOR.'..', 'name'=>'My Web Application', 'modules'=>array( 'testmodule' => array( 'class' => '\mynamespace\modules\testmodule\TestModuleModule', ), ), ~~~
$Id$