# Aplicações ¶

Aplicações são objetos que regem a estrutura e ciclo de vida gerais de aplicações em Yii. Cada aplicação contém um único objeto Application que é criado no script de entrada e que pode ser acessado globalmente pela expressão `\Yii::$app`.

> Informação: Dependendo do contexto, quando dizemos "uma aplicação", pode significar tanto um objeto Application quanto um sistema.

Existem dois tipos de aplicações: aplicações Web e aplicações console. Como o próprio nome indica, o primeiro manipula requisições Web enquanto o segundo trata requisições de comandos do console.

## Configurações da Aplicação ¶

Quando um script de entrada cria uma aplicação, ele carregará uma configuração e a aplicará à aplicação, da seguinte forma:

    require __DIR__ . '/../vendor/autoload.php';
    require __DIR__ . '/../vendor/yiisoft/yii2/Yii.php';

    // carrega a configuração da aplicação
    $config = require __DIR__ . '/../config/web.php';

    // instancia e configura a aplicação
    (new yii\web\Application($config))->run();

Tal como configurações normais, as configurações da aplicação especificam como inicializar as propriedades de objetos Application. Uma vez que geralmente são muito complexas, elas normalmente são mantidas em arquivos de configuração, como o arquivo `web.php` no exemplo acima.

## Propriedades da Aplicação ¶

Existem muitas propriedades importantes da aplicação que deveriam ser configuradas. Essas propriedades tipicamente descrevem o ambiente em que as aplicaçõe estão rodando. Por exemplo, as aplicações precisam saber como carregar os controllers, onde armazenar os arquivos temporários, etc. A seguir resumiremos essas propriedades.

### Propriedades Obrigatórias ¶

Em qualquer aplicação, você deve pelo menos configurar duas propriedades: id e basePath.

#### id ¶

A propriedade id especifica um ID único que diferencia uma aplicação das outras. É usado principalmente programaticamente. Apesar de não ser obrigatório, para melhor interoperabilidade recomenda-se que você só use caracteres alfanuméricos ao especificar um ID de aplicação.

#### basePath ¶

A propriedade basePath especifica o diretório raiz de um sistema. É o diretório que contém todo o código fonte protegido de um sistema. Sob este diretório, você normalmente verá subdiretórios tais como `models`, `views` e `controllers`, que contém o código fonte correspondente ao padrão MVC.

Você pode configurar a propriedade basePath usando um alias de caminho. Em ambas as formas, o diretório correspondente precisa existir, doutra forma será lançada uma exceção. O caminho será normnalizado chamando-se a função `realpath()`.

A propriedade basePath frequentemente é usada para derivar outros caminhos importantes (por exemplo, o diretório de runtime). Por esse motivo, um alias de caminho `@app` é pré-definido para representar esse caminho. Assim os caminhos derivados podem ser formados usando esse alias (por exemplo, `@app/runtime` para referenciar o diretório runtime).

### Propriedades Importantes ¶

As propriedades descritas nesta subseção frequentemente precisam ser configuradas porque elas variam em diferentes aplicações.

#### aliases ¶

Esta propriedade permite que você defina um conjunto de aliases em termos de um array. As chaves do array representam os nomes de alias, e os valores são as definições correspondentes. Por exemplo:

    [
        'aliases' => [
            '@name1' => 'path/to/path1',
            '@name2' => 'path/to/path2',
        ],
    ]

Esta propriedade é fornecida para que você possa definir aliases na configuração da aplicação ao invés de chamar o método Yii::setAlias().

#### bootstrap ¶

Esta é uma propriedade muito útil. Ela permite que você especifique um array de componentes que devem ser executados durante o processo de inicialização da aplicação. Por exemplo, se você quer que um módulo personalize as regras de URL, você pode listar seu ID como um elemento nesta propriedade.

Cada componente listado nesta propriedade deve ser especificado em um dos seguintes formatos:

- o ID de um componente de aplicação conforme especifcado via components.
- o ID de um módulo conforme especificado via modules.
- o nome de uma classe.
- um array de configuração.
- uma função anônima que cria e retorna um componente.

Por exemplo:

    [
        'bootstrap' => [
            // o ID de uma aplicação ou de um módulo
            'demo',

            // um nome de classe
            'app\components\Profiler',

            // um array de configuração
            [
                'class' => 'app\components\Profiler',
                'level' => 3,
            ],

            // uma função anônima
            function () {
                return new app\components\Profiler();
            }
        ],
    ]

> Informação: Se o ID de um módulo é o mesmo que o ID de um componente da aplicação, o componente será usado durante o processo de inicialização. Se você quiser usar o módulo ao invés dele, você pode especificá-lo usando uma função anônima conforme a seguir: ```php [

>     function () {
>         return Yii::$app->getModule('user');
>     },

> ] ```

Durante o processo de inicialização, cada componente será instanciado. Se a classe do componente implementa yii\base\BootstrapInterface, seu método bootstrap() também será chamado.

Outro exemplo prático está na configuração do Template Básico de Projetos, onde os módulos `debug` e `gii` estão configurados como componentes de inicialização quando a aplicação está rodando no ambiente de desenvolvimento:

    if (YII_ENV_DEV) {
        // ajustes da configuração para o ambiente 'dev'
        $config['bootstrap'][] = 'debug';
        $config['modules']['debug'] = 'yii\debug\Module';

        $config['bootstrap'][] = 'gii';
        $config['modules']['gii'] = 'yii\gii\Module';
    }

> Observação: Colocar componentes demais em `bootstrap` degradará o desempenho de sua aplicação, porque para cada requisição o mesmo conjunto de componentes precisará ser carregado. Desta forma, use os componentes de inicialização com juízo.

#### catchAll ¶

Essa propriedade só é suportada por aplicações Web. Ela especifica uma action de um controller que deve manipular todas as requisições. Isso é geralmente usado quando a aplicação está em modo de manutenção e precisa tratar todas as requisições através de uma única action.

A configuração é um array, cujo primeiro elemento especifica a rota para a action. O restante dos elementos do array (pares de chave-valor) especificam os parâmetros que devem ser atrelados à action. Por exemplo:

    [
        'catchAll' => [
            'offline/notice',
            'param1' => 'value1',
            'param2' => 'value2',
        ],
    ]

#### components ¶

Essa é a propriedade mais importante. Ela permite que você registre uma lista de componentes chamados componentes de aplicação que você pode usar em outros lugares. Por exemplo:

    [
        'components' => [
            'cache' => [
                'class' => 'yii\caching\FileCache',
            ],
            'user' => [
                'identityClass' => 'app\models\User',
                'enableAutoLogin' => true,
            ],
        ],
    ]

Cada componente da aplicação é especiifcado como um par de chave-valor em um array. A chave representa o ID do componente, enquanto o valor representa o nome ou a configuração da classe do componente.

Você pode registrar qualquer componente com uma aplicação, e o componente depois poderá ser acessado globalmente através da expressão `\Yii::$app->IDdoComponente`.

Por favor leia a seção Componentes de Aplicação para mais detalhes.

#### controllerMap ¶

Essa propriedade permite que você mapeie um ID de um controller a uma classe de controller arbitrária. Por padrão, o Yii mapeia os IDs de controllers a classes de controllers baseado em uma convenção (por exemplo, o ID `post` será mapeado para `app\controllers\PostController`). Ao configurar essa propriedade, você pode quebrar a convenção de controllers em específico. No exemplo a seguir, `account` será meapeado para `app\controllers\UserController`, enquanto `article` será mapeado para `app\controllers\PostController`.

    [
        'controllerMap' => [
            'account' => 'app\controllers\UserController',
            'article' => [
                'class' => 'app\controllers\PostController',
                'enableCsrfValidation' => false,
            ],
        ],
    ]

As chaves do array dessa propriedade representam os IDs dos controllers, enquanto os valores do array representam o nome ou as configurações da classe do controller.

#### controllerNamespace ¶

Essa propriedade especifica o namespace padrão sob o qual as classes dos controllers deverão ser localizadas. Seu valor padrão é `app\controllers`. Se um ID de um controller for `post`, por convenção o nome da classe de controller correspondente (sem namespace) seria `PostController`, e o nome da classe completo e qualificado seria `app\controllers\PostController`.

As classes de controllers também podem estar localizadas em subdiretórios do diretório correspondente ao namespace. Por exemplo, dado um ID de controller `admin/post`, a classe completa e qualificada correspondente seria `app\controllers\admin\PostController`.

É importante que as classes completas e qualificadas possam ser carregadas automaticamente e que o namespace das suas classes de controller correspondam ao valor dessa propriedade. Doutra forma, você receberia um erro de "Página Não Encontrada" ao acessar a aplicação.

Caso você queira quebrar a convenção conforme descrito acima, você pode configurar a propriedade controllerMap.

#### language ¶

Essa propriedade especifica o idioma no qual a aplicação deve exibir o conteúdo aos usuários finais. O valor padrão dessa propriedade é `en`, significando inglês. Você deve configurar essa propriedade se a sua aplicação suportar múltiplos idiomas.

O valor dessa propriedade determina vários aspectos da internacionalização, incluindo tradução de mensagens, formato de datas, formato de números, etc. Por exemplo, o widget yii\jui\DatePicker usará o valor dessa propriedade por padrão para determinar em qual idioma o calendário deverá ser exibido e como a data deve ser formatada.

Recomenda-se que você especifique um idioma em termos de um código de idioma IETF. Por exenplo, `en` corresponde ao inglês, enquanto `en-US` significa inglês dos Estados Unidos.

Mais detalhes sobre essa propriedade podem ser encontrados na seção Internacionalização.

#### modules ¶

Essa propriedade especifica os módulos que uma aplicação contém.

A propriedade recebe um array de classes de módulos ou configurações com as chaves do array sendo os IDs dos módulos. Por exemplo:

    [
        'modules' => [
            // um módulo "booking" especificado com a classe do módulo
            'booking' => 'app\modules\booking\BookingModule',

            // um módulo "comment" especificado com um array de configurações
            'comment' => [
                'class' => 'app\modules\comment\CommentModule',
                'db' => 'db',
            ],
        ],
    ]

Por favor consulte a seção Módulos para mais detalhes.

#### name ¶

Essa propriedade especifica o nome da aplicação que pode ser exibido aos usuários finais. Ao contrário da propriedade id que deveria receber um valor único, o valor desta propriedade serve principalmente para fins de exibição e não precisa ser único.

Você nem sempre precisa configurar essa propriedade se nenhuma parte do código a estiver usando.

#### params ¶

Essa propriedade especifica um array de parâmetros da aplicação que podem ser acessados globalmente. Ao invés de usar números e strings fixos espalhados por toda parte no seu código, é uma boa prática defini-los como parâmetros da aplicação em um único lugar e usá-los nos lugares onde for necessário. Por exemplo, você pode definir o tamanho de uma miniatura de imagem como um parâmetro conforme a seguir:

    [
        'params' => [
            'thumbnail.size' => [128, 128],
        ],
    ]

Então no seu código onde você precisar usar o valor do tamanho, você pode simplesmente usar o código conforme a seguir:

    $size = \Yii::$app->params['thumbnail.size'];
    $width = \Yii::$app->params['thumbnail.size'][0];

Mais tarde, se você decidir mudar o tamanho da miniatura, você só precisa modificá-lo na configuração da aplicação sem tocar em quaisquer códigos dependentes.

#### sourceLanguage ¶

Essa propriedade especifica o idioma no qual o código da aplicação foi escrito. O valor padrão é `'en-US'`, significando inglês dos Estados Unidos. Você deve configurar essa propriedade se o conteúdo do texto no seu código não estiver em inglês.

Conforme a propriedade language, você deve configurar essa propriedade em termos de um código de idioma IETF. Por exemplo, `en` corresponde ao inglês, enquanto `en-US` significa inglês dos Estados Unidos.

Mais detalhes sobre essa propriedade podem ser encontrados na seção Internacionalização.

#### timeZone ¶

Essa propriedade é disponibilizada como uma maneira alternativa de definir a timezone do PHP em tempo de execução. Ao confiugrar essa propriedade, você está essencialmente chamando a função date_default_timezone_set() do PHP. Por exemplo:

    [
        'timeZone' => 'America/Los_Angeles',
    ]

#### version ¶

Essa propriedade especifica a versão da aplicação. Seu valor padrão é `'1.0'`. Você não precisa configurar esta propriedade se nenhuma parte do seu código estiver utilizando-a.

### Propriedades Úteis ¶

As propriedades descritas nesta subseção não são comumente configuradas porque seus valores padrão estipulam convenções comuns. No entanto, você pode ainda configurá-las no caso de querer quebrar as convenções.

#### charset ¶

Essa propriedade especifica o charset que a aplicação usa. O valor padrão é `'UTF-8'`, que deveria ser mantido como está para a maioria das aplicações, a menos que você esteja trabalhando com sistemas legados que usam muitos dados que não são unicode.

#### defaultRoute ¶

Essa propriedade especifica a rota que uma aplicação deveria usar quando uma requisição não especifica uma. A rota pode consistir de um ID de módulo, ID de controller e/ou ID de action. Por exemplo, `help`, `post/create`, `admin/post/create`. Se não for passado um ID de action, ele assumirá o valor conforme especificado em yii\base\Controller::$defaultAction.

Para aplicações Web, o valor padrão dessa propriedade é `'site'`, o que significa que deve usar o controller `SiteController` e sua action padrão. Como resultado disso, se você acessar a aplicação sem especificar uma rota, ele exibirá o resultado de `app\controllers\SiteController::actionIndex()`.

Para aplicações do console, o valor padrão é `'help'`, o que significado que deve usar o comando do core yii\console\controllers\HelpController::actionIndex(). Como resultado, se você executar o comando `yii` sem fornecer quaisquer argumentos, ele exibirá a informação de ajuda.

#### extensions ¶

Essa propriedade especifica a lista de extensões que estão instaladas e são usadas pela aplicação. Por padrão, ela receberá o array retornado pelo arquivo `@vendor/yiisoft/extensions.php`. O arquivo `extensions.php` é gerado e mantido automaticamente quando você usa o Composer para instalar extensões. Então na maioria dos casos você não precisa configurar essa propriedade.

No caso especial de você querer manter extensões manualmente, você pode configurar essa propriedade da seguinte forma:

    [
        'extensions' => [
            [
                'name' => 'extension name',
                'version' => 'version number',
                'bootstrap' => 'BootstrapClassName',  // opcional, também pode ser um array de configuração
                'alias' => [  // opcional
                    '@alias1' => 'to/path1',
                    '@alias2' => 'to/path2',
                ],
            ],

            // ... mais extensões conforme acima ...

        ],
    ]

Como você pode ver, a propriedade recebe um array de especificações de extensões. Cada extensão é especificada com um array composto pelos elementos `name` e `version`. Se uma extensão precisa executar durante o processo de inicialização, um elemento `bootstrap` pode ser especificado com um nome de uma classe de inicialização ou um array de configuração. Uma extensão também pode definir alguns aliases.

#### layout ¶

Essa propriedade especifica o nome do layout padrão que deverá ser usado ao renderizar uma view. O valor padrão é `'main'`, significando que o arquivo de layout `main.php` sob o caminho dos layouts deverá ser usado. Se tanto o caminho do layout quanto o caminho da view estiverem recebendo os valores padrão, o arquivo de layout padrão pode ser representado como o alias de caminho `@app/views/layouts/main.php`.

Você pode configurar esta propriedade como `false` se você quiser desativar o layout por padrão, embora isso seja muito raro.

#### layoutPath ¶

Essa propriedade especifica o caminho onde os arquivos de layout devem ser procurados. O valor padrão é o subdiretório `layouts` dentro do diretório do caminho das views. Se o caminho das views estiver recebendo seu valor padrão, o caminho padrão dos layouts pode ser representado como o alias de caminho `@app/views/layouts`.

Você pode configurá-la como um diretório ou um alias de caminho.

#### runtimePath ¶

Essa propriedade especifica o caminho onde os arquivos temporários, tais como arquivos de log e de cache, podem ser gerados. O valor padrão é o diretório representado pelo alias `@app/runtime`.

Você pode configurá-la como um diretório ou alias de caminho. Perceba que o caminho de runtime precisa ter permissão de escrita para o processo que executa a aplicação. E o caminho deveria ser protegido para não ser acessado pelos usuários finais, porque os arquivos temporários dentro dele podem conter informações sensíveis.

Para simplificar o acesso a esse caminho, o Yii possui um alias de caminho pré-definido chamado `@runtime` para ele.

#### viewPath ¶

Essa propriedade especifica o diretório raiz onde os arquivos de views estão localizados. O valor padrão do diretório é representado pelo alias `@app/views`. Você pode configurá-lo como um diretório ou alias de caminho.

#### vendorPath ¶

Essa propriedade especifica o diretório vendor gerenciado pelo Composer. Ele contém todas as bibliotecas de terceiros usadas pela sua aplicação, incluindo o framework do Yii. O valor padrão é o diretório representado pelo alias `@app/vendor`.

Você pode configurar essa propriedade como um diretório ou alias de caminho. Quando você modificar essa propriedade, assegure-se de ajustar a configuração do Composer de acordo.

Para simplificar o acesso a esse caminho, o Yii tem um alias de caminho pré-definido para ele chamado de `@vendor`.

#### enableCoreCommands ¶

Essa propriedade só é suportada por aplicações do console. Ela especifica se os comandos do core inclusos no pacote do Yii devem estar ativos. O valor padrão é `true`.

## Eventos da Aplicação ¶

Uma aplicação dispara muitos eventos durante o ciclo de vida de manipulação de uma requisição. Você pode vincular manipuladores a esses eventos nas configurações da aplicação do seguinte modo,

    [
        'on beforeRequest' => function ($event) {
            // ...
        },
    ]

A sintaxe de uso de `on eventName` é descrita na seção Configurações.

Alternativamente, você pode vincular manipuladores de evento durante o processo de inicialização após a instância da aplicação ser criada. Por exemplo:

    \Yii::$app->on(\yii\base\Application::EVENT_BEFORE_REQUEST, function ($event) {
        // ...
    });

### EVENT_BEFORE_REQUEST ¶

Este evento é disparado antes de uma aplicação manipular uma requisição. O nome do evento é `beforeRequest`.

Quando esse evento é disparado, a instância da aplicação foi configurada e inicializada. Então é um bom lugar para inserir código personalizado por meio do mecanismo de eventos para interceptar o processo de tratamento da requisição. Por exemplo, no manipulador de eventos, você pode definir dinamicamente a propriedade yii\base\Application::$language baseado em alguns parâmetros.

### EVENT_AFTER_REQUEST ¶

Este evento é disparado depois que uma aplicação finaliza o tratamento da requisição, mas antes de enviar a resposta. O nome do evento é `afterRequest`.

Quando este evento é disparado, o tratamento da requisição está completo e você pode aproveitar essa ocasião para fazer um pós-processamento da requisição ou personalizar a resposta.

Perceba que o componente response também dispara alguns eventos enquanto está enviando conteúdo de resposta para os usuários finais. Esses eventos são disparados depois deste evento.

### EVENT_BEFORE_ACTION ¶

Este evento é disparado antes de executar cada action de controller. O nome do evento é `beforeAction`.

O parâmetro do evento é uma instância de yii\base\ActionEvent. Um manipulador de evento pode definir o valor da propriedade yii\base\ActionEvent::$isValid como `false` para interromper a execução da action. Por exemplo:

    [
        'on beforeAction' => function ($event) {
            if (alguma condição$event->isValid = false;
            } else {
            }
        },
    ]

Perceba que o mesmo evento `beforeAction` também é disparado pelos módulos e controllers. Os objetos Application são os primeiros a disparar este evento, seguidos pelos módulos (se houver algum) e finalmente pelos controllers. Se um manipulador de evento definir yii\base\ActionEvent::$isValid como `false`, todos os eventos seguintes NÃO serão disparados.

### EVENT_AFTER_ACTION ¶

Este evento é disparado depois de executar cada action de controller. O nome do evento é `afterAction`.

O parâmetro do evento é uma instância de yii\base\ActionEvent. Através da propriedade yii\base\ActionEvent::$result, um manipulador de evento pode acessar ou modificar o resultado da action. Por exemplo:

    [
        'on afterAction' => function ($event) {
            if (alguma condição// modifica $event->result
            } else {
            }
        },
    ]

Perceba que o mesmo evento `afterAction` também é disparado pelos módulos e controllers. Estes objetos disparam esse evento na order inversa da do `beforeAction`. Ou seja, os controllers são os primeiros objetos a disparar este evento, seguidos pelos módulos (se houver algum) e finalmente pelos objetos Application.

## Ciclo de Vida da Aplicação ¶

Quando um script de entrada estiver sendo executado para manipular uma requisição, uma aplicação passará pelo seguinte ciclo de vida:

1. O script de entrada carrega a configuração da aplicação como um array.
2. O script de entrada cria uma nova instância da aplicação:
   - preInit() é chamado, que configura algumas propriedades da aplicação de alta prioridade, tais como basePath.
   - Registra o manipulador de erros.
   - Configura as propriedades da aplicação.
   - init() é chamado, que por sua vez chama bootstrap() para rodar os componentes de inicialização.
3. O script de entrada chama yii\base\Application::run() para executar a aplicação:
   - Dispara o evento EVENT_BEFORE_REQUEST.
   - Trata a requisição: resolve a requisição em uma rota e os parâmetros associados; cria os objetos do módulo, do controller e da action conforme especificado pela rota; e executa a action.
   - Dispara o evento EVENT_AFTER_REQUEST.
   - Envia a resposta para o usuário final.
4. O script de entrada recebe o status de saída da aplicação e completa o processamento da requisição.