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.

1. 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;
  • application: refere-se ao diretório base da aplicação;
  • webroot: refere-se ao diretório que contém o arquivo do script de entrada.
  • ext: refere-se ao diretório que contém todas as extensões de terceiros.

Além disso, se a aplicação utiliza módulos, 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.

2. 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:

Yii::import('system.web.CController');

O método 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.

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():

Yii::$classMap=array(
    'ClassName1' => 'path/to/ClassName1.php',
    'ClassName2' => 'path/to/ClassName2.php',
    ......
);

3. 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.

Yii::import('system.web.*');

Além do método 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.

4. 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.

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.

5. 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:

Yii::setPathOfAlias('mynamespace', '/var/www/common/mynamespace/');

6. 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:

// 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.

7. 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:

// 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
 
// define namespace:
namespace mynamespace\modules\testmodule\controllers;
 
// since class is now under namespace, global namespace
// should be referenced explicitly using "\":
class DefaultController extends \Controller
{
    public function actionIndex()
    {
        $this->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):

// 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$

Be the first person to leave a comment

Please to leave your comment.