# Technical Documentation: yiisoft/yii2

> ℹ️ **Provenance:** Multi-Tier Ingestion · [CodeWiki Reference](https://codewiki.google/github.com/yiisoft/yii2)

### Overview (`README.md`)

<p align="center">
    <a href="https://www.yiiframework.com/" target="_blank">
        <picture>
            <source media="(prefers-color-scheme: dark)" srcset="https://www.yiiframework.com/image/design/logo/yii3_full_for_dark.svg">
            <source media="(prefers-color-scheme: light)" srcset="https://www.yiiframework.com/image/design/logo/yii3_full_for_light.svg">
            <img src="https://www.yiiframework.com/image/design/logo/yii3_full_for_light.svg" alt="Yii Framework" height="100">
        </picture>
    </a>
</p>

Yii 2 is a modern framework designed to be a solid foundation for your PHP application.

It is fast, secure and efficient and works right out of the box pre-configured with reasonable defaults.
The framework is easy to adjust to meet your needs, because Yii has been designed to be flexible.

[](https://packagist.org/packages/yiisoft/yii2)
[](https://packagist.org/packages/yiisoft/yii2)
[](https://github.com/yiisoft/yii2/actions/workflows/build.yml)
[](https://github.com/yiisoft/yii2/actions/workflows/static.yml)
[](https://codecov.io/gh/yiisoft/yii2)

Installation
------------

> [!IMPORTANT]
> - The minimum required [PHP](https://www.php.net/) version of Yii is PHP `7.4`.
> - It works best with PHP `8`.

- [Follow the Definitive Guide](https://www.yiiframework.com/doc-2.0/guide-start-installation.html)
in order to get step by step instructions.

Documentation
-------------

- A [Definitive Guide](https://www.yiiframework.com/doc/guide/2.0) and 
a [Class Reference](https://www.yiiframework.com/doc/api/2.0) cover every detail
of the framework.
- There is a [PDF version](https://www.yiiframework.com/doc/download/yii-guide-2.0-en.pdf) of the Definitive Guide
and a [Definitive Guide Mirror](http://stuff.cebe.cc/yii2docs/) which is updated every 15 minutes.
- For Yii 1.1 users, there is [Upgrading from Yii 1.1](https://www.yiiframework.com/doc/guide/2.0/en/intro-upgrade-from-v1)
to get an idea of what has changed in 2.0.

Versions & PHP compatibility
----------------------------

> [!NOTE]
> See ["Release Cycle" at the website](https://www.yiiframework.com/release-cycle) for detailed information about supported versions.

Community
---------

- Participate in [discussions at forums](https://www.yiiframework.com/forum/).
- [Community Slack](https://join.slack.com/t/yii/shared_invite/MjIxMjMxMTk5MTU1LTE1MDE3MDAwMzMtM2VkMTMyMjY1Ng) and [Chat in IRC](https://www.yiiframework.com/chat/).
- Follow us on [Facebook](https://www.facebook.com/groups/yiitalk/), [Twitter](https://twitter.com/yiiframework)
and [GitHub](https://github.com/yiisoft/yii2).
- Check [other communities](https://github.com/yiisoft/yii2/wiki/communities).

Contributing
------------

The framework is [Open Source](LICENSE.md) powered by [an excellent community](https://github.com/yiisoft/yii2/graphs/contributors).

You may join us and:

- [Report an issue](docs/internals/report-an-issue.md)
- [Translate documentation or messages](docs/internals/translation-workflow.md)
- [Give us feedback or start a design discussion](https://www.yiiframework.com/forum/index.php/forum/42-general-discussions-for-yii-20/)
- [Contribute to the core code or fix bugs](docs/internals/git-workflow.md)
- [Become a sponsor](#sponsoring)

### Reporting Security issues

> [!WARNING]
> Please do not report security vulnerabilities through public GitHub issues.

Please refer to a [special page at the website](https://www.yiiframework.com/security/)
describing proper workflow for security issue reports.

### Directory Structure

```
build/               internally used build tools
docs/                documentation
framework/           core framework code
tests/               tests of the core framework code
```

### Spreading the Word

Acknowledging or citing Yii 2 is as important as direct contributions.

**In presentations**

If you are giving a presentation or talk featuring work that makes use of Yii 2 and would like to acknowledge it,
we suggest using [our logo](https://www.yiiframework.com/logo/) on your title slide.

**In projects**

If you are using Yii 2 as part of an OpenSource project, a way to acknowledge it is to
[use a special badge](https://img.shields.io/badge/Powered_by-Yii_Framework-green.svg?style=for-the-badge&logo=yii) in your README:    

[](https://www.yiiframework.com/)

If your code is hosted at GitHub, you can place the following in your README.md file to get the badge:

```
[](https://www.yiiframework.com/)
```

### Security

[](https://github.com/yiisoft/yii2/actions/workflows/zizmor.yml)
[](https://scorecard.dev/viewer/?uri=github.com/yiisoft/yii2)

GitHub Actions workflows are analyzed by [zizmor](https://github.com/yiisoft/yii2/actions/workflows/zizmor.yml) for supply-chain vulnerabilities and workflow misconfigurations.
Supply-chain security is tracked via the [OpenSSF Scorecard](https://scorecard.dev/viewer/?uri=github.com/yiisoft/yii2), which evaluates security practices across the repository.

### Sponsoring

Support this project by becoming a sponsor or a backer. 

[](https://opencollective.com/yiisoft) 
[](https://opencollective.com/yiisoft)

---

### Overview (`framework/README.md`)

Yii PHP Framework Version 2
===========================

This is the core framework code of [Yii 2](https://github.com/yiisoft/yii2#readme).

This repository is a read-only git subsplit of <https://github.com/yiisoft/yii2>.
Please submit issue reports and pull requests to the main repository.
For license information check the [LICENSE](LICENSE.md)-file.

Installation
------------

The preferred way to install the Yii framework is through [composer](https://getcomposer.org/download/).

Refer to [Bower and NPM Assets installation](https://www.yiiframework.com/doc/guide/2.0/en/structure-assets#bower-npm-assets) to select an asset installation method.

Either run

```
composer require yiisoft/yii2
```

or add

```json
"yiisoft/yii2": "~2.0.0",
```

to the require section of your composer.json.

---

### Overview (`tests/README.md`)

# Yii 2.0 Unit tests

## DIRECTORY STRUCTURE

    data/            models, config and other test data
        config.php   this file contains configuration for database and caching backends
    framework/       the framework unit tests
    runtime/         the application runtime dir for the yii test app

## HOW TO RUN THE TESTS

Make sure you have PHPUnit installed and that you installed all composer dependencies (run `composer update` in the repo base directory).

Run PHPUnit in the yii repo base directory.

```
phpunit
```

You can run tests for specific groups only:

```
phpunit --group=mysql,base,i18n
```

You can get a list of available groups via `phpunit --list-groups`.

A single test class could be run like the following:

```
phpunit tests/framework/base/ObjectTest.php
```

## TEST CONFIGURATION

PHPUnit configuration is in `phpunit.xml.dist` in repository root folder.
You can create your own phpunit.xml to override dist config.

Database and other backend system configuration can be found in `tests/data/config.php`
adjust them to your needs to allow testing databases and caching in your environment.
You can override configuration values by creating a `config.local.php` file
and manipulate the `$config` variable.
For example to change MySQL username and password your `config.local.php` should
contain the following:

```php
<?php
$config['databases']['mysql']['username'] = 'yiitest';
$config['databases']['mysql']['password'] = 'changeme';
```

## DOCKERIZED TESTING

Get started by going to the `tests` directory and copy the environment configuration.

```bash
cd tests
cp .env-dist .env
```

The newly created `.env` file defines the configuration files used by `docker-compose`. By default MySQL, Postgres etc. services are disabled.

> You can choose services available for testing by merging `docker-compose.[...].yml` files in `.env`. For example, if you only want to test with MySQL, you can modify the `COMPOSE_FILE` variable as follows:

```env
COMPOSE_FILE=docker-compose.yml:docker-compose.mysql.yml
```

> Note: The files `docker-compose.caching.yml` and `docker-compose.mssql.yml` cannot be merged with `docker-compose.yml`.

### Running tests via shell script

You need to go to the `tests` directory and run the `test-local.sh` script. The first argument can be: `default`, `caching`, `mssql`, `pgsql`, `mysql`. You can pass additional arguments to this script to control the behavior of PHPUnit. For example:

```bash
cd tests
sh test-local.sh default --exclude caching,db
```

### Manually running the tests

You can also run tests manually. To do this, you need to start the container and run the tests. For example:

```bash
docker compose up -d
docker compose exec php vendor/bin/phpunit -v
```

### Oracle tests

> [!IMPORTANT]
> Oracle tests require `oci8` and `pdo_oci` PHP extensions installed locally. The `docker-compose.oracle.yml` only starts the Oracle database container; PHPUnit runs on the host.

Start the Oracle container and run the tests manually:

```bash
cd tests
COMPOSE_FILE=docker-compose.oracle.yml docker compose up -d --wait
cd ..
vendor/bin/phpunit -v --group oci
cd tests
COMPOSE_FILE=docker-compose.oracle.yml docker compose down -v
```

---

### Overview (`docs/guide-ar/README.md`)

Yii 2.0 الدليل التقني الخاص ببيئة العمل
===============================

تم تحرير هذا الملف اعتمادا على [الشروط الخاصة بتوثيف ال Yii](https://www.yiiframework.com/doc/terms/).

جميع الحقوق محفوظة

2014 (c) Yii Software LLC.


المقدمة
------------

* [عن بيئة العمل Yii](intro-yii.md)
* [التحديث من الإصدار 1.1](../guide/intro-upgrade-from-v1.md)


البداية من هنا
---------------

* [ماذا يجب أن تعرف عن بيئة العمل](start-prerequisites.md)
* [تثبيت ال Yii](start-installation.md)
* [تشغيل التطبيقات - Running Applications](start-workflow.md)
* [قل مرحبا - المشروع الأول](start-hello.md)
* [التعامل مع ال forms](start-forms.md)
* [التعامل مع قواعد البيانات](start-databases.md)
* [إنشاء الشيفرة البرمجية من خلال ال gii](start-gii.md)
* [ماذا الآن - الخطوة القادمة](start-looking-ahead.md)


الهيكلية الخاصة بالتطبيق (Application Structure)
---------------------

* [نظرة عامة عن الهيكلية الخاصة بالتطبيق](../guide/structure-overview.md)
* [Entry Scripts](../guide/structure-entry-scripts.md)
* [التطبيقات](../guide/structure-applications.md)
* [مكونات التطبيقات](../guide/structure-application-components.md)
* [Controllers](../guide/structure-controllers.md)
* [Models](../guide/structure-models.md)
* [Views](../guide/structure-views.md)
* [Modules](../guide/structure-modules.md)
* [Filters](../guide/structure-filters.md)
* [Widgets](../guide/structure-widgets.md)
* [Assets](../guide/structure-assets.md)
* [Extensions](../guide/structure-extensions.md)


التعامل مع ال requests
-----------------

* [نظرة عامة عن التعامل مع ال requests](../guide/runtime-overview.md)
* [Bootstrapping](../guide/runtime-bootstrapping.md)
* [Routing and URL Creation](../guide/runtime-routing.md)
* [Requests](../guide/runtime-requests.md)
* [Responses](../guide/runtime-responses.md)
* [Sessions and Cookies](../guide/runtime-sessions-cookies.md)
* [Handling Errors - التحكم بالأخطاء](../guide/runtime-handling-errors.md)
* [Logging - تسجيل الحركات](../guide/runtime-logging.md)


المفاهيم الرئيسية (Key Concepts)
------------

* [Components](../guide/concept-components.md)
* [Properties](../guide/concept-properties.md)
* [Events](../guide/concept-events.md)
* [Behaviors](../guide/concept-behaviors.md)
* [Configurations](../guide/concept-configurations.md)
* [Aliases](../guide/concept-aliases.md)
* [Class Autoloading](../guide/concept-autoloading.md)
* [Service Locator](../guide/concept-service-locator.md)
* [Dependency Injection Container](../guide/concept-di-container.md)


التعامل مع قواعد البيانات
----------------------

* [Database Access Objects](../guide/db-dao.md): Connecting to a database, basic queries, transactions, and schema manipulation
* [Query Builder](../guide/db-query-builder.md): Querying the database using a simple abstraction layer
* [Active Record](../guide/db-active-record.md): The Active Record ORM, retrieving and manipulating records, and defining relations
* [Migrations](../guide/db-migrations.md): Apply version control to your databases in a team development environment
* [Sphinx](https://www.yiiframework.com/extension/yiisoft/yii2-sphinx/doc/guide)
* [Redis](https://www.yiiframework.com/extension/yiisoft/yii2-redis/doc/guide)
* [MongoDB](https://www.yiiframework.com/extension/yiisoft/yii2-mongodb/doc/guide)
* [ElasticSearch](https://www.yiiframework.com/extension/yiisoft/yii2-elasticsearch/doc/guide)


الحصول على البيانات من خلال المستخدمين
-----------------------

* [Creating Forms](../guide/input-forms.md)
* [Validating Input](../guide/input-validation.md)
* [Uploading Files](../guide/input-file-upload.md)
* [Collecting Tabular Input](../guide/input-tabular-input.md)
* [Getting Data for Multiple Models](../guide/input-multiple-models.md)
* [Extending ActiveForm on the Client Side](../guide/input-form-javascript.md)


عرض البيانات
---------------

* [Data Formatting](../guide/output-formatting.md)
* [Pagination](../guide/output-pagination.md)
* [Sorting](../guide/output-sorting.md)
* [Data Providers](../guide/output-data-providers.md)
* [Data Widgets](../guide/output-data-widgets.md)
* [Working with Client Scripts](../guide/output-client-scripts.md)
* [Theming](../guide/output-theming.md)


الامان والحماية
--------

* [Security Overview](../guide/security-overview.md)
* [Authentication](../guide/security-authentication.md)
* [Authorization](../guide/security-authorization.md)
* [Working with Passwords](../guide/security-passwords.md)
* [Cryptography](../guide/security-cryptography.md)
* [Auth Clients](https://www.yiiframework.com/extension/yiisoft/yii2-authclient/doc/guide)
* [Best Practices](../guide/security-best-practices.md)


Caching التخزين المؤقت
-------

* [Caching Overview](../guide/caching-overview.md)
* [Data Caching](../guide/caching-data.md)
* [Fragment Caching](../guide/caching-fragment.md)
* [Page Caching](../guide/caching-page.md)
* [HTTP Caching](../guide/caching-http.md)


RESTful Web Services
--------------------

* [Quick Start](../guide/rest-quick-start.md)
* [Resources](../guide/rest-resources.md)
* [Controllers](../guide/rest-controllers.md)
* [Routing](../guide/rest-routing.md)
* [Response Formatting](../guide/rest-response-formatting.md)
* [Authentication](../guide/rest-authentication.md)
* [Rate Limiting](../guide/rest-rate-limiting.md)
* [Versioning](../guide/rest-versioning.md)
* [Error Handling](../guide/rest-error-handling.md)


الأدوات المساعدة أثناء تطوير التطبيقات
-----------------

* [Debug Toolbar and Debugger](https://www.yiiframework.com/extension/yiisoft/yii2-debug/doc/guide)
* [Generating Code using Gii](https://www.yiiframework.com/extension/yiisoft/yii2-gii/doc/guide)
* [Generating API Documentation](https://www.yiiframework.com/extension/yiisoft/yii2-apidoc)


فحص واختبار التطبيقات
-------

* [Testing Overview](../guide/test-overview.md)
* [Testing environment setup](../guide/test-environment-setup.md)
* [Unit Tests](../guide/test-unit.md)
* [Functional Tests](../guide/test-functional.md)
* [Acceptance Tests](../guide/test-acceptance.md)
* [Fixtures](../guide/test-fixtures.md)


مواضيع وعناوين مميزة
--------------

* [Advanced Project Template](https://www.yiiframework.com/extension/yiisoft/yii2-app-advanced/doc/guide)
* [Building Application from Scratch](../guide/tutorial-start-from-scratch.md)
* [Console Commands](../guide/tutorial-console.md)
* [Core Validators](../guide/tutorial-core-validators.md)
* [Docker](../guide/tutorial-docker.md)
* [Internationalization](../guide/tutorial-i18n.md)
* [Mailing](../guide/tutorial-mailing.md)
* [Performance Tuning](../guide/tutorial-performance-tuning.md)
* [Shared Hosting Environment](../guide/tutorial-shared-hosting.md)
* [Template Engines](../guide/tutorial-template-engines.md)
* [Working with Third-Party Code](../guide/tutorial-yii-integration.md)
* [Using Yii as a micro framework](../guide/tutorial-yii-as-micro-framework.md)


Widgets
-------

* [GridView](https://www.yiiframework.com/doc-2.0/yii-grid-gridview.html)
* [ListView](https://www.yiiframework.com/doc-2.0/yii-widgets-listview.html)
* [DetailView](https://www.yiiframework.com/doc-2.0/yii-widgets-detailview.html)
* [ActiveForm](https://www.yiiframework.com/doc-2.0/guide-input-forms.html#activerecord-based-forms-activeform)
* [Pjax](https://www.yiiframework.com/doc-2.0/yii-widgets-pjax.html)
* [Menu](https://www.yiiframework.com/doc-2.0/yii-widgets-menu.html)
* [LinkPager](https://www.yiiframework.com/doc-2.0/yii-widgets-linkpager.html)
* [LinkSorter](https://www.yiiframework.com/doc-2.0/yii-widgets-linksorter.html)
* [Bootstrap Widgets](https://www.yiiframework.com/extension/yiisoft/yii2-bootstrap/doc/guide)
* [jQuery UI Widgets](https://www.yiiframework.com/extension/yiisoft/yii2-jui/doc/guide)


Helpers
-------

* [Helpers Overview](../guide/helper-overview.md)
* [ArrayHelper](../guide/helper-array.md)
* [Html](../guide/helper-html.md)
* [Url](../guide/helper-url.md)

---

### Overview (`docs/guide-de/README.md`)

Das umfassende Handbuch für Yii 2.0
===================================

Dieses Tutorial wurde unter den [Bedingungen der Yii-Dokumentation](https://www.yiiframework.com/doc/terms/) veröffentlicht.

Alle Rechte vorbehalten.

2014 (c) Yii Software LLC.


Einführung
----------

* [Über Yii](intro-yii.md)
* [Upgrade von Version 1.1](intro-upgrade-from-v1.md)


Einstieg
--------

* [Yii installieren](start-installation.md)
* [Running Applications](start-workflow.md)
* [Hallo sagen](start-hello.md)
* [Arbeiten mit Formularen](start-forms.md)
* [Arbeiten mit Datenbanken](start-databases.md)
* [Code generieren mit Gii](start-gii.md)
* [Ausblick](start-looking-ahead.md)


Application Struktur
--------------------

* [Überblick](structure-overview.md)
* [Entry Scripts](structure-entry-scripts.md)
* [Applications](structure-applications.md)
* [Application Komponenten](structure-application-components.md)
* [Controller](structure-controllers.md)
* [Model](structure-models.md)
* [View](structure-views.md)
* **TBD** [Filters](structure-filters.md)
* **TBD** [Widgets](structure-widgets.md)
* **TBD** [Modules](structure-modules.md)
* [Assets](structure-assets.md)
* **TBD** [Extensions](structure-extensions.md)


Anfragen bearbeiten
-------------------

* **TBD** [Bootstrapping](runtime-bootstrapping.md)
* **TBD** [Routing](runtime-routing.md)
* **TBD** [Requests](runtime-requests.md)
* **TBD** [Responses](runtime-responses.md)
* **TBD** [Sessions and Cookies](runtime-sessions-cookies.md)
* [Parsen und Generieren von URLs](runtime-url-handling.md)
* [Fehlerbehandlung](runtime-handling-errors.md)
* [Logging](runtime-logging.md)


Kern-Konzepte
-------------

* [Komponenten](concept-components.md)
* [Eigenschaften](concept-properties.md)
* [Events (Ereignisse)](concept-events.md)
* [Behaviors](concept-behaviors.md)
* [Konfiguration](concept-configurations.md)
* [Aliase](concept-aliases.md)
* [Class Autoloading](concept-autoloading.md)
* [Service Locator](concept-service-locator.md)
* [Dependency Injection Container](concept-di-container.md)


Arbeiten mit Datenbanken
------------------------

* [Data Access Objects](db-dao.md) - Connecting to a database, basic queries, transactions and schema manipulation
* [Query Builder](db-query-builder.md) - Querying the database using a simple abstraction layer
* [Active Record](db-active-record.md) - The active record ORM, retrieving and manipulating records and defining relations
* [Migrations](db-migrations.md) - Version control your databases in a team development environment
* **TBD** [Sphinx](db-sphinx.md)
* **TBD** [Redis](db-redis.md)
* **TBD** [MongoDB](db-mongodb.md)
* **TBD** [ElasticSearch](db-elastic-search.md)


Eingabedaten verarbeiten
------------------------

* [Creating Forms](input-forms.md)
* [Validating Input](input-validation.md)
* **TBD** [Uploading Files](input-file-upload.md)
* **TBD** [Getting Data for Multiple Models](input-multiple-models.md)


Ausgabe von Daten
-----------------

* **TBD** [Data Formatting](output-formatting.md)
* **TBD** [Pagination](output-pagination.md)
* **TBD** [Sorting](output-sorting.md)
* [Data Providers](output-data-providers.md)
* [Data Widgets](output-data-widgets.md)
* [Theming](output-theming.md)


Sicherheit
----------

* [Authentication](security-authentication.md)
* [Authorization](security-authorization.md)
* [Working with Passwords](security-passwords.md)
* **TBD** [Auth Clients](security-auth-clients.md)
* **TBD** [Best Practices](security-best-practices.md)


Caching
-------

* [Overview](caching-overview.md)
* [Data Caching](caching-data.md)
* [Fragment Caching](caching-fragment.md)
* [Page Caching](caching-page.md)
* [HTTP Caching](caching-http.md)


RESTful Web Services
--------------------

* [Quick Start](rest-quick-start.md)
* [Resources](rest-resources.md)
* [Controllers](rest-controllers.md)
* [Routing](rest-routing.md)
* [Response Formatting](rest-response-formatting.md)
* [Authentication](rest-authentication.md)
* [Rate Limiting](rest-rate-limiting.md)
* [Versioning](rest-versioning.md)
* [Error Handling](rest-error-handling.md)


Development Tools
-----------------

* [Debug Toolbar and Debugger](tool-debugger.md)
* [Generating Code using Gii](tool-gii.md)
* **TBD** [Generating API Documentation](tool-api-doc.md)


Testing
-------

* [Overview](test-overview.md)
* **TBD** [Unit Tests](test-unit.md)
* **TBD** [Functional Tests](test-functional.md)
* **TBD** [Acceptance Tests](test-acceptance.md)
* [Fixtures](test-fixtures.md)


Yii erweitern
-------------

* [Creating Extensions](extend-creating-extensions.md)
* [Customizing Core Code](extend-customizing-core.md)
* [Using 3rd-Party Libraries](extend-using-libs.md)
* **TBD** [Using Yii in 3rd-Party Systems](extend-embedding-in-others.md)
* **TBD** [Using Yii 1.1 and 2.0 Together](extend-using-v1-v2.md)
* [Using Composer](extend-using-composer.md)


Weitere Themen
--------------

* [Advanced Application Template](tutorial-advanced-app.md)
* [Building Application from Scratch](tutorial-start-from-scratch.md)
* [Console Commands](tutorial-console.md)
* [Core Validators](tutorial-core-validators.md)
* [Internationalization](tutorial-i18n.md)
* [Mailing](tutorial-mailing.md)
* [Performance Tuning](tutorial-performance-tuning.md)
* **TBD** [Shared Hosting Environment](tutorial-shared-hosting.md)
* [Template Engines](tutorial-template-engines.md)


Widgets
-------

* GridView: link to demo page
* ListView: link to demo page
* DetailView: link to demo page
* ActiveForm: link to demo page
* Pjax: link to demo page
* Menu: link to demo page
* LinkPager: link to demo page
* LinkSorter: link to demo page
* [Bootstrap Widgets](bootstrap-widgets.md)
* [Jquery UI Widgets](jui-widgets.md)


Helfer-Klassen
--------------

* [Overview](helper-overview.md)
* **TBD** [ArrayHelper](helper-array.md)
* **TBD** [Html](helper-html.md)
* **TBD** [Url](helper-url.md)
* **TBD** [Security](helper-security.md)

---

### Overview (`docs/guide-es/README.md`)

Guía Definitiva de Yii 2.0
==========================

Este tutorial se publica bajo los [Términos de Documentación Yii](https://www.yiiframework.com/doc/terms/).

Todos los derechos reservados.

2014 (c) Yii Software LLC.


Introducción
------------

* [Acerca de Yii](intro-yii.md)
* [Actualizar desde Yii 1.1](intro-upgrade-from-v1.md)


Primeros pasos
--------------

* [Qué necesita saber](start-prerequisites.md)
* [Instalar Yii](start-installation.md)
* [Funcionamiento de aplicaciones](start-workflow.md)
* [Hola a todos](start-hello.md)
* [Trabajar con formularios](start-forms.md)
* [Trabajar con bases de datos](start-databases.md)
* [Generar códigos con Gii](start-gii.md)
* [Adentrarse en Yii](start-looking-ahead.md)


Estructura de una aplicación
----------------------------

* [Información general](structure-overview.md)
* [Script de entrada](structure-entry-scripts.md)
* [Aplicaciones](structure-applications.md)
* [Componentes de una aplicación](structure-application-components.md)
* [Controladores](structure-controllers.md)
* [Modelos](structure-models.md)
* [Vistas](structure-views.md)
* [Filtros](structure-filters.md)
* [Widgets](structure-widgets.md)
* [Módulos](structure-modules.md)
* [Assets](structure-assets.md)
* [Extensiones](structure-extensions.md)


Gestión de las peticiones
-------------------------

* [Información general](runtime-overview.md)
* [Bootstrapping](runtime-bootstrapping.md)
* [Routing y Creación de las URL](runtime-routing.md)
* [Peticiones (Requests)](runtime-requests.md)
* [Respuestas (Responses)](runtime-responses.md)
* [Sesiones (Sessions) y Cookies](runtime-sessions-cookies.md)
* [Gestión de errores](runtime-handling-errors.md)
* [Registro de anotaciones](runtime-logging.md)


Conceptos clave
---------------

* [Componentes](concept-components.md)
* [Propiedades](concept-properties.md)
* [Eventos](concept-events.md)
* [Comportamientos (Behaviors)](concept-behaviors.md)
* [Configuraciones](concept-configurations.md)
* [Alias](concept-aliases.md)
* [Autocarga de clases](concept-autoloading.md)
* [Localizador de servicios (Service Locator)](concept-service-locator.md)
* [Contenedor de inyección de dependencia](concept-di-container.md)


Trabajar con bases de datos
---------------------------

* [Objeto de acceso a datos](db-dao.md) - Conexión a una base de datos, consultas básicas, transacciones y
  manipulación de esquemas
* [Constructor de consultas](db-query-builder.md) - Consulta de la base de datos utilizando una simple capa de
  abstracción
* **TBD** [Active Record](db-active-record.md) - ORM Active Record, recuperación y manipulación de registros y
  definición de relaciones
* **TBD** [Migraciones](db-migrations.md) - Control de versiones de bases de datos en el entorno de desarrollo en
  equipo
* **TBD** [Sphinx](db-sphinx.md)
* **TBD** [Redis](db-redis.md)
* **TBD** [MongoDB](db-mongodb.md)
* **TBD** [ElasticSearch](db-elastic-search.md)


Obtener datos de los usuarios
-----------------------------

* **TBD** [Crear formularios](input-forms.md)
* **TBD** [Validar datos](input-validation.md)
* **TBD** [Subir archivos](input-file-upload.md)
* **TBD** [Recogida de tabular input](input-tabular-input.md)
* **TBD** [Obtener datos para múltiples modelos](input-multiple-models.md)


Visualizar datos
----------------

* **TBD** [Formato de datos](output-formatting.md)
* **TBD** [Paginación](output-pagination.md)
* **TBD** [Ordenación](output-sorting.md)
* **TBD** [Proveedores de datos](output-data-providers.md)
* **TBD** [Widgets de datos](output-data-widgets.md)
* **TBD** [Trabajar con scripts de cliente](output-client-scripts.md)
* [Temas](output-theming.md)


Seguridad
---------

* **TBD** [Autenticación](security-authentication.md)
* **TBD** [Autorización](security-authorization.md)
* **TBD** [Trabajar con contraseñas](security-passwords.md)
* [Autenticar Clientes](https://www.yiiframework.com/extension/yiisoft/yii2-authclient/doc/guide)
* **TBD** [Buenas prácticas](security-best-practices.md)


Caché
-----

* [Información general](caching-overview.md)
* [Caché de datos](caching-data.md)
* [Caché de fragmentos](caching-fragment.md)
* [Caché de páginas](caching-page.md)
* [Caché HTTP](caching-http.md)


Servicios Web RESTful
---------------------

* [Guía breve](rest-quick-start.md)
* [Recursos (Resources)](rest-resources.md)
* [Controladores](rest-controllers.md)
* [Gestión de rutas](rest-routing.md)
* [Formateo de respuestas](rest-response-formatting.md)
* [Autenticación](rest-authentication.md)
* [Límite de Rango](rest-rate-limiting.md)
* [Gestión de versiones](rest-versioning.md)
* [Gestión de errores](rest-error-handling.md)


Herramientas de Desarrollo
--------------------------

* [Depurador y Barra de Herramientas de Depuración](https://github.com/yiisoft/yii2-debug/blob/master/docs/guide-es/README.md)
* **TBD** [Generación de códigos con Gii](tool-gii.md)
* **TBD** [Generación de documentación de API](tool-api-doc.md)


Pruebas
------

* **TBD** [Información general](test-overview.md)
* **TBD** [Configuración del entorno de pruebas](test-environment-setup.md)
* **TBD** [Pruebas unitarias](test-unit.md)
* **TBD** [Pruebas funcionales](test-functional.md)
* **TBD** [Pruebas de aceptación](test-acceptance.md)
* **TBD** [Fixtures](test-fixtures.md)


Temas especiales
----------------

* **TBD** [Plantilla aplicación avanzada](tutorial-advanced-app.md)
* **TBD** [Creación de una aplicación desde cero](tutorial-start-from-scratch.md)
* **TBD** [Comandos de consola](tutorial-console.md)
* [Validadores del núcleo](tutorial-core-validators.md)
* **TBD** [Internacionalización](tutorial-i18n.md)
* **TBD** [Envío de correos electrónicos](tutorial-mailing.md)
* **TBD** [Mejora del rendimiento](tutorial-performance-tuning.md)
* **TBD** [Entorno de alojamiento compartido](tutorial-shared-hosting.md)
* **TBD** [Motores de plantillas](tutorial-template-engines.md)
* **TBD** [Trabajar con Código de Terceros](tutorial-yii-integration.md)


Widgets
-------

* GridView: **TBD** link to demo page
* ListView: **TBD** link to demo page
* DetailView: **TBD** link to demo page
* ActiveForm: **TBD** link to demo page
* Pjax: **TBD** link to demo page
* Menu: **TBD** link to demo page
* LinkPager: **TBD** link to demo page
* LinkSorter: **TBD** link to demo page
* [Bootstrap Widgets](https://github.com/yiisoft/yii2-bootstrap/blob/master/docs/guide-es/README.md)
* [Jquery UI Widgets](https://github.com/yiisoft/yii2-jui/blob/master/docs/guide-es/README.md)


Clases auxiliares
-----------------

* [Información general](helper-overview.md)
* [ArrayHelper](helper-array.md)
* [Html](helper-html.md)
* [Url](helper-url.md)

---

### Overview (`docs/guide-fr/README.md`)

Guide définitif pour Yii 2.0
============================

Ce guide est soumis aux [Conditions de la Documentation de Yii](https://www.yiiframework.com/doc/terms/).

Tous droits réservés.

2014 (c) Yii Software LLC.


Introduction
------------

* [A propos de Yii](intro-yii.md)
* [Mise à jour depuis la version 1.1](intro-upgrade-from-v1.md)


Mise en Route
-------------

* [Installer Yii](start-installation.md)
* [Fonctionnement des applications](start-workflow.md)
* [Hello World](start-hello.md)
* [Travailler avec les formulaires](start-forms.md)
* [Travailler avec les bases de données](start-databases.md)
* [Générer du code avec Gii](start-gii.md)
* [En savoir plus](start-looking-ahead.md)


Structure Application
---------------------

* [Vue d'ensemble](structure-overview.md)
* [Scripts d'entrée](structure-entry-scripts.md)
* [Applications](structure-applications.md)
* [Composants application](structure-application-components.md)
* [Contrôleurs](structure-controllers.md)
* [Modèles](structure-models.md)
* [Vues](structure-views.md)
* **TBD** [Filtres](structure-filters.md)
* **TBD** [Widgets](structure-widgets.md)
* **TBD** [Modules](structure-modules.md)
* [Assets](structure-assets.md)
* **TBD** [Extensions](structure-extensions.md)


Gérer les Requêtes
------------------

* **TBD** [Amorçage (Bootstrapping)](runtime-bootstrapping.md)
* **TBD** [Routes](runtime-routing.md)
* **TBD** [Requêtes](runtime-requests.md)
* **TBD** [Réponses](runtime-responses.md)
* **TBD** [Sessions et Cookies](runtime-sessions-cookies.md)
* [Génération et traitement des URL](runtime-url-handling.md)
* [Gestion des erreurs](runtime-handling-errors.md)
* [Journalisation](runtime-logging.md)


Concepts Clés
-------------

* [Composants](concept-components.md)
* [Propriétés](concept-properties.md)
* [Evénements](concept-events.md)
* [Comportements](concept-behaviors.md)
* [Configurations](concept-configurations.md)
* [Alias](concept-aliases.md)
* [Auto-chargement de classes](concept-autoloading.md)
* [Annuaire de services](concept-service-locator.md)
* [Conteneur d'injection de dépendance](concept-di-container.md)


Travailler avec les Bases de Données
------------------------------------

* [Objet d'accès aux données (DAO)](db-dao.md) - Connexion à une base de données, requêtes basiques, transactions et manipulation de schéma
* [Constructeur de requête](db-query-builder.md) - Interrogation de base de données en utilisant une couche d'abstraction simple
* [Active Record](db-active-record.md) - Active Record ORM, récupération et manipulation d'enregistrements et définition des relations
* [Migrations](db-migrations.md) - Contrôle de version de vos bases de données dans un environnement de développement en équipe
* **TBD** [Sphinx](db-sphinx.md)
* **TBD** [Redis](db-redis.md)
* **TBD** [MongoDB](db-mongodb.md)
* **TBD** [ElasticSearch](db-elastic-search.md)


Getting Data from Users
-----------------------

* [Créer des formulaires](input-forms.md)
* [Valider les entrées](input-validation.md)
* **TBD** [Télécharger des fichiers](input-file-upload.md)
* **TBD** [Récupération de données provenant de plusieurs modèles](input-multiple-models.md)


Afficher les données
--------------------

* **TBD** [Formattage](output-formatting.md)
* **TBD** [Pagination](output-pagination.md)
* **TBD** [Tri](output-sorting.md)
* [Fournisseurs de données](output-data-providers.md)
* [Widgets pour afficher des données](output-data-widgets.md)
* [Thématisation](output-theming.md)


Securité
--------

* [Authentification](security-authentication.md)
* [Autorisation](security-authorization.md)
* [Gestion des mots de passe](security-passwords.md)
* **TBD** [Clients authentification](security-auth-clients.md)
* **TBD** [Meilleures pratiques](security-best-practices.md)


Cache
-----

* [Vue d'ensemble](caching-overview.md)
* [Cache de données](caching-data.md)
* [Cache de fragment](caching-fragment.md)
* [Cache de page](caching-page.md)
* [Cache HTTP](caching-http.md)


Services Web RESTful
--------------------

* [Démarrage rapide](rest-quick-start.md)
* [Ressources](rest-resources.md)
* [Contrôleurs](rest-controllers.md)
* [Gestion des routes](rest-routing.md)
* [Formattage des réponses](rest-response-formatting.md)
* [Authentification](rest-authentication.md)
* [Limiter le taux d'utilisation](rest-rate-limiting.md)
* [Gestion des versions](rest-versioning.md)
* [Gestion des erreurs](rest-error-handling.md)


Outils de développement
-----------------------

* [Barre de débogage, et débogueur](tool-debugger.md)
* [Générer du code avec Gii](tool-gii.md)
* **TBD** [Générer une documentation API](tool-api-doc.md)


Tests
-----

* [Vue d'ensemble](test-overview.md)
* **TBD** [Tests unitaires](test-unit.md)
* **TBD** [tests fonctionnels](test-functional.md)
* **TBD** [Tests d'acceptation](test-acceptance.md)
* [Fixtures](test-fixtures.md)


Etendre Yii
-----------

* [Créer des extensions](extend-creating-extensions.md)
* [Personnalisation du code du noyau](extend-customizing-core.md)
* [Utiliser des libraires tierces](extend-using-libs.md)
* **TBD** [Utiliser Yii dans d'autres systèmes](extend-embedding-in-others.md)
* **TBD** [Utiliser Yii 1.1 et 2.0 ensemble](extend-using-v1-v2.md)
* [Utiliser Composer](extend-using-composer.md)


Sujets avancés
--------------

* [Modèle application avancée](tutorial-advanced-app.md)
* [Créer une application à partir de zéro](tutorial-start-from-scratch.md)
* [Commandes console](tutorial-console.md)
* [Validateurs de base](tutorial-core-validators.md)
* [Internationalisation](tutorial-i18n.md)
* [Envoyer des courriels](tutorial-mailing.md)
* [Amélioration des performances](tutorial-performance-tuning.md)
* **TBD** [Environnement d'hébergement mutualisé](tutorial-shared-hosting.md)
* [Moteur de gabarit](tutorial-template-engines.md)


Widgets
-------

* GridView: link to demo page
* ListView: link to demo page
* DetailView: link to demo page
* ActiveForm: link to demo page
* Pjax: link to demo page
* Menu: link to demo page
* LinkPager: link to demo page
* LinkSorter: link to demo page
* [Widgets Bootstrap](bootstrap-widgets.md)
* **TBD** [Widgets Jquery UI](jui-widgets.md)


Assistants
----------

* [Vue d'ensemble](helper-overview.md)
* **TBD** [ArrayHelper](helper-array.md)
* **TBD** [Html](helper-html.md)
* **TBD** [Url](helper-url.md)
* **TBD** [Security](helper-security.md)

---

### Overview (`docs/guide-id/README.md`)

Panduan Definitif Untuk Yii 2.0
===============================

Tutorial ini dirilis di bawah [Persyaratan Dokumentasi Yii](https://www.yiiframework.com/doc/terms/).

Seluruh hak cipta dilindungi.

2014 (c) Yii Software LLC.


Pengantar
------------

* [Tentang Yii](intro-yii.md)
* [Upgrade dari Versi 1.1](intro-upgrade-from-v1.md)


Mulai
---------------

* [Instalasi Yii](start-installation.md)
* [Menjalankan Aplikasi](start-workflow.md)
* [Mengatakan Hello](start-hello.md)
* [Bekerja dengan Form](start-forms.md)
* [Bekerja dengan Database](start-databases.md)
* [Membuat Kode Otomatis dengan Gii](start-gii.md)
* [Menatap ke Depan](start-looking-ahead.md)


Struktur Aplikasi
---------------------

* [Tinjauan](structure-overview.md)
* [Script Masuk](structure-entry-scripts.md)
* [Aplikasi](structure-applications.md)
* [Komponen Aplikasi](structure-application-components.md)
* [Controller](structure-controllers.md)
* [Model](structure-models.md)
* [Views](structure-views.md)
* [Modul](structure-modules.md)
* [Filter](structure-filters.md)
* [Widgets](structure-widgets.md)
* [Aset](structure-assets.md)
* [Ekstensi](structure-extensions.md)


Penanganan Permintaan
-----------------

* [Tinjauan](runtime-overview.md)
* [Bootstrap](runtime-bootstrapping.md)
* [Routing dan Pembuatan URL](runtime-routing.md)
* [Permintaan](runtime-requests.md)
* [Tanggapan](runtime-responses.md)
* [Sesi dan Cookies](runtime-sessions-cookies.md)
* [Penanganan Kesalahan](runtime-handling-errors.md)
* [Logging](runtime-logging.md)


Konsep Pokok
------------

* [Komponen](concept-components.md)
* [Properti](concept-properties.md)
* [Event](concept-events.md)
* [Perilaku](concept-behaviors.md)
* [Konfigurasi](concept-configurations.md)
* [Alias](concept-aliases.md)
* [Class Autoloading](concept-autoloading.md)
* [Layanan Locator](concept-service-locator.md)
* [Dependency Injection](concept-di-container.md)


Bekerja dengan Database
----------------------

* [Data Access Objects](db-dao.md): Menghubungkan ke database, query dasar, transaksi, dan manipulasi skema
* [Query Builder](db-query-builder.md): Query database menggunakan lapisan abstraksi sederhana
* [Active Record](db-active-record.md): ORM Active Record, mengambil dan memanipulasi catatan, dan mendefinisikan hubungan
* [Migrasi](db-migrations.md): Terapkan kontrol versi untuk database Anda dalam lingkungan pengembangan tim
* [Sphinx](https://github.com/yiisoft/yii2-sphinx/blob/master/docs/guide/README.md)
* [Redis](https://github.com/yiisoft/yii2-redis/blob/master/docs/guide/README.md)
* [MongoDB](https://github.com/yiisoft/yii2-mongodb/blob/master/docs/guide/README.md)
* [ElasticSearch](https://github.com/yiisoft/yii2-elasticsearch/blob/master/docs/guide/README.md)


Mendapatkan Data dari Pengguna
-----------------------

* [Membuat Formulir](input-forms.md)
* [Memvalidasi Masukan](input-validation.md)
* [Mengunggah File](input-file-upload.md)
* [Mengumpulkan Masukan Tabel](input-tabular-input.md)
* [Mendapatkan Data untuk Beberapa Model](input-multiple-models.md)


Menampilkan Data
---------------

* [Pemformatan Data](output-formatting.md)
* [Pagination](output-pagination.md)
* [Pengurutan](output-sorting.md)
* [Penyedia Data](output-data-providers.md)
* [Data Widget](output-data-widgets.md)
* [Bekerja dengan Script Client](output-client-scripts.md)
* [Tema](output-theming.md)


Keamanan
--------

* [Tinjauan](security-overview.md)
* [Otentikasi](security-authentication.md)
* [Otorisasi](security-authorization.md)
* [Bekerja dengan Kata Sandi](security-passwords.md)
* [Kriptografi](security-cryptography.md)
* [Otentikasi Klien](https://github.com/yiisoft/yii2-authclient/blob/master/docs/guide/README.md)
* [Praktik Terbaik](security-best-practices.md)


Caching
-------

* [Tinjauan](caching-overview.md)
* [Caching Data](caching-data.md)
* [Caching Fragmen](caching-fragment.md)
* [Caching Halaman](caching-page.md)
* [Caching HTTP](caching-http.md)


Layanan Web RESTful
--------------------

* [Quick Start](rest-quick-start.md)
* [Sumber Daya](rest-resources.md)
* [Controller](rest-controllers.md)
* [Routing](rest-routing.md)
* [Penformatan Respon](rest-response-formatting.md)
* [Otentikasi](rest-authentication.md)
* [Pembatasan Laju](rest-rate-limiting.md)
* [Versi](rest-versioning.md)
* [Penanganan Kesalahan](rest-error-handling.md)


Alat Pengembangan
-----------------

* [Debug Toolbar dan Debugger](https://github.com/yiisoft/yii2-debug/blob/master/docs/guide/README.md)
* [Membuat Kode Otomatis dengan Gii](https://github.com/yiisoft/yii2-gii/blob/master/docs/guide/README.md)
* [Membuat API Documentation](https://github.com/yiisoft/yii2-apidoc)


Pengujian
-------

* [Tinjauan](test-overview.md)
* [Persiapan Lingkungan Pengujian](test-environment-setup.md)
* [Tes Satuan](test-unit.md)
* [Tes Fungsional](test-functional.md)
* [Tes Penerimaan](test-acceptance.md)
* [Jadwal](test-fixtures.md)


Topik Khusus
--------------

* [Cetakan Proyek Lanjutan](https://github.com/yiisoft/yii2-app-advanced/blob/master/docs/guide/README.md)
* [Membangun Aplikasi dari Awal](tutorial-start-from-scratch.md)
* [Console Commands](tutorial-console.md)
* [Validator Inti](tutorial-core-validators.md)
* [Internasionalisasi](tutorial-i18n.md)
* [Mailing](tutorial-mailing.md)
* [Penyetelan Performa](tutorial-performance-tuning.md)
* [Lingkungan Shared Hosting](tutorial-shared-hosting.md)
* [Template Engine](tutorial-template-engines.md)
* [Bekerja dengan Kode Pihak Ketiga](tutorial-yii-integration.md)


Widget
-------

* [GridView](https://www.yiiframework.com/doc-2.0/yii-grid-gridview.html)
* [ListView](https://www.yiiframework.com/doc-2.0/yii-widgets-listview.html)
* [DetailView](https://www.yiiframework.com/doc-2.0/yii-widgets-detailview.html)
* [ActiveForm](https://www.yiiframework.com/doc-2.0/guide-input-forms.html#activerecord-based-forms-activeform)
* [Pjax](https://www.yiiframework.com/doc-2.0/yii-widgets-pjax.html)
* [Menu](https://www.yiiframework.com/doc-2.0/yii-widgets-menu.html)
* [LinkPager](https://www.yiiframework.com/doc-2.0/yii-widgets-linkpager.html)
* [LinkSorter](https://www.yiiframework.com/doc-2.0/yii-widgets-linksorter.html)
* [Bootstrap Widgets](https://github.com/yiisoft/yii2-bootstrap/blob/master/docs/guide/README.md)
* [JQuery UI Widgets](https://github.com/yiisoft/yii2-jui/blob/master/docs/guide/README.md)


Alat Bantu
---------

* [Tinjauan](helper-overview.md)
* [ArrayHelper](helper-array.md)
* [Html](helper-html.md)
* [Url](helper-url.md)

---

### Overview (`docs/guide-it/README.md`)

La guida definitiva a Yii 2.0
=============================

Questa guida è rilasciata nei [termini della documentazione di Yii](https://www.yiiframework.com/doc/terms/).

Tutti i diritti riservati.

2014 (c) Yii Software LLC.

Traduzione italiana a cura di Lorenzo Milesi ([yetopen.it](https://www.yetopen.it)).


Introduzione
------------

* [Informazioni su Yii](intro-yii.md)
* [Aggiornare dalla versione 1.1](intro-upgrade-from-v1.md)


Primi passi
-----------

* [Installare Yii](start-installation.md)
* [Esecuzione applicazioni](start-workflow.md)
* [Dire Ciao](start-hello.md)
* [Utilizzo dei form](start-forms.md)
* [Utilizzo dei database](start-databases.md)
* [Generare codice con Gii](start-gii.md)
* [Passi successivi](start-looking-ahead.md)


Struttura dell'applicazione
---------------------------

* [Panoramica](structure-overview.md)
* [Entry Scripts](structure-entry-scripts.md)
* [Applicazioni](structure-applications.md)
* [Componenti applicazioni](structure-application-components.md)
* [Controller](structure-controllers.md)
* [Modelli](structure-models.md)
* [Viste](structure-views.md)
* [Moduli](structure-modules.md)
* [Filtri](structure-filters.md)
* [Widget](structure-widgets.md)
* [Asset](structure-assets.md)
* [Estensioni](structure-extensions.md)


Gestione delle richieste
------------------------

* [Panoramica](runtime-overview.md)
* [Bootstrapping](runtime-bootstrapping.md)
* [Instradamenti (routing)](runtime-routing.md)
* [Richieste](runtime-requests.md)
* [Risposte](runtime-responses.md)
* **TBD** [Sessioni e cookie](runtime-sessions-cookies.md)
* [Analisi e generazione URL](runtime-url-handling.md)
* [Gestione errori](runtime-handling-errors.md)
* [Log](runtime-logging.md)


Concetti chiave
---------------

* [Componenti](concept-components.md)
* [Proprietà](concept-properties.md)
* [Eventi](concept-events.md)
* [Behavior](concept-behaviors.md)
* [Configurazioni](concept-configurations.md)
* [Alias](concept-aliases.md)
* [Caricamento automatico delle classi (autoload)](concept-autoloading.md)
* [Service Locator](concept-service-locator.md)
* [Container per Dependency Injection](concept-di-container.md)


Utilizzo del database
------------------------

* [Data Access Objects](db-dao.md): Connessione ad un database, query semplici, transazioni e modifiche allo schema
* [Query Builder](db-query-builder.md): Esecuzione di query al database usando un semplice livello di astrazione
* [Active Record](db-active-record.md): The Active Record ORM, retrieving and manipulating records, and defining relations
* [Migrazoni](db-migrations.md): Applicare il controllo di versione al database in un ambiente di sviluppo di gruppo
* **TBD** [Sphinx](db-sphinx.md)
* **TBD** [Redis](db-redis.md)
* **TBD** [MongoDB](db-mongodb.md)
* **TBD** [ElasticSearch](db-elasticsearch.md)


Ricezione dati dagli utenti
---------------------------

* [Creare form](input-forms.md)
* [Validazione informazioni](input-validation.md)
* **TBD** [Caricamento file](input-file-upload.md)
* **TBD** [Raccogliere dati per più modelli](input-multiple-models.md)


Visualizzazione dei dati
------------------------

* **TBD** [Formattazione](output-formatting.md)
* **TBD** [Paginazione](output-pagination.md)
* **TBD** [Ordinamento](output-sorting.md)
* [Data Provider](output-data-providers.md)
* [Data Widget](output-data-widgets.md)
* [Utilizzo del Client Scripts](output-client-scripts.md)
* [Temi](output-theming.md)


Sicurezza
---------

* [Autenticazione](security-authentication.md)
* [Autorizzazione](security-authorization.md)
* [Utilizzo delle password](security-passwords.md)
* **TBD** [Auth Clients](security-auth-clients.md)
* **TBD** [Buona prassi](security-best-practices.md)


Cache
-----

* [Panoramica](caching-overview.md)
* [Cache dati](caching-data.md)
* [Fragment Caching](caching-fragment.md)
* [Cache pagina](caching-page.md)
* [Cache HTTP](caching-http.md)


Servizi web RESTful
-------------------

* [Avvio veloce](rest-quick-start.md)
* [Risorse](rest-resources.md)
* [Controller](rest-controllers.md)
* [Instradamenti](rest-routing.md)
* [Formattazione risposte](rest-response-formatting.md)
* [Autenticazione](rest-authentication.md)
* [Limitazione di utilizzo](rest-rate-limiting.md)
* [Versioning](rest-versioning.md)
* [Gestione degli errori](rest-error-handling.md)


Strumenti di sviluppo
---------------------

* [Barra di debug e debugger](tool-debugger.md)
* [Generazione codice con Gii](tool-gii.md)
* **TBD** [Generazione documentazione API](tool-api-doc.md)


Test
----

* [Panoramica](test-overview.md)
* [Inizializzazione ambiente di test](test-environment-setup.md)
* [Unit Test](test-unit.md)
* [Functional Test](test-functional.md)
* [Acceptance Test](test-acceptance.md)
* [Fixture](test-fixtures.md)


Argomenti speciali
------------------

* [Modello di applicazione avanzata](tutorial-advanced-app.md)
* [Creazione di una applicazione da zero](tutorial-start-from-scratch.md)
* [Comandi da console](tutorial-console.md)
* [Validazioni predefinite](tutorial-core-validators.md)
* [Internazionalizzazione](tutorial-i18n.md)
* [Invio email](tutorial-mailing.md)
* [Ottimizzazione delle prestazioni](tutorial-performance-tuning.md)
* **TBD** [Ambienti di hosting condiviso](tutorial-shared-hosting.md)
* [Template Engine](tutorial-template-engines.md)
* [Utilizzo di codice di terze parti](tutorial-yii-integration.md)


Widget
------

* GridView: link to demo page
* ListView: link to demo page
* DetailView: link to demo page
* ActiveForm: link to demo page
* Pjax: link to demo page
* Menu: link to demo page
* LinkPager: link to demo page
* LinkSorter: link to demo page
* [Widget Bootstrap](widget-bootstrap.md)
* [Widget Jquery UI](widget-jui.md)


Helper
------

* [Panoramica](helper-overview.md)
* **TBD** [ArrayHelper](helper-array.md)
* **TBD** [Html](helper-html.md)
* **TBD** [Url](helper-url.md)
* **TBD** [Security](helper-security.md)

---

### Overview (`docs/guide-ja/README.md`)

Yii 2.0 決定版ガイド
====================

このチュートリアルは [Yii ドキュメント許諾条件](https://www.yiiframework.com/doc/terms/) の下にリリースされています。

All Rights Reserved.

2014 (c) Yii Software LLC.


導入
----

* [Yii について](intro-yii.md)
* [バージョン 1.1 からのアップグレード](intro-upgrade-from-v1.md)


始めよう
--------

* [何を知っている必要があるか](start-prerequisites.md)
* [Yii をインストールする](start-installation.md)
* [アプリケーションを走らせる](start-workflow.md)
* [こんにちは、と言う](start-hello.md)
* [フォームを扱う](start-forms.md)
* [データベースを扱う](start-databases.md)
* [Gii でコードを生成する](start-gii.md)
* [先を見通す](start-looking-ahead.md)


アプリケーションの構造
----------------------

* [アプリケーションの構造の概要](structure-overview.md)
* [エントリ・スクリプト](structure-entry-scripts.md)
* [アプリケーション](structure-applications.md)
* [アプリケーション・コンポーネント](structure-application-components.md)
* [コントローラ](structure-controllers.md)
* [モデル](structure-models.md)
* [ビュー](structure-views.md)
* [モジュール](structure-modules.md)
* [フィルタ](structure-filters.md)
* [ウィジェット](structure-widgets.md)
* [アセット](structure-assets.md)
* [エクステンション](structure-extensions.md)


リクエストの処理
----------------

* [リクエストの処理の概要](runtime-overview.md)
* [ブートストラップ](runtime-bootstrapping.md)
* [ルーティングと URL 生成](runtime-routing.md)
* [リクエスト](runtime-requests.md)
* [レスポンス](runtime-responses.md)
* [セッションとクッキー](runtime-sessions-cookies.md)
* [エラー処理](runtime-handling-errors.md)
* [ロギング](runtime-logging.md)


鍵となる概念
------------

* [コンポーネント](concept-components.md)
* [プロパティ](concept-properties.md)
* [イベント](concept-events.md)
* [ビヘイビア](concept-behaviors.md)
* [構成情報](concept-configurations.md)
* [エイリアス](concept-aliases.md)
* [クラスのオートロード](concept-autoloading.md)
* [サービス・ロケータ](concept-service-locator.md)
* [依存注入コンテナ](concept-di-container.md)


データベースの取り扱い
----------------------

* [データベース・アクセス・オブジェクト](db-dao.md): データベースへの接続、基本的なクエリ、トランザクション、および、スキーマ操作
* [クエリ・ビルダ](db-query-builder.md): シンプルな抽象レイヤを使ってデータベースに対してクエリを行う
* [アクティブ・レコード](db-active-record.md): アクティブ・レコード ORM、レコードの読み出しと操作、リレーションの定義
* [マイグレーション](db-migrations.md): チーム開発環境においてデータベースにバージョン・コントロールを適用
* [Sphinx](https://www.yiiframework.com/extension/yiisoft/yii2-sphinx/doc/guide)
* [Redis](https://www.yiiframework.com/extension/yiisoft/yii2-redis/doc/guide)
* [MongoDB](https://www.yiiframework.com/extension/yiisoft/yii2-mongodb/doc/guide)
* [ElasticSearch](https://www.yiiframework.com/extension/yiisoft/yii2-elasticsearch/doc/guide)


ユーザからのデータ取得
----------------------

* [フォームを作成する](input-forms.md)
* [入力を検証する](input-validation.md)
* [ファイルをアップロードする](input-file-upload.md)
* [表形式インプットのデータ収集](input-tabular-input.md)
* [複数のモデルのデータを取得する](input-multiple-models.md)
* [クライアント・サイドで ActiveForm を拡張する](input-form-javascript.md)


データの表示
------------

* [データのフォーマット](output-formatting.md)
* [ページネーション](output-pagination.md)
* [並べ替え](output-sorting.md)
* [データ・プロバイダ](output-data-providers.md)
* [データ・ウィジェット](output-data-widgets.md)
* [クライアント・スクリプトを扱う](output-client-scripts.md)
* [テーマ](output-theming.md)


セキュリティ
------------

* [セキュリティの概要](security-overview.md)
* [認証](security-authentication.md)
* [権限付与](security-authorization.md)
* [パスワードを扱う](security-passwords.md)
* [暗号化](security-cryptography.md)
* [認証クライアント](https://www.yiiframework.com/extension/yiisoft/yii2-authclient/doc/guide)
* [ベスト・プラクティス](security-best-practices.md)


キャッシュ
----------

* [キャッシュの概要](caching-overview.md)
* [データ・キャッシュ](caching-data.md)
* [フラグメント・キャッシュ](caching-fragment.md)
* [ページ・キャッシュ](caching-page.md)
* [HTTP キャッシュ](caching-http.md)


RESTful ウェブ・サービス
------------------------

* [クイック・スタート](rest-quick-start.md)
* [リソース](rest-resources.md)
* [コレクションのフィルタリング](rest-filtering-collections.md)
* [コントローラ](rest-controllers.md)
* [ルーティング](rest-routing.md)
* [レスポンス形式の設定](rest-response-formatting.md)
* [認証](rest-authentication.md)
* [レート制限](rest-rate-limiting.md)
* [バージョン管理](rest-versioning.md)
* [エラー処理](rest-error-handling.md)


開発ツール
----------

* [デバッグ・ツールバーとデバッガ](https://www.yiiframework.com/extension/yiisoft/yii2-debug/doc/guide)
* [Gii を使ってコードを生成する](https://www.yiiframework.com/extension/yiisoft/yii2-gii/doc/guide)
* [API ドキュメントを生成する](https://www.yiiframework.com/extension/yiisoft/yii2-apidoc)


テスト
------

* [テストの概要](test-overview.md)
* [テスト環境の構築](test-environment-setup.md)
* [単体テスト](test-unit.md)
* [機能テスト](test-functional.md)
* [受入テスト](test-acceptance.md)
* [フィクスチャ](test-fixtures.md)


スペシャル・トピック
--------------------

* [アドバンスト・プロジェクト・テンプレート](https://www.yiiframework.com/extension/yiisoft/yii2-app-advanced/doc/guide)
* [アプリケーションを一から構築する](tutorial-start-from-scratch.md)
* [コンソール・コマンド](tutorial-console.md)
* [コア・バリデータ](tutorial-core-validators.md)
* [国際化](tutorial-i18n.md)
* [メール送信](tutorial-mailing.md)
* [パフォーマンス・チューニング](tutorial-performance-tuning.md)
* [共有ホスティング環境](tutorial-shared-hosting.md)
* [テンプレート・エンジン](tutorial-template-engines.md)
* [サードパーティのコードを扱う](tutorial-yii-integration.md)
* [Yii をマイクロ・フレームワークとして使う](tutorial-yii-as-micro-framework.md)


ウィジェット
------------

* [GridView](https://www.yiiframework.com/doc-2.0/yii-grid-gridview.html)
* [ListView](https://www.yiiframework.com/doc-2.0/yii-widgets-listview.html)
* [DetailView](https://www.yiiframework.com/doc-2.0/yii-widgets-detailview.html)
* [ActiveForm](https://www.yiiframework.com/doc/guide/2.0/ja/input-forms#activerecord-based-forms-activeform)
* [Pjax](https://www.yiiframework.com/doc-2.0/yii-widgets-pjax.html)
* [Menu](https://www.yiiframework.com/doc-2.0/yii-widgets-menu.html)
* [LinkPager](https://www.yiiframework.com/doc-2.0/yii-widgets-linkpager.html)
* [LinkSorter](https://www.yiiframework.com/doc-2.0/yii-widgets-linksorter.html)
* [Bootstrap ウィジェット](https://www.yiiframework.com/extension/yiisoft/yii2-bootstrap/doc/guide)
* [jQuery UI ウィジェット](https://www.yiiframework.com/extension/yiisoft/yii2-jui/doc/guide)


ヘルパ
------

* [ヘルパの概要](helper-overview.md)
* [配列ヘルパ](helper-array.md)
* [Html ヘルパ](helper-html.md)
* [Url ヘルパ](helper-url.md)

---

### Overview (`docs/guide-pl/README.md`)

Przewodnik po Yii 2.0
=====================

Ten poradnik udostępniony jest na [Warunkach dokumentacji Yii](https://www.yiiframework.com/doc/terms/).

Wszelkie prawa zastrzeżone.

2014 (c) Yii Software LLC.


Wstęp
-----

* [O Yii](intro-yii.md)
* [Aktualizacja z wersji 1.1](intro-upgrade-from-v1.md)


Pierwsze kroki
--------------

* [Co musisz wiedzieć](start-prerequisites.md)
* [Instalacja Yii](start-installation.md)
* [Uruchamianie aplikacji](start-workflow.md)
* [Witaj świecie](start-hello.md)
* [Praca z formularzami](start-forms.md)
* [Praca z bazami danych](start-databases.md)
* [Generowanie kodu za pomocą Gii](start-gii.md)
* [Dalsze kroki](start-looking-ahead.md)


Struktura aplikacji
-------------------

* [Przegląd](structure-overview.md)
* [Skrypty wejściowe](structure-entry-scripts.md)
* [Aplikacje](structure-applications.md)
* [Komponenty aplikacji](structure-application-components.md)
* [Kontrolery](structure-controllers.md)
* [Modele](structure-models.md)
* [Widoki](structure-views.md)
* [Moduły](structure-modules.md)
* [Filtry](structure-filters.md)
* [Widżety](structure-widgets.md)
* [Zasoby (Assets)](structure-assets.md)
* [Rozszerzenia](structure-extensions.md)


Obsługa żądań
-------------

* [Przegląd](runtime-overview.md)
* [Bootstrapping](runtime-bootstrapping.md)
* [Parsowanie i generowanie adresów URL](runtime-routing.md)
* [Żądania](runtime-requests.md)
* [Odpowiedzi](runtime-responses.md)
* [Sesje i ciasteczka](runtime-sessions-cookies.md)
* [Obsługa błędów](runtime-handling-errors.md)
* [Logowanie](runtime-logging.md)


Kluczowe koncepcje
------------------

* [Komponenty](concept-components.md)
* [Właściwości](concept-properties.md)
* [Zdarzenia (Events)](concept-events.md)
* [Zachowania (Behaviors)](concept-behaviors.md)
* [Konfiguracje](concept-configurations.md)
* [Aliasy](concept-aliases.md)
* [Autoładowanie klas](concept-autoloading.md)
* [Lokator usług (Service Locator)](concept-service-locator.md)
* [Kontener wstrzykiwania zależności (DI Container)](concept-di-container.md)


Praca z bazami danych
---------------------

* [Obiekty dostępu do danych (DAO)](db-dao.md): Łączenie z bazą, podstawowe zapytania, transakcje i manipulacja schematem.
* [Konstruktor kwerend](db-query-builder.md): Zapytania do bazy danych z użyciem warstwy abstrakcyjnej.
* [Active Record](db-active-record.md): Active Record ORM, otrzymywanie i manipulacja rekordami oraz definiowanie relacji.
* [Migracje](db-migrations.md): Użycie systemu kontroli wersji bazy danych do pracy z wieloma środowiskami.
* [Sphinx](https://www.yiiframework.com/extension/yiisoft/yii2-sphinx/doc/guide)
* [Redis](https://www.yiiframework.com/extension/yiisoft/yii2-redis/doc/guide)
* [MongoDB](https://www.yiiframework.com/extension/yiisoft/yii2-mongodb/doc/guide)
* [ElasticSearch](https://www.yiiframework.com/extension/yiisoft/yii2-elasticsearch/doc/guide)


Odbieranie danych od użytkowników
---------------------------------

* [Tworzenie formularzy](input-forms.md)
* [Walidacja danych wejściowych](input-validation.md)
* [Wysyłanie plików](input-file-upload.md)
* [Odczytywanie tablicowych danych wejściowych](input-tabular-input.md)
* [Pobieranie danych dla wielu modeli](input-multiple-models.md)
* [Rozszerzanie ActiveForm po stronie klienta](input-form-javascript.md)


Wyświetlanie danych
-------------------

* [Formatowanie danych](output-formatting.md)
* [Stronicowanie](output-pagination.md)
* [Sortowanie](output-sorting.md)
* [Dostawcy danych](output-data-providers.md)
* [Widżety danych](output-data-widgets.md)
* [Praca ze skryptami](output-client-scripts.md)
* [Skórki i motywy (Theming)](output-theming.md)


Bezpieczeństwo
--------------

* [Omówienie](security-overview.md)
* [Uwierzytelnianie](security-authentication.md)
* [Autoryzacja](security-authorization.md)
* [Praca z hasłami](security-passwords.md)
* [Kryptografia](security-cryptography.md)
* [Klienty autoryzacji](https://www.yiiframework.com/extension/yiisoft/yii2-authclient/doc/guide)
* [Bezpieczeństwo w praktyce](security-best-practices.md)


Pamięć podręczna
----------------

* [Przegląd](caching-overview.md)
* [Pamięć podręczna danych](caching-data.md)
* [Pamięć podręczna fragmentów](caching-fragment.md)
* [Pamięć podręczna stron](caching-page.md)
* [Pamięć podręczna HTTP](caching-http.md)


Webserwisy z wykorzystaniem REST
--------------------------------

* [Szybki start](rest-quick-start.md)
* [Zasoby](rest-resources.md)
* [Kontrolery](rest-controllers.md)
* [Routing](rest-routing.md)
* [Formatowanie odpowiedzi](rest-response-formatting.md)
* [Uwierzytelnianie](rest-authentication.md)
* [Limit użycia](rest-rate-limiting.md)
* [Wersjonowanie](rest-versioning.md)
* [Obsługa błędów](rest-error-handling.md)


Narzędzia wspomagające tworzenie aplikacji
------------------------------------------

* [Pasek debugowania i debuger](https://www.yiiframework.com/extension/yiisoft/yii2-debug/doc/guide)
* [Generowanie kodu przy użyciu Gii](https://www.yiiframework.com/extension/yiisoft/yii2-gii/doc/guide)
* [Generowanie dokumentacji API](https://www.yiiframework.com/extension/yiisoft/yii2-apidoc)


Testowanie
----------

* [Przegląd](test-overview.md)
* [Konfiguracja środowiska testowego](test-environment-setup.md)
* [Testy jednostkowe](test-unit.md)
* [Testy funkcjonalnościowe](test-functional.md)
* [Testy akceptacyjne](test-acceptance.md)
* [Fixtures](test-fixtures.md)


Tematy specjalne
----------------

* [Szablon zaawansowanej aplikacji](https://www.yiiframework.com/extension/yiisoft/yii2-app-advanced/doc/guide)
* [Tworzenie aplikacji od podstaw](tutorial-start-from-scratch.md)
* [Komendy konsolowe](tutorial-console.md)
* [Wbudowane walidatory](tutorial-core-validators.md)
* [Docker](tutorial-docker.md)
* [Internacjonalizacja](tutorial-i18n.md)
* [Wysyłanie poczty](tutorial-mailing.md)
* [Poprawianie wydajności](tutorial-performance-tuning.md)
* [Współdzielone środowisko hostingowe](tutorial-shared-hosting.md)
* [Silniki szablonów](tutorial-template-engines.md)
* [Praca z kodem zewnętrznym](tutorial-yii-integration.md)
* [Używanie Yii jako mikroframeworka](tutorial-yii-as-micro-framework.md)


Widżety
-------

* [GridView](https://www.yiiframework.com/doc-2.0/yii-grid-gridview.html)
* [ListView](https://www.yiiframework.com/doc-2.0/yii-widgets-listview.html)
* [DetailView](https://www.yiiframework.com/doc-2.0/yii-widgets-detailview.html)
* [ActiveForm](https://www.yiiframework.com/doc-2.0/guide-input-forms.html#activerecord-based-forms-activeform)
* [Pjax](https://www.yiiframework.com/doc-2.0/yii-widgets-pjax.html)
* [Menu](https://www.yiiframework.com/doc-2.0/yii-widgets-menu.html)
* [LinkPager](https://www.yiiframework.com/doc-2.0/yii-widgets-linkpager.html)
* [LinkSorter](https://www.yiiframework.com/doc-2.0/yii-widgets-linksorter.html)
* [Widżety Bootstrapowe](https://www.yiiframework.com/extension/yiisoft/yii2-bootstrap/doc/guide)
* [Widżety jQuery UI](https://www.yiiframework.com/extension/yiisoft/yii2-jui/doc/guide)


Klasy pomocnicze
----------------

* [Przegląd](helper-overview.md)
* [ArrayHelper](helper-array.md)
* [Html](helper-html.md)
* [Json](helper-json.md)
* [Url](helper-url.md)


Uwagi do polskiego tłumaczenia przewodnika
------------------------------------------

Niektóre z użytych w tym przewodniku programistycznych nazw zostały celowo spolszczone, w przypadku, gdy 
w literaturze popularnej nie występują ich polskie odpowiedniki. Mam nadzieję, że czytelnik wybaczy okazjonalne 
"settery", "gettery" i "traity", które umieszczamy tutaj licząc na powszechne zrozumienie tych terminów w polskiej 
społeczności programistycznej. Jednocześnie spolszczenia/tłumaczenia niektórych terminów, jak "Fixtures", odmawiamy na razie 
całkowicie, licząc na to, że język polski w końcu nadgoni lub wchłonie, w ten, czy inny sposób, techniczne nowości.

---

### Overview (`docs/guide-pt-BR/README.md`)

Guia Definitivo para Yii 2.0
============================

Esse tutorial está disponível sob os [termos da documentação do Yii](https://www.yiiframework.com/doc/terms/).

Todos os Direitos Reservados.

2014 (c) Yii Software LLC.


Introdução
----------

* [Sobre o Yii](intro-yii.md)
* [Migrando a partir da versão 1.1](intro-upgrade-from-v1.md)


Primeiros Passos
----------------

* [O que você precisa saber](start-prerequisites.md)
* [Instalando o Yii](start-installation.md)
* [Executando Aplicações](start-workflow.md)
* [Dizendo "Olá!"](start-hello.md)
* [Trabalhando com Formulários](start-forms.md)
* [Trabalhando com Bancos de Dados](start-databases.md)
* [Gerando Código com Gii](start-gii.md)
* [Seguindo em Frente](start-looking-ahead.md)


Estrutura da Aplicação
--------------------------

* [Visão Geral](structure-overview.md)
* [Scripts de Entrada](structure-entry-scripts.md)
* [Aplicações](structure-applications.md)
* [Componentes de Aplicação](structure-application-components.md)
* [Controladores (Controllers)](structure-controllers.md)
* [Modelos (Models)](structure-models.md)
* [Visões (Views)](structure-views.md)
* [Módulos](structure-modules.md)
* [Filtros](structure-filters.md)
* [Widgets](structure-widgets.md)
* [Assets](structure-assets.md)
* [Extensões](structure-extensions.md)


Tratando Requisições
-------------------------

* [Visão Geral](runtime-overview.md)
* [Preparação do Ambiente (Bootstrapping)](runtime-bootstrapping.md)
* [Roteamento e Criação de URL](runtime-routing.md)
* [Requisições](runtime-requests.md)
* [Respostas](runtime-responses.md)
* [Sessões e Cookies](runtime-sessions-cookies.md)
* [Tratamento de Erros](runtime-handling-errors.md)
* [Gerenciamento de Logs](runtime-logging.md)


Conceitos Chave
---------------

* [Componentes](concept-components.md)
* [Propriedades](concept-properties.md)
* [Eventos](concept-events.md)
* [Comportamentos](concept-behaviors.md)
* [Configurações](concept-configurations.md)
* [Apelidos (Aliases)](concept-aliases.md)
* [Carregamento Automático de Classes (Autoloading)](concept-autoloading.md)
* [Service Locator](concept-service-locator.md)
* [Container de Injeção de Dependência](concept-di-container.md)


Trabalhando com Banco de Dados
------------------------------

* [Objetos de Acesso a Dados - (Database Access Objects)](db-dao.md): Conectando a um banco de dados, consultas básicas, transações e manipulação de esquema
* [Construtor de Consulta (Query Builder)](db-query-builder.md): Consultando o banco de dados usando uma camada de abstração simples
* [Active Record](db-active-record.md): Sobre o Active Record ORM, recuperando e manipulando registros e definindo relacionamentos
* [Migrações (Migrations)](db-migrations.md): Aplica controle de versão para seus banco de dados em um ambiente de desenvolvimento em equipe
* [Sphinx](https://www.yiiframework.com/extension/yiisoft/yii2-sphinx/doc/guide)
* [Redis](https://www.yiiframework.com/extension/yiisoft/yii2-redis/doc/guide)
* [MongoDB](https://www.yiiframework.com/extension/yiisoft/yii2-mongodb/doc/guide)
* [ElasticSearch](https://www.yiiframework.com/extension/yiisoft/yii2-elasticsearch/doc/guide)


Coletando Dados de Usuários
---------------------------

* [Criando Formulários](input-forms.md)
* [Validando Dados](input-validation.md)
* [Recebendo Arquivos (Upload)](input-file-upload.md)
* [Coletando Dados Tabulares](input-tabular-input.md)
* [Coletando Dados para Múltiplos Models](input-multiple-models.md)
* [Extendendo o ActiveForm no Client Side](input-form-javascript.md)


Exibindo Dados
---------------

* [Formatação de Dados](output-formatting.md)
* [Paginação](output-pagination.md)
* [Ordenação](output-sorting.md)
* [Provedores de Dados (Data Providers)](output-data-providers.md)
* [Widgets de Dados](output-data-widgets.md)
* [Trabalhando com Client Scripts](output-client-scripts.md)
* [Temas](output-theming.md)


Segurança
--------

* [Visão Geral](security-overview.md)
* [Autenticação](security-authentication.md)
* [Autorização](security-authorization.md)
* [Trabalhando com Senhas](security-passwords.md)
* [Criptografia](security-cryptography.md)
* [Auth Clients](https://www.yiiframework.com/extension/yiisoft/yii2-authclient/doc/guide)
* [Melhores Práticas](security-best-practices.md)


Cache
-------

* [Visão Geral](caching-overview.md)
* [Cache de Dados](caching-data.md)
* [Cache de Fragmento](caching-fragment.md)
* [Cache de Página](caching-page.md)
* [Cache HTTP](caching-http.md)


Web Services RESTful
------------------------

* [Introdução](rest-quick-start.md)
* [Recursos](rest-resources.md)
* [Controladores (Controllers)](rest-controllers.md)
* [Roteamento](rest-routing.md)
* [Formatação de Respostas](rest-response-formatting.md)
* [Autenticação](rest-authentication.md)
* [Taxa de Limite de Acessos](rest-rate-limiting.md)
* [Versionamento](rest-versioning.md)
* [Tratamento de Erros](rest-error-handling.md)


Ferramentas de Desenvolvimento
------------------------------

* [Barra de Ferramentas de Depuração e Depurador](https://www.yiiframework.com/extension/yiisoft/yii2-debug/doc/guide)
* [Gerando Código usando o Gii](https://www.yiiframework.com/extension/yiisoft/yii2-gii/doc/guide)
* [Gerando Documentação da API](https://www.yiiframework.com/extension/yiisoft/yii2-apidoc)


Testes
------

* [Visão Geral](test-overview.md)
* [Configuração do ambiente de testes](test-environment-setup.md)
* [Testes Unitários](test-unit.md)
* [Testes Funcionais](test-functional.md)
* [Testes de Aceitação](test-acceptance.md)
* [Fixtures](test-fixtures.md)


Tópicos Especiais
-----------------

* [Template Avançado de Projetos](https://github.com/yiisoft/yii2-app-advanced/blob/master/docs/guide-pt-BR)
* [Construindo uma Aplicação a Partir do Zero](tutorial-start-from-scratch.md)
* [Comandos de Console](tutorial-console.md)
* [Validadores Nativos](tutorial-core-validators.md)
* [Docker](tutorial-docker.md)
* [Internacionalização](tutorial-i18n.md)
* [Envio de E-mails](tutorial-mailing.md)
* [Ajustes de Desempenho](tutorial-performance-tuning.md)
* [Ambiente de Hospedagem Compartilhada](tutorial-shared-hosting.md)
* [Motores de Template (Template Engines)](tutorial-template-engines.md)
* [Trabalhando com Código de Terceiros](tutorial-yii-integration.md)
* [Usando Yii como um Microframework](tutorial-yii-as-micro-framework.md)



Widgets
-------

* [GridView](https://www.yiiframework.com/doc-2.0/yii-grid-gridview.html)
* [ListView](https://www.yiiframework.com/doc-2.0/yii-widgets-listview.html)
* [DetailView](https://www.yiiframework.com/doc-2.0/yii-widgets-detailview.html)
* [ActiveForm](https://www.yiiframework.com/doc-2.0/guide-input-forms.html#activerecord-based-forms-activeform)
* [Pjax](https://www.yiiframework.com/doc-2.0/yii-widgets-pjax.html)
* [Menu](https://www.yiiframework.com/doc-2.0/yii-widgets-menu.html)
* [LinkPager](https://www.yiiframework.com/doc-2.0/yii-widgets-linkpager.html)
* [LinkSorter](https://www.yiiframework.com/doc-2.0/yii-widgets-linksorter.html)
* [Widgets Bootstrap](https://www.yiiframework.com/extension/yiisoft/yii2-bootstrap/doc/guide)
* [Widgets jQuery UI](https://www.yiiframework.com/extension/yiisoft/yii2-jui/doc/guide)


Helpers - Funções Auxiliares
-------

* [Visão Geral](helper-overview.md)
* [ArrayHelper](helper-array.md)
* [Html](helper-html.md)
* [Url](helper-url.md)

---

### Overview (`docs/guide-ru/README.md`)

Полное руководство по Yii 2.0
=============================

Данное руководство выпущено в соответствии с [положениями о документации Yii](https://www.yiiframework.com/doc/terms/).

All Rights Reserved.

2014 © Yii Software LLC.


Введение
--------

* [О Yii](intro-yii.md)
* [Обновление с версии 1.1](intro-upgrade-from-v1.md)


Первое знакомство
-----------------

* [Что нужно знать](start-prerequisites.md)
* [Установка Yii](start-installation.md)
* [Запуск приложения](start-workflow.md)
* [Говорим «привет»](start-hello.md)
* [Работа с формами](start-forms.md)
* [Работа с базами данных](start-databases.md)
* [Генерация кода при помощи Gii](start-gii.md)
* [Что дальше?](start-looking-ahead.md)


Структура приложения
--------------------

* [Обзор](structure-overview.md)
* [Входные скрипты](structure-entry-scripts.md)
* [Приложения](structure-applications.md)
* [Компоненты приложения](structure-application-components.md)
* [Контроллеры](structure-controllers.md)
* [Модели](structure-models.md)
* [Представления](structure-views.md)
* [Модули](structure-modules.md)
* [Фильтры](structure-filters.md)
* [Виджеты](structure-widgets.md)
* [Ресурсы](structure-assets.md)
* [Расширения](structure-extensions.md)


Обработка запросов
------------------

* [Обзор](runtime-overview.md)
* [Bootstrapping](runtime-bootstrapping.md)
* [Разбор и генерация URL](runtime-routing.md)
* [Запросы](runtime-requests.md)
* [Ответы](runtime-responses.md)
* [Сессии и куки](runtime-sessions-cookies.md)
* [Обработка ошибок](runtime-handling-errors.md)
* [Логирование](runtime-logging.md)


Основные понятия
----------------

* [Компоненты](concept-components.md)
* [Свойства](concept-properties.md)
* [События](concept-events.md)
* [Поведения](concept-behaviors.md)
* [Конфигурации](concept-configurations.md)
* [Псевдонимы](concept-aliases.md)
* [Автозагрузка классов](concept-autoloading.md)
* [Service Locator](concept-service-locator.md)
* [Dependency Injection Container](concept-di-container.md)


Работа с базами данных
----------------------

* [Объекты доступа к данным (DAO)](db-dao.md) - Соединение с базой данных, простые запросы, транзакции и работа со схемой.
* [Построитель запросов](db-query-builder.md) - Запросы к базе данных через простой слой абстракции.
* [Active Record](db-active-record.md) - Получение объектов AR, работа с ними и определение связей.
* [Миграции](db-migrations.md) - Контроль версий схемы данных при работе в команде.
* [Sphinx](https://github.com/yiisoft/yii2-sphinx/blob/master/docs/guide-ru/README.md)
* [Redis](https://github.com/yiisoft/yii2-redis/blob/master/docs/guide-ru/README.md)
* [MongoDB](https://github.com/yiisoft/yii2-mongodb/blob/master/docs/guide-ru/README.md)
* [ElasticSearch](https://github.com/yiisoft/yii2-elasticsearch/blob/master/docs/guide-ru/README.md)


Получение данных от пользователя
--------------------------------

* [Создание форм](input-forms.md)
* [Валидация](input-validation.md)
* [Загрузка файлов](input-file-upload.md)
* [Табличный ввод](input-tabular-input.md)
* [Работа с несколькими моделями](input-multiple-models.md)
* [Расширение ActiveForm на стороне клиента](input-form-javascript.md)


Отображение данных
------------------

* [Форматирование данных](output-formatting.md)
* [Постраничная разбивка](output-pagination.md)
* [Сортировка](output-sorting.md)
* [Провайдеры данных](output-data-providers.md)
* [Виджеты для данных](output-data-widgets.md)
* [Работа с клиентскими скриптами](output-client-scripts.md)
* [Темизация](output-theming.md)


Безопасность
------------

* [Обзор](security-overview.md)
* [Аутентификация](security-authentication.md)
* [Авторизация](security-authorization.md)
* [Работа с паролями](security-passwords.md)
* [Криптография](security-cryptography.md)
* [Клиенты авторизации](https://github.com/yiisoft/yii2-authclient/blob/master/docs/guide-ru/README.md)
* [Лучшие практики](security-best-practices.md)


Кеширование
-----------

* [Обзор](caching-overview.md)
* [Кэширование данных](caching-data.md)
* [Кэширование фрагментов](caching-fragment.md)
* [Кэширование страниц](caching-page.md)
* [HTTP кэширование](caching-http.md)


Веб-сервисы REST
----------------

* [Быстрый старт](rest-quick-start.md)
* [Ресурсы](rest-resources.md)
* [Контроллеры](rest-controllers.md)
* [Фильтрация коллекций](rest-filtering-collections.md)
* [Роутинг](rest-routing.md)
* [Форматирование ответа](rest-response-formatting.md)
* [Аутентификация](rest-authentication.md)
* [Ограничение частоты запросов](rest-rate-limiting.md)
* [Версионирование](rest-versioning.md)
* [Обработка ошибок](rest-error-handling.md)


Инструменты разработчика
------------------------

* [Отладочная панель и отладчик](https://github.com/yiisoft/yii2-debug/blob/master/docs/guide/README.md)
* [Генерация кода с Gii](https://github.com/yiisoft/yii2-gii/blob/master/docs/guide/README.md)
* [Генератор документации API](https://github.com/yiisoft/yii2-apidoc)


Тестирование
------------

* [Обзор](test-overview.md)
* [Настройка тестового окружения](test-environment-setup.md)
* [Модульные тесты](test-unit.md)
* [Функциональные тесты](test-functional.md)
* [Приёмочные тесты](test-acceptance.md)
* [Фикстуры](test-fixtures.md)


Специальные темы
----------------

* [Шаблон приложения advanced](https://github.com/yiisoft/yii2-app-advanced/blob/master/docs/guide/README.md)
* [Создание приложения с нуля](tutorial-start-from-scratch.md)
* [Консольные команды](tutorial-console.md)
* [Docker](tutorial-docker.md)
* [Встроенные валидаторы](tutorial-core-validators.md)
* [Интернационализация](tutorial-i18n.md)
* [Отправка почты](tutorial-mailing.md)
* [Оптимизация производительности](tutorial-performance-tuning.md)
* [Окружение виртуального хостинга](tutorial-shared-hosting.md)
* [Шаблонизаторы](tutorial-template-engines.md)
* [Работа со сторонним кодом](tutorial-yii-integration.md)
* [Использование Yii в качестве микро-framework'а](tutorial-yii-as-micro-framework.md)


Виджеты
-------

* [GridView](https://www.yiiframework.com/doc-2.0/yii-grid-gridview.html)
* [ListView](https://www.yiiframework.com/doc-2.0/yii-widgets-listview.html)
* [DetailView](https://www.yiiframework.com/doc-2.0/yii-widgets-detailview.html)
* [ActiveForm](https://www.yiiframework.com/doc-2.0/guide-input-forms.html#activerecord-based-forms-activeform)
* [Pjax](https://www.yiiframework.com/doc-2.0/yii-widgets-pjax.html)
* [Menu](https://www.yiiframework.com/doc-2.0/yii-widgets-menu.html)
* [LinkPager](https://www.yiiframework.com/doc-2.0/yii-widgets-linkpager.html)
* [LinkSorter](https://www.yiiframework.com/doc-2.0/yii-widgets-linksorter.html)
* [Виджеты Bootstrap](https://github.com/yiisoft/yii2-bootstrap/blob/master/docs/guide-ru/README.md)
* [Виджеты Jquery UI](https://github.com/yiisoft/yii2-jui/blob/master/docs/guide-ru/README.md)


Хелперы
-------

* [Обзор](helper-overview.md)
* [ArrayHelper](helper-array.md)
* [Html](helper-html.md)
* [Json](helper-json.md)
* [Url хелпер](helper-url.md)

---

### Overview (`docs/guide-tr/README.md`)

Yii 2.0 için Açıklayıcı Rehber
==============================

Bu döküman, [Yii Dökümantasyon Koşulları](https://www.yiiframework.com/doc/terms/) altında yayınlandı.

Tüm hakları saklıdır.

2014 (c) Yii Software LLC.


Giriş
------------

* [Yii hakkında](intro-yii.md)
* [Sürüm 1.1'den yükseltme](intro-upgrade-from-v1.md)


Başlarken
---------------

* [Ne bilmeye ihtiyacın var](start-prerequisites.md)
* [Yii Kurulumu](start-installation.md)
* [Uygulamaları Çalıştırmak](start-workflow.md)
* [Merhaba deyin](start-hello.md)
* [Formlarla Çalışırken](start-forms.md)
* [Veritabanıyla Çalışırken](start-databases.md)
* [Gii ile Kod Oluşturmak](start-gii.md)
* [İleriye Bakmak](start-looking-ahead.md)


Uygulama Yapısı
---------------------

* [Uygulama Yapısına Genel Bakış](structure-overview.md)
* [Giriş Komutları](structure-entry-scripts.md)
* [Uygulamalar](structure-applications.md)
* [Uygulama Bileşenleri](structure-application-components.md)
* [Kontrolcüler](structure-controllers.md)
* [Modeller](structure-models.md)
* [Görünümler](structure-views.md)
* [Modüller](structure-modules.md)
* [Filtreler](structure-filters.md)
* [Araçlar](structure-widgets.md)
* [Varlıklar](structure-assets.md)
* [Uzantılar](structure-extensions.md)


İstekleri İşlemek
-----------------

* [İstekleri İşlemeye Genel Bakış](runtime-overview.md)
* [Bootstrapping](runtime-bootstrapping.md)
* [Yönlendirme ve URL Oluşturma](runtime-routing.md)
* [İstekler](runtime-requests.md)
* [Yanıtlar](runtime-responses.md)
* [Oturumlar ve Çerezler](runtime-sessions-cookies.md)
* [Hataları İşleme](runtime-handling-errors.md)
* [Logging](runtime-logging.md)


Anahtar Kavramlar
------------

* [Bileşenler](concept-components.md)
* [Özellikler](concept-properties.md)
* [Olaylar](concept-events.md)
* [Davranışlar](concept-behaviors.md)
* [Yapılandırmalar](concept-configurations.md)
* [Takma Adlar](concept-aliases.md)
* [Sınıf Otomatik Yüklemesi](concept-autoloading.md)
* [Servis Bulucu](concept-service-locator.md)
* [Dependency Injection Container](concept-di-container.md)


Veritabanıyla Çalışırken
----------------------

* [Veritabanı Erişim Nesneleri](db-dao.md): Bir veritabanına bağlanmak, basit sorgular, işlemler ve şema manipilasyonu
* [Sorgu Oluşturucu](db-query-builder.md): Basit bir ayırma katmanı kullanarak veritabanı sorgulama
* [Active Record](db-active-record.md): Active Record ORM, kayıtları almak, değiştirmek ve ilişkileri tanımlama
* [Taşıma İşlemleri](db-migrations.md): Bir takım geliştirme ortamında sürüm kontrolünü veritabanlarına uygula
* [Sphinx](https://www.yiiframework.com/extension/yiisoft/yii2-sphinx/doc/guide)
* [Redis](https://www.yiiframework.com/extension/yiisoft/yii2-redis/doc/guide)
* [MongoDB](https://www.yiiframework.com/extension/yiisoft/yii2-mongodb/doc/guide)
* [ElasticSearch](https://www.yiiframework.com/extension/yiisoft/yii2-elasticsearch/doc/guide)


Kullanıcılardan Veri Alırken
-----------------------

* [Form Oluşturma](input-forms.md)
* [Veri Kontrolü](input-validation.md)
* [Dosya Yükleme](input-file-upload.md)
* [Collecting Tabular Input](input-tabular-input.md)
* [Birden fazla Model için Veri Alma](input-multiple-models.md)
* [Extending ActiveForm on the Client Side](input-form-javascript.md)


Veriyi Gösterirken
---------------

* [Veri Tipini Değiştirme](output-formatting.md)
* [Sayfalama](output-pagination.md)
* [Sıralama](output-sorting.md)
* [Veri Sağlayıcıları](output-data-providers.md)
* [Veri Araçları](output-data-widgets.md)
* [Scriptlerle Çalışmak](output-client-scripts.md)
* [Tema Kullanımı](output-theming.md)


Güvenlik
--------

* [Güvenliğe Genel Bakış](security-overview.md)
* [Kimlik Denetleme](security-authentication.md)
* [Yetkilendirme](security-authorization.md)
* [Şifrelerle Çalışma](security-passwords.md)
* [Kriptografi](security-cryptography.md)
* [Auth Clients](https://www.yiiframework.com/extension/yiisoft/yii2-authclient/doc/guide)
* [Egzersizler](security-best-practices.md)


Cache Almak
-------

* [Cache Genel Bakış](caching-overview.md)
* [Veriyi Cache Alma](caching-data.md)
* [Sayfanın Sadece Bir Kısmını Cache Alma](caching-fragment.md)
* [Sayfanın Tamamını Cache Alma](caching-page.md)
* [HTTP Cache Alma](caching-http.md)


RESTful Web Servisleri
--------------------

* [Hızlı Başlangıç](rest-quick-start.md)
* [Kaynaklar](rest-resources.md)
* [Kontrolcüler](rest-controllers.md)
* [Rota Yöntemleri](rest-routing.md)
* [Yanıt Formatlama](rest-response-formatting.md)
* [Kimlik Denetleme](rest-authentication.md)
* [İstek Sınırlama](rest-rate-limiting.md)
* [Sürümlere Ayırma](rest-versioning.md)
* [Hataları Kullanma](rest-error-handling.md)


Geliştirici Araçları
-----------------

* [Geliştirici Aracı ve Debugger](https://www.yiiframework.com/extension/yiisoft/yii2-debug/doc/guide)
* [Gii'yi Kullanarak Kod Oluşturmak](https://www.yiiframework.com/extension/yiisoft/yii2-gii/doc/guide)
* [API Dökümanı Oluşturma](https://www.yiiframework.com/extension/yiisoft/yii2-apidoc)


Test
-------

* [Testlere Genel Bakış](test-overview.md)
* [Testler için Ortam Kurulumu](test-environment-setup.md)
* [Unit Testleri](test-unit.md)
* [Fonksiyonel Testler](test-functional.md)
* [Kabul Testleri](test-acceptance.md)
* [Fixtures](test-fixtures.md)


Özel Başlıklar
--------------

* [Gelişmiş Proje Şablonu](https://www.yiiframework.com/extension/yiisoft/yii2-app-advanced/doc/guide)
* [Building Application from Scratch](tutorial-start-from-scratch.md)
* [Konsol Komutları](tutorial-console.md)
* [Core Validators](tutorial-core-validators.md)
* [Docker](tutorial-docker.md)
* [Uluslararası Hale Getirme](tutorial-i18n.md)
* [Mail Gönderme](tutorial-mailing.md)
* [Performans Ayarları](tutorial-performance-tuning.md)
* [Paylaşımlı Sunucu Ortamı](tutorial-shared-hosting.md)
* [Şablon Motoru](tutorial-template-engines.md)
* [3. Parti Kodlarla Çalışma](tutorial-yii-integration.md)
* [Yii'yi Mikro Kütüphane Gibi Kullanma](tutorial-yii-as-micro-framework.md)


Araçlar
-------

* [GridView](https://www.yiiframework.com/doc-2.0/yii-grid-gridview.html)
* [ListView](https://www.yiiframework.com/doc-2.0/yii-widgets-listview.html)
* [DetailView](https://www.yiiframework.com/doc-2.0/yii-widgets-detailview.html)
* [ActiveForm](https://www.yiiframework.com/doc-2.0/guide-input-forms.html#activerecord-based-forms-activeform)
* [Pjax](https://www.yiiframework.com/doc-2.0/yii-widgets-pjax.html)
* [Menu](https://www.yiiframework.com/doc-2.0/yii-widgets-menu.html)
* [LinkPager](https://www.yiiframework.com/doc-2.0/yii-widgets-linkpager.html)
* [LinkSorter](https://www.yiiframework.com/doc-2.0/yii-widgets-linksorter.html)
* [Bootstrap Widgets](https://www.yiiframework.com/extension/yiisoft/yii2-bootstrap/doc/guide)
* [jQuery UI Widgets](https://www.yiiframework.com/extension/yiisoft/yii2-jui/doc/guide)


Yardımcılar
-------

* [Helpers Overview](helper-overview.md)
* [ArrayHelper](helper-array.md)
* [Html](helper-html.md)
* [Url](helper-url.md)

---

### Overview (`docs/guide-uk/README.md`)

Повний посібник з Yii 2.0
=========================

Даний посібник випущено відповідно до [положень про документацію Yii](https://www.yiiframework.com/doc/terms/).

All Rights Reserved.

2014 (c) Yii Software LLC.


Введення
--------

* [Про Yii](intro-yii.md)
* [Оновлення із версії 1.1](intro-upgrade-from-v1.md)


Перше знайомство
----------------

* [Встановлення Yii](start-installation.md)
* [Виконання додатків](start-workflow.md)
* [Говоримо "Привіт"](start-hello.md)
* [Робота з формами](start-forms.md)
* [Робота з базами даних](start-databases.md)
* [Генерування коду за допомогою Gii](start-gii.md)
* [Наступні кроки](start-looking-ahead.md)


Структура додатка
-----------------

* [Огляд](structure-overview.md)
* [Вхідні скрипти](structure-entry-scripts.md)
* [Додатки](structure-applications.md)
* [Компоненти додатка](structure-application-components.md)
* [Контролери](structure-controllers.md)
* [Моделі](structure-models.md)
* **TBD** [Представлення](structure-views.md)
* **TBD** [Модулі](structure-modules.md)
* **TBD** [Фільтри](structure-filters.md)
* **TBD** [Віджети](structure-widgets.md)
* **TBD** [Ресурси](structure-assets.md)
* **TBD** [Розширення](structure-extensions.md)


Обробка запитів
---------------

* **TBD** [Огляд](runtime-overview.md)
* **TBD** [Початкове завантаження](runtime-bootstrapping.md)
* **TBD** [Маршрутизація та створення URL](runtime-routing.md)
* **TBD** [Запити](runtime-requests.md)
* **TBD** [Відповіді](runtime-responses.md)
* **TBD** [Сесії та кукі](runtime-sessions-cookies.md)
* **TBD** [Обробка помилок](runtime-handling-errors.md)
* **TBD** [Журналювання](runtime-logging.md)


Основні поняття
---------------

* **TBD** [Компоненти](concept-components.md)
* **TBD** [Властивості](concept-properties.md)
* **TBD** [Події](concept-events.md)
* **TBD** [Поведінки](concept-behaviors.md)
* **TBD** [Конфігурації](concept-configurations.md)
* [Псевдоніми](concept-aliases.md)
* [Автозавантаження класів](concept-autoloading.md)
* **TBD** [Локатор служб](concept-service-locator.md)
* **TBD** [Dependency Injection Container](concept-di-container.md)


Робота з базами даних
---------------------

* **TBD** [Обʼєкти доступу до даних (DAO)](db-dao.md): Зʼєднання з базою даних, прості запити, транзакції і робота зі схемою
* **TBD** [Конструктор запитів](db-query-builder.md): Запити до бази даних через простий шар абстракції
* **TBD** [Active Record](db-active-record.md): Отримання обʼєктів AR, робота з ними та визначення звʼязків
* **TBD** [Міграції](db-migrations.md): Контроль версій схеми даних при роботі в команді
* [Sphinx](https://github.com/yiisoft/yii2-sphinx/blob/master/docs/guide/README.md)
* [Redis](https://github.com/yiisoft/yii2-redis/blob/master/docs/guide/README.md)
* [MongoDB](https://github.com/yiisoft/yii2-mongodb/blob/master/docs/guide/README.md)
* [ElasticSearch](https://github.com/yiisoft/yii2-elasticsearch/blob/master/docs/guide/README.md)


Отримання даних від користувача
-------------------------------

* **TBD** [Створення форм](input-forms.md)
* **TBD** [Перевірка вводу](input-validation.md)
* **TBD** [Завантаження файлів](input-file-uploading.md)
* **TBD** [Збір табличного вводу](input-tabular-input.md)
* **TBD** [Робота з декількома моделями](input-multiple-models.md)


Відображення даних
------------------

* **TBD** [Форматування даних](output-formatting.md)
* **TBD** [Розділення на сторінки](output-pagination.md)
* **TBD** [Сортування](output-sorting.md)
* **TBD** [Провайдери даних](output-data-providers.md)
* **TBD** [Віджети даних](output-data-widgets.md)
* **TBD** [Робота з клієнтськими скриптами](output-client-scripts.md)
* **TBD** [Темізація](output-theming.md)


Безпека
-------

* **TBD** [Аутентифікація](security-authentication.md)
* **TBD** [Авторизація](security-authorization.md)
* **TBD** [Робота з паролями](security-passwords.md)
* [Клієнти авторизації](https://github.com/yiisoft/yii2-authclient/blob/master/docs/guide/README.md)
* **TBD** [Кращі практики](security-best-practices.md)


Кешування
---------

* **TBD** [Огляд](caching-overview.md)
* **TBD** [Кешування даних](caching-data.md)
* [Кешування фрагментів](caching-fragment.md)
* **TBD** [Кешування сторінок](caching-page.md)
* **TBD** [HTTP кешування](caching-http.md)


Веб-сервіси RESTful
-------------------

* [Швидкий старт](rest-quick-start.md)
* **TBD** [Ресурси](rest-resources.md)
* **TBD** [Контролери](rest-controllers.md)
* **TBD** [Маршрутизація](rest-routing.md)
* **TBD** [Форматування відповіді](rest-response-formatting.md)
* **TBD** [Аутентифікація](rest-authentication.md)
* [Обмеження частоти запитів](rest-rate-limiting.md)
* **TBD** [Версіонування](rest-versioning.md)
* **TBD** [Обробка помилок](rest-error-handling.md)


Інструменти розробника
----------------------

* [Панель налагодження та налагоджувач](https://github.com/yiisoft/yii2-debug/blob/master/docs/guide-uk/README.md)
* [Генерування коду за допомогою Gii](https://github.com/yiisoft/yii2-gii/blob/master/docs/guide-uk/README.md)
* **TBD** [Генерування документації API](https://github.com/yiisoft/yii2-apidoc)


Тестування
----------

* **TBD** [Огляд](test-overview.md)
* **TBD** [Налаштування середовища тестування](test-environment-setup.md)
* **TBD** [Модульні тести](test-unit.md)
* **TBD** [Функціональні тести](test-functional.md)
* **TBD** [Приймальні тести](test-acceptance.md)
* **TBD** [Фікстури](test-fixtures.md)


Спеціальні теми
---------------

* **TBD** [Розширений шаблон проекту](https://github.com/yiisoft/yii2-app-advanced/blob/master/docs/guide-uk/README.md)
* [Створення додатка з нуля](tutorial-start-from-scratch.md)
* [Консольні додатки](tutorial-console.md)
* **TBD** [Основні валідатори](tutorial-core-validators.md)
* **TBD** [Інтернаціоналізація](tutorial-i18n.md)
* **TBD** [Робота з поштою](tutorial-mailing.md)
* **TBD** [Покращення швидкодії](tutorial-performance-tuning.md)
* **TBD** [Робота на віртуальному хостингу](tutorial-shared-hosting.md)
* [Шаблонізатори](tutorial-template-engines.md)
* [Робота із стороннім кодом](tutorial-yii-integration.md)


Віджети
-------

* GridView: **TBD** link to demo page
* ListView: **TBD** link to demo page
* DetailView: **TBD** link to demo page
* ActiveForm: **TBD** link to demo page
* Pjax: **TBD** link to demo page
* Menu: **TBD** link to demo page
* LinkPager: **TBD** link to demo page
* LinkSorter: **TBD** link to demo page
* [Віджети Bootstrap](https://github.com/yiisoft/yii2-bootstrap/blob/master/docs/guide-uk/README.md)
* [Віджети jQuery UI](https://github.com/yiisoft/yii2-jui/blob/master/docs/guide-uk/README.md)


Хелпери
-------

* **TBD** [Огляд хелперів](helper-overview.md)
* **TBD** [ArrayHelper](helper-array.md)
* **TBD** [Html](helper-html.md)
* **TBD** [Url](helper-url.md)

---

### Overview (`docs/guide-uz/README.md`)

Yii 2.0 bo'yicha to'liq qo'llanma
=================================

Ushbu qo'llanma [Yii qo'llanmalarining holati](https://www.yiiframework.com/doc/terms/) bilan mos holda yo'lga qo'yildi.

All Rights Reserved.

2014 © Yii Software LLC.

Kirish
------

* [Yii haqida](intro-yii.md)
* [1.1 dan keyingi yangilanishlar](intro-upgrade-from-v1.md)


Birinchi tanishuv
-----------------

* [Yii ni o'rnatish](start-installation.md)
* [Ilovani ishga tushirish](start-workflow.md)
* [«Salom» deymiz](start-hello.md)
* [Formalar bilan ishlash](start-forms.md)
* [Ma'lumotlar ombori bilan ishlash](start-databases.md)
* [Gii yordamida kodlarni generatsiya qilish](start-gii.md)
* [Keyin nima?](start-looking-ahead.md)


Ilova strukturasi
-----------------

* [Sharh](structure-overview.md)
* [Kirish skriptlari](structure-entry-scripts.md)
* [Ilova](structure-applications.md)
* [Ilova komponentlari](structure-application-components.md)
* [Kontrollyorlar](structure-controllers.md)
* [Namoyish](structure-views.md)
* [Modellar](structure-models.md)
* **TBD** [Filtrlar](structure-filters.md)
* **TBD** [Vidjetlar](structure-widgets.md)
* **TBD** [Modullar](structure-modules.md)
* [Resurslar](structure-assets.md)
* **TBD** [Kengaytmalar](structure-extensions.md)


So'rovlarni qayta ishlash
-------------------------

* **TBD** [Bootstrapping](runtime-bootstrapping.md)
* **TBD** [Routing](runtime-routing.md)
* **TBD** [So'rovlar](runtime-requests.md)
* **TBD** [Javoblar](runtime-responses.md)
* **TBD** [Sessiyalar va kuklar](runtime-sessions-cookies.md)
* [URL ni tahlil va generatsiya qilish](runtime-url-handling.md)
* [Xatoliklarni qayta ishlash](runtime-handling-errors.md)
* [Jurnallarga yozish](runtime-logging.md)


Asosiy tushunchalar
-------------------

* [Komponentlar](concept-components.md)
* [Xususiyat](concept-properties.md)
* [Xodisa](concept-events.md)
* [O'zini tutish](concept-behaviors.md)
* [Muhim sozlashlar](concept-configurations.md)
* [Taxalluslar](concept-aliases.md)
* [Sinflarni avtoyuklash](concept-autoloading.md)
* [Service Locator](concept-service-locator.md)
* [Dependency Injection Container](concept-di-container.md)


Ma'lumotlar ombori bilan ishlash
--------------------------------

* [Ma'lumotlar bilan ishlashga imkon beruvchi obektlar(DAO)](db-dao.md) - Ma'lumotlar ombori bilan bog'lanish, oddiy so'rovlar, tranzaksiya va sxema bilan ishlash.
* [So'rovlarni yaratuvchi](db-query-builder.md) - Ma'lumotlar omboriga abstraksiyaning oddiy qatlamidan so'rovlar.
* [Active Record](db-active-record.md) - AR obektlarini  olish, ular bilan ishlash va bog'lanishlarni aniqlash.
* [Migratsiyalar](db-migrations.md) - Komandada (jamoada) ishlaganda ma'lumotlar sxemasini talqinlarini boshqarish.
* **TBD** [Sphinx](db-sphinx.md)
* **TBD** [Redis](db-redis.md)
* **TBD** [MongoDB](db-mongodb.md)
* **TBD** [ElasticSearch](db-elastic-search.md)


Foydalanuvchidan ma'lumotlarni qabul qilish
-------------------------------------------

* [Formani yaratish](input-forms.md)
* [Validatsiya](input-validation.md)
* **TBD** [Fayllarni yuklash](input-file-uploading.md)
* **TBD** [Bir nechta modellar bilan ishlash](input-multiple-models.md)


Ma'lumotlarni namoyish etish
----------------------------

* **TBD** [Ma'lumotlarni formatlash](output-formatting.md)
* **TBD** [Sahifalar bo'yicha ajratish](output-pagination.md)
* **TBD** [Saralash](output-sorting.md)
* [Ma'lumotlar provayderlari](output-data-providers.md)
* [Ma'lumotlar uchun vidjetlar](output-data-widgets.md)
* [Mavzulashtirish](output-theming.md)


Xavfsizlik
----------

* [Autentifikatsiya](security-authentication.md)
* [Avtorizatsiya](security-authorization.md)
* [Parollar bilan ishlash](security-passwords.md)
* **TBD** [Avtorizatsiya mijozlari](security-auth-clients.md)
* **TBD** [Eng yaxshi amaliyotlar](security-best-practices.md)


Keshlash
--------

* [Sharh](caching-overview.md)
* [Ma'lumotlarni keshlash](caching-data.md)
* [Fragmentlarni keshlash](caching-fragment.md)
* [Sahifalarni keshlash](caching-page.md)
* [HTTP ni keshlash](caching-http.md)


REST web-xizmatlari
-------------------

* [Tezkor boshlash](rest-quick-start.md)
* [Resurslar](rest-resources.md)
* [Kontrollyorlar](rest-controllers.md)
* [Routing](rest-routing.md)
* [Javoblarni formatlash](rest-response-formatting.md)
* [Autentifikatsiya](rest-authentication.md)
* [So'rovlarni chastotasini chegaralash](rest-rate-limiting.md)
* [Talqin yaratish](rest-versioning.md)
* [Xatoliklarni qayta ishlash](rest-error-handling.md)


Ishlab chiquvchining uskunalari
---------------------------

* [Qayta ishlash paneli va qayta ishlovchi](tool-debugger.md)
* [Gii bilan kodni generatsiya qilish](tool-gii.md)
* **TBD** [API qo'llanmani generatori](tool-api-doc.md)


Test o'tkazish
--------------

* [Sharh](test-overview.md)
* **TBD** [MOdulli testlar](test-unit.md)
* **TBD** [Funksional testlar](test-functional.md)
* **TBD** [Qabul qiluvchi testlar](test-acceptance.md)
* [Fiksturalar](test-fixtures.md)


Yii kengaytmalari
-----------------

* [Kengaytmani yaratish](extend-creating-extensions.md)
* [Freymvork kodini kengaytirish](extend-customizing-core.md)
* [Tashqi kutubxonalarni qo'llash](extend-using-libs.md)
* **TBD** [Tashqi tizimlarda Yii integratsiyasi](extend-embedding-in-others.md)
* **TBD** [Yii 1.1 va 2.0 larni bir vaqtda ishlatish](extend-using-v1-v2.md)
* [Composer ni ishlatish](extend-using-composer.md)


Maxsus mavzular
---------------

* [advanced ilova shabloni](tutorial-advanced-app.md)
* [Ilovani noldan yaratish](tutorial-start-from-scratch.md)
* [Konsol komandalari](tutorial-console.md)
* [Xalqarolashtirish](tutorial-i18n.md)
* [Pochta yuborish](tutorial-mailing.md)
* [Ish inumdorligini oshirish](tutorial-performance-tuning.md)
* **TBD** [shared xostingida ishlash](tutorial-shared-hosting.md)
* [Shablonlashtiruvchilar](tutorial-template-engines.md)


Vidjetlar
---------

* GridView: link to demo page
* ListView: link to demo page
* DetailView: link to demo page
* ActiveForm: link to demo page
* Pjax: link to demo page
* Menu: link to demo page
* LinkPager: link to demo page
* LinkSorter: link to demo page
* [Bootstrap vidjetlari](bootstrap-widgets.md)
* **TBD** [Jquery UI vidjetlari](jui-widgets.md)


Xelperlar
---------

* [Sharh](helper-overview.md)
* **TBD** [ArrayHelper](helper-array.md)
* **TBD** [Html](helper-html.md)
* **TBD** [Url](helper-url.md)
* **TBD** [Security](helper-security.md)

---

### Overview (`docs/guide-vi/README.md`)

The Definitive Guide to Yii 2.0
===============================

Các hướng dẫn được phát hành theo [Các điều khoản về tài liệu Yii](https://www.yiiframework.com/doc/terms/).

Tất cả bản quyền đã được bảo hộ (All Rights Reserved).

2014 (c) Yii Software LLC.


Giới thiệu
------------

* [Về Yii](intro-yii.md)
* [Hướng dẫn nâng cấp lên từ phiên bản 1.1](intro-upgrade-from-v1.md)


Bắt đầu
---------------

* [Những gì bạn cần biết](start-prerequisites.md)
* [Cài đặt Yii](start-installation.md)
* [Thực hiện chạy ứng dụng](start-workflow.md)
* [Viết chương trình đầu tiên](start-hello.md)
* [Làm việc với Forms](start-forms.md)
* [Làm việc với Databases](start-databases.md)
* [Sử dụng Gii để sinh mã tự động](start-gii.md)
* [Nâng cao](start-looking-ahead.md)


Kiến trúc ứng dụng (Application Structure)
---------------------

* [Tổng quan về kiến trúc ứng dụng](structure-overview.md)
* [Mục Scripts](structure-entry-scripts.md)
* [Ứng dụng (Applications)](structure-applications.md)
* [Các thành phần bên trong ứng dụng](structure-application-components.md)
* [Controllers](structure-controllers.md)
* [Models](structure-models.md)
* [Views](structure-views.md)
* [Modules](structure-modules.md)
* [Bộ lọc (Filters)](structure-filters.md)
* [Widgets](structure-widgets.md)
* [Assets](structure-assets.md)
* [Phần mở rộng (Extensions)](structure-extensions.md)


Xử lý yêu cầu (Handling Requests)
-----------------

* [Tổng quan](runtime-overview.md)
* [Khởi động](runtime-bootstrapping.md)
* [Định tuyến (Routing) và khởi tạo đường dẫn (URL Creation)](runtime-routing.md)
* [Yêu cầu (Requests)](runtime-requests.md)
* [Kết quả (Responses)](runtime-responses.md)
* [Sessions và Cookies](runtime-sessions-cookies.md)
* [Xử lý lỗi (Handling Error)](runtime-handling-errors.md)
* [Logging](runtime-logging.md)


Các khái niệm chính
------------

* [Thành phần (Components)](concept-components.md)
* [Thuộc tính (Properties)](concept-properties.md)
* [Sự kiện (Events)](concept-events.md)
* [Hành vi (Behaviors)](concept-behaviors.md)
* [Cấu hình (Configurations)](concept-configurations.md)
* [Bí danh (Aliases)](concept-aliases.md)
* [Lớp tự động nạp (Autoloading)](concept-autoloading.md)
* [Service Locator](concept-service-locator.md)
* [Dependency Injection Container](concept-di-container.md)


Làm việc với Databases
----------------------

* [Data Access Objects](db-dao.md): Kết nối cơ sở dữ liệu, truy vấn cơ bản, giao dịch và phương thức hoạt động
* [Query Builder](db-query-builder.md): Sử dụng một truy vấn đơn giản, các lớp cơ sở dữ liệu trừu tượng
* [Active Record](db-active-record.md): The Active Record ORM, truy vấn và thao tác với dữ liệu, định nghĩa các mối quan hệ giữa các bảng
* [Migrations](db-migrations.md): Cung cấp cho đội dự án một công cụ dễ dàng trong việc quản lý những schema CSDL trong ứng dụng
* [Sphinx](https://www.yiiframework.com/extension/yiisoft/yii2-sphinx/doc/guide)
* [Redis](https://www.yiiframework.com/extension/yiisoft/yii2-redis/doc/guide)
* [MongoDB](https://www.yiiframework.com/extension/yiisoft/yii2-mongodb/doc/guide)
* [ElasticSearch](https://www.yiiframework.com/extension/yiisoft/yii2-elasticsearch/doc/guide)


Nhận dữ liệu từ user
-----------------------

* [Tạo mới Forms](input-forms.md)
* [Kiểm tra dữ liệu đầu vào (Validating Input)](input-validation.md)
* [File Upload](input-file-upload.md)
* [Thu thập dữ liệu từ danh sách đầu vào (Đang phát triển)](input-tabular-input.md)
* [Lấy dữ liệu cho nhiều Models (Chưa giải quyết)](input-multiple-models.md)
* [Mở rộng ActiveForm ở phía Máy khách](input-form-javascript.md)


Hiển thị dữ liệu
---------------

* [Định dạng dữ liệu (Data Formatting)](output-formatter.md)
* [Phân trang (Pagination)](output-pagination.md)
* [Sắp xếp (Sorting)](output-sorting.md)
* [Cung cấp dữ liệu ra (Data Providers)](output-data-providers.md)
* [Dữ liệu Widgets](output-data-widgets.md)
* [làm việc với Client Scripts](output-client-scripts.md)
* [Giao diện (Theming)](output-theming.md)


Bảo mật (Security)
--------

* [Xác thực (Authentication)](security-authentication.md)
* [Quyền (Authorization)](security-authorization.md)
* [Các thao tác xử lý với Passwords (Đang phát triển)](security-passwords.md)
* [Auth Clients](https://www.yiiframework.com/extension/yiisoft/yii2-authclient/doc/guide)
* [Best Practices](security-best-practices.md)


Bộ nhớ Cache
-------

* [Tổng quan](caching-overview.md)
* [Cache dữ liệu](caching-data.md)
* [Fragment Caching](caching-fragment.md)
* [Page Caching](caching-page.md)
* [HTTP Caching](caching-http.md)


RESTful Web Services
--------------------

* [Bắt đầu](rest-quick-start.md)
* [Tài nguyên (Resources)](rest-resources.md)
* [Bộ điều khiển (Controllers)](rest-controllers.md)
* [Routing](rest-routing.md)
* [Định dạng thông điệp gửi đi (Response Formatting)](rest-response-formatting.md)
* [Xác thực (Authentication)](rest-authentication.md)
* [Rate Limiting](rest-rate-limiting.md)
* [Phiên bản (Version)](rest-versioning.md)
* [Error Handling](rest-error-handling.md)


Công cụ phát triển (Development Tools)
-----------------

* [Thanh công cụ gỡ lỗi và sửa lỗi (Debug Toolbar và Debugger)](https://www.yiiframework.com/extension/yiisoft/yii2-debug/doc/guide)
* [Sử dụng Gii để tạo code](https://www.yiiframework.com/extension/yiisoft/yii2-gii/doc/guide)
* [Tạo tài liệu về API ](https://www.yiiframework.com/extension/yiisoft/yii2-apidoc)


Testing
-------

* [Tổng quan](test-overview.md)
* [Thiết lập môi trường](test-environment-setup.md)
* [Unit Tests](test-unit.md)
* [Kiểm tra chức năng (Functional Tests)](test-functional.md)
* [Acceptance Tests](test-acceptance.md)
* [Fixtures](test-fixtures.md)


Chủ đề năng cao
--------------

* [Advanced Application Template](https://www.yiiframework.com/extension/yiisoft/yii2-app-advanced/doc/guide)
* [Building Application from Scratch](tutorial-start-from-scratch.md)
* [Giao diện dòng lệnh (Console Commands)](tutorial-console.md)
* [Core Validators](tutorial-core-validators.md)
* [Quốc tế hóa (Internationalization)](tutorial-i18n.md)
* [Thư (Mailing)](tutorial-mailing.md)
* [Tối ưu hiệu năng ứng dụng (Performance Tuning)](tutorial-performance-tuning.md)
* [Shared Hosting Environment](tutorial-shared-hosting.md)
* [Template Engines](tutorial-template-engines.md)
* [Tích hợp mã nguồn của bên thứ ba (Working with Third-Party Code)](tutorial-yii-integration.md)
* [Dùng Yii như các framework nhỏ](tutorial-yii-as-micro-framework.md)


Widgets
-------

* [GridView](https://www.yiiframework.com/doc-2.0/yii-grid-gridview.html)
* [ListView](https://www.yiiframework.com/doc-2.0/yii-widgets-listview.html)
* [DetailView](https://www.yiiframework.com/doc-2.0/yii-widgets-detailview.html)
* [ActiveForm](https://www.yiiframework.com/doc-2.0/guide-input-forms.html#activerecord-based-forms-activeform)
* [Pjax](https://www.yiiframework.com/doc-2.0/yii-widgets-pjax.html)
* [Menu](https://www.yiiframework.com/doc-2.0/yii-widgets-menu.html)
* [LinkPager](https://www.yiiframework.com/doc-2.0/yii-widgets-linkpager.html)
* [LinkSorter](https://www.yiiframework.com/doc-2.0/yii-widgets-linksorter.html)
* [Bootstrap Widgets](https://www.yiiframework.com/extension/yiisoft/yii2-bootstrap/doc/guide)
* [jQuery UI Widgets](https://www.yiiframework.com/extension/yiisoft/yii2-jui/doc/guide)


Helpers
-------

* [Tổng quan](helper-overview.md)
* [ArrayHelper](helper-array.md)
* [Html](helper-html.md)
* [Url](helper-url.md)

---

### Overview (`docs/guide-zh-CN/README.md`)

Yii 2.0 权威指南
===============================

本教程的发布遵循 [Yii 文档使用许可](https://www.yiiframework.com/doc/terms/)。

版权所有。

2014 (c) Yii Software LLC。


介绍（Introduction）
------------------

* [关于 Yii（About Yii）](intro-yii.md)
* [从 Yii 1.1 升级（Upgrading from Version 1.1）](intro-upgrade-from-v1.md)


入门（Getting Started）
---------------------

* [你需要了解什么（What do you need to know）](start-prerequisites.md)
* [安装 Yii（Installing Yii）](start-installation.md)
* [运行应用（Running Applications）](start-workflow.md)
* [第一次问候（Saying Hello）](start-hello.md)
* [使用 Forms（Working with Forms）](start-forms.md)
* [玩转 Databases（Working with Databases）](start-databases.md)
* [用 Gii 生成代码（Generating Code with Gii）](start-gii.md)
* [更上一层楼（Looking Ahead）](start-looking-ahead.md)


应用结构（Application Structure）
------------------------------

* [结构概述（Overview）](structure-overview.md)
* [入口脚本（Entry Scripts）](structure-entry-scripts.md)
* [应用（Applications）](structure-applications.md)
* [应用组件（Application Components）](structure-application-components.md)
* [控制器（Controllers）](structure-controllers.md)
* [模型（Models）](structure-models.md)
* [视图（Views）](structure-views.md)
* [模块（Modules）](structure-modules.md)
* [过滤器（Filters）](structure-filters.md)
* [小部件（Widgets）](structure-widgets.md)
* [前端资源（Assets）](structure-assets.md)
* [扩展（Extensions）](structure-extensions.md)


请求处理（Handling Requests）
--------------------------

* [运行概述（Overview）](runtime-overview.md)
* [引导（Bootstrapping）](runtime-bootstrapping.md)
* [路由引导与创建 URL（Routing and URL Creation）](runtime-routing.md)
* [请求（Requests）](runtime-requests.md)
* [响应（Responses）](runtime-responses.md)
* [Sessions and Cookies](runtime-sessions-cookies.md)
* [错误处理（Handling Errors）](runtime-handling-errors.md)
* [日志（Logging）](runtime-logging.md)


关键概念（Key Concepts）
---------------------

* [组件（Components）](concept-components.md)
* [属性（Properties）](concept-properties.md)
* [事件（Events）](concept-events.md)
* [行为（Behaviors）](concept-behaviors.md)
* [配置（Configurations）](concept-configurations.md)
* [别名（Aliases）](concept-aliases.md)
* [类自动加载（Class Autoloading）](concept-autoloading.md)
* [服务定位器（Service Locator）](concept-service-locator.md)
* [依赖注入容器（Dependency Injection Container）](concept-di-container.md)


配合数据库工作（Working with Databases）
------------------------------------

* [数据库访问（Data Access Objects）](db-dao.md): 数据库连接、基本查询、事务和模式操作
* [查询生成器（Query Builder）](db-query-builder.md): 使用简单抽象层查询数据库
* [活动记录（Active Record）](db-active-record.md): 活动记录对象关系映射（ORM），检索和操作记录、定义关联关系
* [数据库迁移（Migrations）](db-migrations.md): 在团体开发中对你的数据库使用版本控制
* [Sphinx](https://www.yiiframework.com/extension/yiisoft/yii2-sphinx/doc/guide)
* [Redis（yii2-redis）](https://www.yiiframework.com/extension/yiisoft/yii2-redis/doc/guide/2.0/zh-cn): yii2-redis 扩展详解
* [MongoDB](https://www.yiiframework.com/extension/yiisoft/yii2-mongodb/doc/guide)
* [ElasticSearch](https://www.yiiframework.com/extension/yiisoft/yii2-elasticsearch/doc/guide)


接收用户数据（Getting Data from Users）
------------------------------------

* [创建表单（Creating Forms）](input-forms.md)
* [输入验证（Validating Input）](input-validation.md)
* [文件上传（Uploading Files）](input-file-upload.md)
* [收集列表输入（Collecting Tabular Input）](input-tabular-input.md)
* [多模型同时输入（Getting Data for Multiple Models）](input-multiple-models.md)
* [在客户端扩展 ActiveForm（Extending ActiveForm on the Client Side）](input-form-javascript.md)


显示数据（Displaying Data）
------------------------

* [格式化输出数据（Data Formatting）](output-formatting.md)
* [分页（Pagination）](output-pagination.md)
* [排序（Sorting）](output-sorting.md)
* [数据提供器（Data Providers）](output-data-providers.md)
* [数据小部件（Data Widgets）](output-data-widgets.md)
* [操作客户端脚本（Working with Client Scripts）](output-client-scripts.md)
* [主题（Theming）](output-theming.md)


安全（Security）
--------------

* [概述（Overview）](security-overview.md)
* [认证（Authentication）](security-authentication.md)
* [授权（Authorization）](security-authorization.md)
* [处理密码（Working with Passwords）](security-passwords.md)
* [加密（Cryptography）](security-cryptography.md)
* [客户端认证（Auth Clients）](https://github.com/yiisoft/yii2-authclient/blob/master/docs/guide-zh-CN/README.md)
* [安全领域的最佳实践（Best Practices）](security-best-practices.md)


缓存（Caching）
-------------

* [概述（Overview）](caching-overview.md)
* [数据缓存（Data Caching）](caching-data.md)
* [片段缓存（Fragment Caching）](caching-fragment.md)
* [页面缓存（Page Caching）](caching-page.md)
* [HTTP 缓存（HTTP Caching）](caching-http.md)


RESTful Web 服务（RESTful Web Services）
--------------------------------------

* [快速入门（Quick Start）](rest-quick-start.md)
* [资源（Resources）](rest-resources.md)
* [控制器（Controllers）](rest-controllers.md)
* [路由（Routing）](rest-routing.md)
* [格式化响应（Response Formatting）](rest-response-formatting.md)
* [授权验证（Authentication）](rest-authentication.md)
* [速率限制（Rate Limiting）](rest-rate-limiting.md)
* [版本化（Versioning）](rest-versioning.md)
* [错误处理（Error Handling）](rest-error-handling.md)


开发工具（Development Tools）
--------------------------

* [调试工具栏和调试器（Debug Toolbar and Debugger）](https://github.com/yiisoft/yii2-debug/blob/master/docs/guide-zh-CN/README.md)
* [使用 Gii 生成代码（Generating Code using Gii）](https://github.com/yiisoft/yii2-gii/blob/master/docs/guide-zh-CN/README.md)
* [生成 API 文档（Generating API Documentation）](https://github.com/yiisoft/yii2-apidoc)


测试（Testing）
-------------

* [概述（Overview）](test-overview.md)
* [搭建测试环境（Testing environment setup）](test-environment-setup.md)
* [单元测试（Unit Tests）](test-unit.md)
* [功能测试（Functional Tests）](test-functional.md)
* [验收测试（Acceptance Tests）](test-acceptance.md)
* [测试夹具（Fixtures）](test-fixtures.md)


高级专题（Special Topics）
-----------------------

* [高级应用模版（Advanced Project Template）](https://github.com/yiisoft/yii2-app-advanced/blob/master/docs/guide-zh-CN/README.md)
* [从头构建自定义模版（Building Application from Scratch）](tutorial-start-from-scratch.md)
* [控制台命令（Console Commands）](tutorial-console.md)
* [核心验证器（Core Validators）](tutorial-core-validators.md)
* [Docker](tutorial-docker.md)
* [国际化（Internationalization）](tutorial-i18n.md)
* [收发邮件（Mailing）](tutorial-mailing.md)
* [性能优化（Performance Tuning）](tutorial-performance-tuning.md)
* [共享主机环境（Shared Hosting Environment）](tutorial-shared-hosting.md)
* [模板引擎（Template Engines）](tutorial-template-engines.md)
* [集成第三方代码（Working with Third-Party Code）](tutorial-yii-integration.md)
* [使用 Yii 作为微框架（Using Yii as a micro framework）](tutorial-yii-as-micro-framework.md)


小部件（Widgets）
---------------

* [GridView](https://www.yiiframework.com/doc-2.0/yii-grid-gridview.html)
* [ListView](https://www.yiiframework.com/doc-2.0/yii-widgets-listview.html)
* [DetailView](https://www.yiiframework.com/doc-2.0/yii-widgets-detailview.html)
* [ActiveForm](https://www.yiiframework.com/doc-2.0/guide-input-forms.html#activerecord-based-forms-activeform)
* [Pjax](https://www.yiiframework.com/doc-2.0/yii-widgets-pjax.html)
* [Menu](https://www.yiiframework.com/doc-2.0/yii-widgets-menu.html)
* [LinkPager](https://www.yiiframework.com/doc-2.0/yii-widgets-linkpager.html)
* [LinkSorter](https://www.yiiframework.com/doc-2.0/yii-widgets-linksorter.html)
* [Bootstrap Widgets](https://github.com/yiisoft/yii2-bootstrap/blob/master/docs/guide-zh-CN/README.md)
* [jQuery UI Widgets](https://github.com/yiisoft/yii2-jui/blob/master/docs/guide-zh-CN/README.md)


助手类（Helpers）
---------------

* [助手一览（Overview）](helper-overview.md)
* [Array 助手（ArrayHelper）](helper-array.md)
* [Html 助手（Html）](helper-html.md)
* [Url 助手（Url）](helper-url.md)

---

### Overview (`docs/guide/README.md`)

The Definitive Guide to Yii 2.0
===============================

This tutorial is released under the [Terms of Yii Documentation](https://www.yiiframework.com/doc/terms/).

All Rights Reserved.

2014 (c) Yii Software LLC.


Introduction
------------

* [About Yii](intro-yii.md)
* [Upgrading from Version 1.1](intro-upgrade-from-v1.md)


Getting Started
---------------

* [What do you need to know](start-prerequisites.md)
* [Installing Yii](start-installation.md)
* [Running Applications](start-workflow.md)
* [Saying Hello](start-hello.md)
* [Working with Forms](start-forms.md)
* [Working with Databases](start-databases.md)
* [Generating Code with Gii](start-gii.md)
* [Looking Ahead](start-looking-ahead.md)


Application Structure
---------------------

* [Application Structure Overview](structure-overview.md)
* [Entry Scripts](structure-entry-scripts.md)
* [Applications](structure-applications.md)
* [Application Components](structure-application-components.md)
* [Controllers](structure-controllers.md)
* [Models](structure-models.md)
* [Views](structure-views.md)
* [Modules](structure-modules.md)
* [Filters](structure-filters.md)
* [Widgets](structure-widgets.md)
* [Assets](structure-assets.md)
* [Extensions](structure-extensions.md)


Handling Requests
-----------------

* [Request Handling Overview](runtime-overview.md)
* [Bootstrapping](runtime-bootstrapping.md)
* [Routing and URL Creation](runtime-routing.md)
* [Requests](runtime-requests.md)
* [Responses](runtime-responses.md)
* [Sessions and Cookies](runtime-sessions-cookies.md)
* [Handling Errors](runtime-handling-errors.md)
* [Logging](runtime-logging.md)


Key Concepts
------------

* [Components](concept-components.md)
* [Properties](concept-properties.md)
* [Events](concept-events.md)
* [Behaviors](concept-behaviors.md)
* [Configurations](concept-configurations.md)
* [Aliases](concept-aliases.md)
* [Class Autoloading](concept-autoloading.md)
* [Service Locator](concept-service-locator.md)
* [Dependency Injection Container](concept-di-container.md)


Working with Databases
----------------------

* [Database Access Objects](db-dao.md): Connecting to a database, basic queries, transactions, and schema manipulation
* [Query Builder](db-query-builder.md): Querying the database using a simple abstraction layer
* [Active Record](db-active-record.md): The Active Record ORM, retrieving and manipulating records, and defining relations
* [Migrations](db-migrations.md): Apply version control to your databases in a team development environment
* [Sphinx](https://www.yiiframework.com/extension/yiisoft/yii2-sphinx/doc/guide)
* [Redis](https://www.yiiframework.com/extension/yiisoft/yii2-redis/doc/guide)
* [MongoDB](https://www.yiiframework.com/extension/yiisoft/yii2-mongodb/doc/guide)
* [ElasticSearch](https://www.yiiframework.com/extension/yiisoft/yii2-elasticsearch/doc/guide)


Getting Data from Users
-----------------------

* [Creating Forms](input-forms.md)
* [Validating Input](input-validation.md)
* [Uploading Files](input-file-upload.md)
* [Collecting Tabular Input](input-tabular-input.md)
* [Getting Data for Multiple Models](input-multiple-models.md)
* [Extending ActiveForm on the Client Side](input-form-javascript.md)


Displaying Data
---------------

* [Data Formatting](output-formatting.md)
* [Pagination](output-pagination.md)
* [Sorting](output-sorting.md)
* [Data Providers](output-data-providers.md)
* [Data Widgets](output-data-widgets.md)
* [Working with Client Scripts](output-client-scripts.md)
* [Theming](output-theming.md)


Security
--------

* [Security Overview](security-overview.md)
* [Authentication](security-authentication.md)
* [Authorization](security-authorization.md)
* [Working with Passwords](security-passwords.md)
* [Cryptography](security-cryptography.md)
* [Auth Clients](https://www.yiiframework.com/extension/yiisoft/yii2-authclient/doc/guide)
* [Best Practices](security-best-practices.md)


Caching
-------

* [Caching Overview](caching-overview.md)
* [Data Caching](caching-data.md)
* [Fragment Caching](caching-fragment.md)
* [Page Caching](caching-page.md)
* [HTTP Caching](caching-http.md)


RESTful Web Services
--------------------

* [Quick Start](rest-quick-start.md)
* [Resources](rest-resources.md)
* [Controllers](rest-controllers.md)
* [Filtering Collections](rest-filtering-collections.md)
* [Routing](rest-routing.md)
* [Response Formatting](rest-response-formatting.md)
* [Authentication](rest-authentication.md)
* [Rate Limiting](rest-rate-limiting.md)
* [Versioning](rest-versioning.md)
* [Error Handling](rest-error-handling.md)


Development Tools
-----------------

* [Debug Toolbar and Debugger](https://www.yiiframework.com/extension/yiisoft/yii2-debug/doc/guide)
* [Generating Code using Gii](https://www.yiiframework.com/extension/yiisoft/yii2-gii/doc/guide)
* [Generating API Documentation](https://www.yiiframework.com/extension/yiisoft/yii2-apidoc)


Testing
-------

* [Testing Overview](test-overview.md)
* [Testing environment setup](test-environment-setup.md)
* [Unit Tests](test-unit.md)
* [Functional Tests](test-functional.md)
* [Acceptance Tests](test-acceptance.md)
* [Fixtures](test-fixtures.md)


Special Topics
--------------

* [Advanced Project Template](https://www.yiiframework.com/extension/yiisoft/yii2-app-advanced/doc/guide)
* [Building Application from Scratch](tutorial-start-from-scratch.md)
* [Console Commands](tutorial-console.md)
* [Core Validators](tutorial-core-validators.md)
* [Docker](tutorial-docker.md)
* [Internationalization](tutorial-i18n.md)
* [Mailing](tutorial-mailing.md)
* [Performance Tuning](tutorial-performance-tuning.md)
* [Shared Hosting Environment](tutorial-shared-hosting.md)
* [Template Engines](tutorial-template-engines.md)
* [Working with Third-Party Code](tutorial-yii-integration.md)
* [Using Yii as a micro framework](tutorial-yii-as-micro-framework.md)


Widgets
-------

* [GridView](https://www.yiiframework.com/doc-2.0/yii-grid-gridview.html)
* [ListView](https://www.yiiframework.com/doc-2.0/yii-widgets-listview.html)
* [DetailView](https://www.yiiframework.com/doc-2.0/yii-widgets-detailview.html)
* [ActiveForm](https://www.yiiframework.com/doc-2.0/guide-input-forms.html#activerecord-based-forms-activeform)
* [Pjax](https://www.yiiframework.com/doc-2.0/yii-widgets-pjax.html)
* [Menu](https://www.yiiframework.com/doc-2.0/yii-widgets-menu.html)
* [LinkPager](https://www.yiiframework.com/doc-2.0/yii-widgets-linkpager.html)
* [LinkSorter](https://www.yiiframework.com/doc-2.0/yii-widgets-linksorter.html)
* [Bootstrap Widgets](https://www.yiiframework.com/extension/yiisoft/yii2-bootstrap/doc/guide)
* [jQuery UI Widgets](https://www.yiiframework.com/extension/yiisoft/yii2-jui/doc/guide)


Helpers
-------

* [Helpers Overview](helper-overview.md)
* [ArrayHelper](helper-array.md)
* [Html](helper-html.md)
* [Json](helper-json.md)
* [Url](helper-url.md)

---

### Overview (`docs/internals-ja/README.md`)

Yii 開発者ドキュメント
======================

このディレクトリは、Yii フレームワークの開発とリリース・プロセスに関するドキュメントを含んでいます。

寄稿者のためのガイドライン
--------------------------

- [課題を報告する仕方](report-an-issue.md)
- [始めよう](getting-started.md)
- [Yii 2 寄稿者のための Git ワークフロー](git-workflow.md) - 開発環境をセットアップして Yii に対する寄稿を始めるためのステップ・バイ・ステップのガイド。
- [Yii 2 コア・フレームワーク・コード・スタイル](core-code-style.md)
- [Yii 2 ビュー・コード・スタイル](view-code-style.md)


ドキュメント
------------

- [翻訳ステータス](translation-status.md) - どのドキュメントが翻訳できる状態か。
- [翻訳チーム](translation-teams.md)
- [翻訳ワークフロー](translation-workflow.md)


フレームワーク開発
------------------

- [プル・リクエストの品質保証](pull-request-qa.md)
- [自動化されるタスク](automation.md) コード・スタイルの修正、ドキュメントやファイルの自動生成など。
- [設計上の決定](design-decisions.md) - よく議論される事柄についての FAQ 形式の声明リスト。

バージョニングとリリース
------------------------

- [プロジェクトの編成](project-organization.md)
- [Yii のバージョニング](versions.md)
- [後方互換性](bc.md)
- [新しいバージョンのリリース](release.md)

その他
------

### 例外の階層



### データベースのテスト

[こちら](https://gist.github.com/sergeymakinen/0696a5952f160ea28d7b64c3adfecf6f) に、Yii がサポートする全てのデータベースのためのテスト環境構成があります。

---

### Overview (`docs/internals-pl/README.md`)

Dokumentacja dewelopera Yii
===========================

Ten folder zawiera dokumentację dotyczącą procesu rozwoju i powstawania nowych wydań frameworka Yii.

Wskazówki dla kontrybutorów
---------------------------

- [W jaki sposób zgłaszać problemy](report-an-issue.md)
- [Od czego zacząć](getting-started.md)
- [Cykl produkcji Git dla kontrybutorów Yii 2](git-workflow.md) - przewodnik krok po kroku jak utworzyć środowisko deweloperskie i współtworzyć Yii.
- [Styl kodowania bazowych plików frameworka Yii 2](core-code-style.md)
- [Styl kodowania widoków Yii 2](view-code-style.md)


Dokumentacja
------------

- [Status tłumaczeń](translation-status.md) - które z dokumentów są gotowe do przetłumaczenia.
- [Ekipy tłumaczące](translation-teams.md)
- [Cykl tworzenia tłumaczenia](translation-workflow.md)


Rozwój frameworka
-----------------

- [Zapewnienie jakości kodu w prośbie o połączenie](pull-request-qa.md)
- [Zadania zautomatyzowane](automation.md), takie jak poprawki stylu kodu, automatyczne tworzenie dokumentacji i generowanie plików.
- [Decyzje projektowe](design-decisions.md) - lista pytań i odpowiedzi dotyczących często rozważanych zagadnień.

Wersjonowanie i wydania
-----------------------

- [Organizacja projektu](project-organization.md)
- [Wersjonowanie Yii](versions.md)
- [Wsteczna kompatybilność](bc.md)
- [Wydawanie nowej wersji](release.md)

Inne zagadnienia
----------------

### Hierarchia wyjątków

---

### Overview (`docs/internals-ru/README.md`)

Документация для разработчиков Yii
==================================

В этой директории собрана документация по разработке Yii Framework и процессу выпуска релизов.

Руководство контрибьютора
-------------------------

- [Как сообщить о проблеме](report-an-issue.md)
- [С чего начать](getting-started.md)
- [Git-процесс для контрибьюторов Yii 2](git-workflow.md) - пошаговое руководство: настройка окружения и начало работы над Yii.
- [Стиль кода ядра Yii 2](core-code-style.md)
- [Стиль кода представлений Yii 2](view-code-style.md)


Документация
------------

- [Статус переводов](translation-status.md) - какие документы готовы к переводу.
- [Команды переводчиков](translation-teams.md)
- [Процесс перевода](translation-workflow.md)


Разработка фреймворка
---------------------

- [Контроль качества pull request](pull-request-qa.md)
- [Автоматизация](automation.md) - автоисправление стиля кода, генерация документации и файлов.
- [Проектные решения](design-decisions.md) - FAQ по спорным вопросам, которые закрыты решением core team.

Версионирование и релизы
------------------------

- [Организация проекта](project-organization.md)
- [Версионирование Yii](versions.md)
- [Обратная совместимость](bc.md)
- [Выпуск новой версии](release.md)

Разное
------

### Иерархия исключений



### Тестирование баз данных

[Здесь](https://gist.github.com/sergeymakinen/0696a5952f160ea28d7b64c3adfecf6f) находится конфигурация тестовых окружений для всех поддерживаемых Yii баз данных.

---

### Overview (`docs/internals/README.md`)

Yii Developer Documentation
===========================

This directory contains documentation about Yii Framework development and release process.

Contributor Guidelines
----------------------

- [How to Report an Issue](report-an-issue.md)
- [Getting started](getting-started.md)
- [Git workflow for Yii 2 contributors](git-workflow.md) - a step by step guide on how to set up your dev environment and start contributing to Yii.
- [Yii 2 Core Framework Code Style](core-code-style.md)
- [Yii 2 View Code Style](view-code-style.md)


Documentation
-------------

- [Translation Status](translation-status.md) - which documents are ready for translation.
- [Translation teams](translation-teams.md)
- [Translation workflow](translation-workflow.md)


Framework Development
---------------------

- [Pull request quality assurance](pull-request-qa.md)
- [Automated Tasks](automation.md), like code style fixes, automatic documentation and file generation.
- [Design Decisions](design-decisions.md) - a FAQ-like list of statements about commonly debated things.

Versioning and Release
----------------------

- [Project Organization](project-organization.md)
- [Yii Versioning](versions.md)
- [Backwards Compatibility](bc.md)
- [Releasing a new version](release.md)

Misc
----

### Exception Hierarchy



### Database testing

[Here](https://gist.github.com/sergeymakinen/0696a5952f160ea28d7b64c3adfecf6f) is config for test environments for all supported Yii databases.

---

### Guide Es Caching Overview (`docs/guide-es/caching-overview.md`)

El Almacenamiento en Caché
==========================

El almacenamiento en caché es una forma económica y eficaz para mejorar el rendimiento de una aplicación web. Mediante
el almacenamiento de datos relativamente estáticos en la memoria caché y su correspondiente recuperación cuando éstos sean
solicidatos, la aplicación salvaría todo ese tiempo y recursos necesarios para volver a generarlos cada vez desde cero.

El almacenamiento en caché se puede usar en diferentes niveles y lugares en una aplicación web. En el lado del servidor, al más bajo nivel,
la caché puede ser usada para almacenar datos básicos, tales como una una lista de los artículos más recientes obtenidos de una base de datos;
y en el más alto nivel, la caché puede ser usada para almacenar fragmentos o la totalidad de las páginas web, tales como el resultado del renderizado de los artículos más recientes. En el lado del cliente, el almacenamiento en caché HTTP puede ser utilizado para mantener
el contenido de la página que ha sido visitada más recientemente en el caché del navegador.

Yii soporta los siguientes mecanismos de almacenamiento de caché:

* [Caché de datos](caching-data.md)
* [Caché de fragmentos](caching-fragment.md)
* [Caché de páginas](caching-page.md)
* [Caché HTTP](caching-http.md)

---

### Guide Es Helper Overview (`docs/guide-es/helper-overview.md`)

Helpers
=======

> Note: Esta sección está en desarrollo.

Yii ofrece muchas clases que ayudan a simplificar las tareas comunes de codificación, como manipulación de string o array,
generación de código HTML, y más. Estas clases helper están organizadas bajo el namespace `yii\helpers` y
son todo clases estáticas (lo que significa que sólo contienen propiedades y métodos estáticos y no deben ser instanciadas).

Puedes usar una clase helper directamente llamando a uno de sus métodos estáticos, como a continuación:

```php
use yii\helpers\Html;

echo Html::encode('Test > test');
```

> Note: Para soportar la [personalización de clases helper](#customizing-helper-classes), Yii separa cada clase helper del núcleo
  en dos clases: una clase base (ej. `BaseArrayHelper`) y una clase concreta (ej. `ArrayHelper`).
  Cuando uses un helper, deberías sólo usar la versión concreta y nunca usar la clase base.


Clases Helper del núcleo
------------------------

Las siguientes clases helper del núcleo son proporcionadas en los releases de Yii:

- [ArrayHelper](helper-array.md)
- Console
- FileHelper
- [Html](helper-html.md)
- HtmlPurifier
- Image
- Inflector
- Json
- Markdown
- Security
- StringHelper
- [Url](helper-url.md)
- VarDumper


Personalizando Las Clases Helper <span id="customizing-helper-classes"></span>
--------------------------------

Para personalizar una clase helper del núcleo (ej. [[yii\helpers\ArrayHelper]]), deberías crear una nueva clase extendiendo
de los helpers correspondientes a la clase base (ej. [[yii\helpers\BaseArrayHelper]]), incluyendo su namespace. Esta clase
será creada para remplazar la implementación original del framework.

El siguiente ejemplo muestra como personalizar el método [[yii\helpers\ArrayHelper::merge()|merge()]] de la clase
[[yii\helpers\ArrayHelper]]:

```php
<?php

namespace yii\helpers;

class ArrayHelper extends BaseArrayHelper
{
    public static function merge($a, $b)
    {
        // tu implementación personalizada
    }
}
```

Guarda tu clase en un fichero nombrado `ArrayHelper.php`. El fichero puede estar en cualquier directorio, por ejemplo `@app/components`.

A continuación, en tu [script de entrada](structure-entry-scripts.md) de la aplicación, añade las siguientes lineas de código
después de incluir el fichero `yii.php` para decirle a la [clase autoloader de Yii](concept-autoloading.md) que cargue tu
clase personalizada en vez de la clase helper original del framework:

```php
Yii::$classMap['yii\helpers\ArrayHelper'] = '@app/components/ArrayHelper.php';
```

Nota que la personalización de clases helper sólo es útil si quieres cambiar el comportamiento de una función
existente de los helpers. Si quieres añadir funciones adicionales para usar en tu aplicación puedes mejor crear un helper
por separado para eso.

---

### Guide Es Runtime Overview (`docs/guide-es/runtime-overview.md`)

Información General
===============

Cada vez que una aplicación Yii gestiona una petición, se somete a un flujo de trabajo similar.

1. Un usuario hace una petición al [script de entrada](structure-entry-scripts.md) ‘web/index.php’.
2. El script de entrada carga la [configuración](concept-configurations.md) y crea una instancia de la 
   [aplicación](structure-applications.md) para gestionar la petición.
3. La aplicación resuelve la [ruta](runtime-routing.md) solicitada con la ayuda del componente 
   [petición](runtime-requests.md) de la aplicación.
4. La aplicación crea una instancia del [controlador](structure-controllers.md) para gestionar la petición. 
5. El controlador crea una instancia de la [acción](structure-controllers.md) y ejecuta los filtros para la acción.
6. Si algún filtro falla, se cancela la acción.
7. Si pasa todos los filtros, se ejecuta la acción.
8. La acción carga un modelo de datos, posiblemente de la base de datos.
9. La acción renderiza una vista, proporcionándole el modelo de datos.
10. El resultado renderizado se devuelve al componente [respuesta](runtime-responses.md) de la aplicación.
11. El componente respuesta envía el resultado renderizado al navegador del usuario.

El siguiente diagrama muestra como una aplicación gestiona una petición.



En esta sección, se describirá en detalle cómo funcionan algunos de estos pasos.

---

### Guide Es Structure Overview (`docs/guide-es/structure-overview.md`)

Información general
===================

Las aplicaciones realizadas con Yii están organizadas de acuerdo al patrón de diseño [modelo-vista-controlador (MVC)](https://es.wikipedia.org/wiki/Modelo%E2%80%93vista%E2%80%93controlador). Los
[modelos](structure-models.md) representan datos, la lógica de negocios y sus reglas; las [vistas](structure-views.md) 
son la representación de salida de los modelos; y finalmente, los [controladores](structure-controllers.md) que toman datos de entrada y los convierten en instrucciones para los [modelos](structure-models.md) y [vistas](structure-views.md). 

Además de MVC, las aplicaciones Yii también tienen las siguientes entidades:

* [scripts de entrada](structure-entry-scripts.md): Existen scripts PHP directamente accesibles a los usuarios finales.
  Son los responsables de comenzar el ciclo de manejo de una solicitud.
* [aplicaciones](structure-applications.md): Son objetos accesibles globalmente que gestionan y coordinan los componentes 
  de la aplicación con el fin de atender las diferentes solicitudes. 
* [componentes de la aplicación](structure-application-components.md): Son los objetos registrados con la aplicación, y
  proporcionan varios servicios para cumplir las solicitudes.
* [módulos](structure-modules.md): Son paquetes auto-contenidos los cuales por si solos poseen estructura MVC.
  Una aplicación puede estar organizada en términos de múltiples módulos.
* [filtros](structure-filters.md): Representan el código que debe ser invocado antes y despues de la ejecución de cada
  solicitud por los controladores.
* [widgets](structure-widgets.md): Son objetos que pueden ser embebidos en las [Vistas](structure-views.md). Pueden
  contener lógica del controlador y ser reutilizados en múltiples vistas.

El siguiente esquema muestra la estructura estática de una aplicación:

---

### Guide Es Test Overview (`docs/guide-es/test-overview.md`)

Tests
=====

Las pruebas son una parte importante del desarrollo de software.  Seamos conscientes
de ello o no, ralizamos pruebas contínuamente.
Por ejemplo, cuando escribimos una clase en PHP, podemos depurarla paso a paso o
simplemente usar declaraciones `echo` o `die` para verificar que la implementación
funciona conforme a nuestro plan inicial.  En el caso de una aplicación web, introducimos
algunos datos de prueba en los formularios para asegurarnos de que la página interactúa
con nosotros como esperábamos.

El proceso de testeo se puede automatizar para que cada vez que necesitemos verificar
algo, solamente necesitemos invocar el código que lo hace por nosotros.  El código que
verifica que el restulado coincide con lo que habíamos planeado se llama *test* y el proceso
de su creación y posterior ejecución es conocido como *testeo automatizado*, que es el
principal tema de estos capítulos sobre testeo.


## Desarrollo con tests

El Desarrollo Dirigido por Pruebas (_Test-Driven Development_ o TDD) y el Desarrollo
Dirigido por Corpotamientos (_Behavior-Driven Development_ o BDD) son enfoques para
desarrollar software, en los que se describe el comportamiento de un trozo de código
o de toda la funcionalidad como un conjunto de escenarios o pruebas antes de escribir
el código real y sólo entonces crear la implementación que permite pasar esos tests
verificando que se ha logrado el comportamiento pretendido.

El proceso de desarrollo de una funcionalidad es el siguiente:

- Crear un nuevo test que describe una funcionalidad a implementar.
- Ejecutar el nuevo test y asegurarse de que falla.  Esto es lo esperado, dado que todavía no hay ninguna implementación.
- Escribir un código sencillo para superar el nuevo test.
- Ejecutar todos los tests y asegurarse de que se pasan todos.
- Mejorar el código y asegurarse de que los tests siguen superándose.

Una vez hecho, se repite el proceso de neuvo para otra funcionalidad o mejora.
Si se va a cambiar la funcionalidad existente, también hay que cambiar los tests.

> Tip: Si siente que está perdiendo tiempo haciendo un montón de iteraciones pequeñas
> y simples, intente cubrir más por cada escenario de test, de modo que haga más cosas antes
> de ejecutar los tests de nuevo.  Si está depurando demasiado, intente hacer lo contrario.

La razón para crear los tests antes de hacer ninguna implementación es que eso nos permite
centrarnos en lo que queremos alcanzar y sumergirnos totalmente en «cómo hacerlo» después.
Normalmente conduce a mejores abstracciones y a un más fácil mantenimiento de los tests
cuando toque hacer ajustes a las funcionalidades o componentes menos acoplados.

Para resumir, las ventajas de este enfoque son las siguientes:

- Le mantiene centrado en una sola cosa en cada momento, lo que resulta en una mejor planificación e implementación.
- Resulta en más funcionalidades cubiertas por tests, y en mayor detalle.  Es decir, si se superan los tests, lo más problable es que no haya nada roto.

A largo plazo normalmente tiene como efecto un buen ahorro de tiempo.

## Qué y cómo probar

Aunque el enfoque de primero los tests descrito arriba tiene sentido para el largo plazo
y proyectos relativamente complejos, sería excesivo para proyectos más simples.
Hay algunas indicaciones de cuándo es apropiado:

- El proyecto ya es grande y complejo.
- Los requisitos del proyecto están empezando a hacerse complejos.  El proyecto crece constantemente.
- El proyecto pretende a ser a largo plazo.
- El coste de fallar es demasiado alto.

No hay nada malo en crear tests que cubran el comportamiento de una implementación existente.

- Es un proyecto legado que se va a renovar gradualmente.
- Le han dado un proyecto sobre el que trabajar y no tiene tests.

En algunos casos cualquier forma de testo automatizado sería exagerada:

- El proyecto es sencillo y no se va a volver más complejo.
- Es un proyecto puntual en el que no se seguirá trabajando.

De todas formas, si dispone de tiempo, es bueno automatizar las pruebas también en esos casos.

## Más lecturas

- Test Driven Development: By Example / Kent Beck. ISBN: 0321146530.

---

### Guide Fr Caching Overview (`docs/guide-fr/caching-overview.md`)

Mise en cache
=============

La mise en cache est un moyen peu coûteux et efficace d'améliorer la performance d'une application Web. En stockant des données relativement statiques en cache et en les servant à partir de ce cache lorsqu'elles sont demandées, l'application économise le temps qu'il aurait fallu pour générer ces données à partir de rien à chaque demande.

La mise en cache se produit à différents endroits et à différents niveaux dans une application Web. Du côté du serveur, au niveau le plus bas, le cache peut être utilisé pour stocker des données de base, telles qu'une liste des informations sur des articles recherchée dans une base de données ; et à un niveau plus élevé, il peut être utilisé pour stocker des fragments ou l'intégralité de pages Web, telles que le rendu des articles les plus récents. 

Du côté client, la mise en cache HTTP peut être utilisée pour conserver le contenu des pages visitées les plus récentes dans le cache du navigateur.

Yii prend en charge tous ces mécanismes de mise en cache :

* [Mise en cache de données](caching-data.md)
* [Mise en cache de fragments](caching-fragment.md)
* [Mise en cache de pages](caching-page.md)
* [Mise en cache HTTP](caching-http.md)

---

### Guide Fr Helper Overview (`docs/guide-fr/helper-overview.md`)

Classes assistantes
===================

> Note: cette section est en cours de développement.

Yii procure de nombreuses classes qui vous aident à simplifier le code de tâches courantes, telles que la manipulation de chaînes de caractères ou de tableaux, la génération de code HTML, et ainsi de suite. Ces classes assistantes sont organisées dans l'espace de noms `yii\helpers` et sont toutes des classes statiques (ce qui signifie qu'elles ne contiennent que des propriétés et des méthodes statiques et ne doivent jamais être instanciées).

Vous utilisez une classe assistante en appelant directement une de ses méthodes statiques, comme ceci :

```php
use yii\helpers\Html;

echo Html::encode('Test > test');
```

> Note: pour prendre en charge la [personnalisation des classes assistantes](#customizing-helper-classes), Yii éclate chacune des classes assistantes du noyau en deux classes : une classe de base (p. ex. `BaseArrayHelper`) et une classe concrète (p. ex. `ArrayHelper`). Lorsque vous utilisez une classe assistante, vous devez utiliser la version concrète uniquement et ne jamais utiliser la classe de base.


Classes assistantes du noyau
----------------------------

Les versions de Yii fournissent les classes assistantes du noyau suivantes :

- [ArrayHelper](helper-array.md)
- Console
- FileHelper
- FormatConverter
- [Html](helper-html.md)
- HtmlPurifier
- Imagine (provided by yii2-imagine extension)
- Inflector
- Json
- Markdown
- StringHelper
- [Url](helper-url.md)
- VarDumper


Personnalisation des classes assistantes <span id="customizing-helper-classes"></span>
----------------------------------------

Pour personnaliser une classe assistante du noyau (p. ex. [[yii\helpers\ArrayHelper]]), vous devez créer une nouvelle classe qui étend la classe de base correspondant à la classe assistante (p. ex. [[yii\helpers\ArrayHelper]]), y compris son espace de noms. Cette classe sera ensuite configurée pour remplacer l'implémentation originale de Yii.

L'exemple qui suit montre comment personnaliser la méthode [[yii\helpers\ArrayHelper::merge()|merge()]] de la classe [[yii\helpers\ArrayHelper]] :

```php
<?php

namespace yii\helpers;

class ArrayHelper extends BaseArrayHelper
{
    public static function merge($a, $b)
    {
        // votre implémentation personnalisée
    }
}
```

Sauvegardez votre classe dans un fichier nommé `ArrayHelper.php`. Le fichier peut se trouver dans n'importe quel dossier, par exemple, `@app/components`.

Ensuite, dans le [script d'entrée](structure-entry-scripts.md) de votre application, ajoutez la ligne de code suivante, après l'inclusion du fichier `yii.php` pour dire à la [classe autoloader de Yii](concept-autoloading.md) de charger votre classe personnalisée au lieu de la classe assistance originale de Yii. 

```php
Yii::$classMap['yii\helpers\ArrayHelper'] = '@app/components/ArrayHelper.php';
```

Notez que la personnalisation d'une classe assistante n'est utile que si vous désirez changer le comportement d'une fonction existante de la classe assistante. Si vous désirez ajouter une fonction additionnelle à utiliser dans votre application, le mieux est de créer une classe assistante séparée pour cela.

---

### Guide Fr Runtime Overview (`docs/guide-fr/runtime-overview.md`)

Vue d'ensemble
==============

À chaque fois qu'une application Yii prend en charge une requête, elle entreprend un flux de travail similaire. 

1. Un utilisateur effectue une requête auprès du [script d'entrée](structure-entry-scripts.md) `web/index.php`.
2. Le script d'entrée charge la [configuration](concept-configurations.md) de l'application et crée une instance d'[application](structure-applications.md) pour prendre en charge la requête.
3. L'application résoud la [route](runtime-routing.md) requise avec l'aide du composant d'application [request](runtime-requests.md).
4. L'application crée une instance de [contrôleur](structure-controllers.md) pour prendre en charge le requête.
5. Le contrôleur crée une instance d'[action](structure-controllers.md) et exécute les filtres de l'action.
6. Si un [filtre](structure-filters.md) échoue, l'exécution de l'action est annulée.
7. Si tous les filtres réussissent l'action est exécutée.
8. L'action charge un [modèle](structure-models.md) de données, possiblement à partir d'une base de données.
9. L'action rend une [vue](structure-views.md), en lui passant le modèle de données.
10. Le résultat rendu est retourné au composant d'application [response](runtime-responses.md).
11. Le composant *response* envoye le résultat rendu au navigateur de l'utilisateur. 
Le diagramme ci-dessous illustre comment une application prend une requête en charge. 



Dans cette section, nous décrivons en détails comment se déroulent quelques unes de ces étapes.

---

### Guide Fr Security Overview (`docs/guide-fr/security-overview.md`)

Sécurité
========

Une bonne sécurité est vitale pour la santé et le succès de toute application. Malheureusement, beaucoup de développeurs lésinent un peu quand ils en arrivent à la sécurité, soit par manque de compréhension ou parce que sa mise en œuvre n'est pas une mince affaire. Pour rendre votre application Yii aussi sûre que possible, Yii inclut plusieurs fonctionnalités de sécurité, excellentes et faciles à mettre en œuvre. 

* L'[authentification](security-authentication.md)
* L'[autorisation](security-authorization.md)
* Le [travail avec des mots de passe](security-passwords.md)
* La [cryptographie](security-cryptography.md)
* La [sécurité des vues](structure-views.md#security)
* L'extension [Auth Clients](https://github.com/yiisoft/yii2-authclient/blob/master/docs/guide/README.md)
* Les [bonnes pratiques](security-best-practices.md)

---

### Guide Fr Structure Overview (`docs/guide-fr/structure-overview.md`)

Vue d'ensemble
========

Les applications Yii sont organisées suivant le modèle de conception 
[model-view-controller (MVC)](https://fr.wikipedia.org/wiki/Mod%C3%A8le-vue-contr%C3%B4leur). Les [Modèles](structure-models.md) 
représentent les données, la logique métier et les règles; les [vues](structure-views.md) sont les représentations
visuelles des modèles, et les [contrôleurs](structure-controllers.md) prennent une entrée et la convertissent en 
commandes pour les [modèles](structure-models.md) et les [vues](structure-views.md).

En plus du MVC, les applications Yii ont les entités suivantes :

* [scripts d'entrée](structure-entry-scripts.md): ce sont des scripts PHP qui sont directement accessibles aux 
  utilisateurs. Ils sont responsables de l'amorçage d'un cycle de gestion de requête.
* [applications](structure-applications.md): ce sont des objets globalement accessibles qui gèrent les composants
  d'application et les coordonnent pour satisfaire des requêtes.
* [composants d'application](structure-application-components.md): ce sont des objets enregistrés avec des applications et 
  qui fournissent différents services pour satisfaire des requêtes.
* [modules](structure-modules.md): ce sont des paquets auto-contenus qui contiennent du MVC complet. Une application peut
  être organisée en de multiples modules.
* [filtres](structure-filters.md): ils représentent du code qui doit être invoqué avant et après la gestion effective 
  de chaque requête par des contrôleurs.
* [objets graphiques](structure-widgets.md): ce sont des objets qui peuvent être intégrés dans des [vues](structure-views.md). Ils
  peuvent contenir de la logique contrôleur et peuvent être réutilisés dans différentes vues.

Le diagramme suivant montre la structure statique d'une application :

---

### Guide Id Structure Overview (`docs/guide-id/structure-overview.md`)

Tinjauan
========

Aplikasi Yii diorganisir berdasarkan pola arsitektur [model-view-controller (MVC)](https://id.wikipedia.org/wiki/MVC).
[Model](structure-models.md) merepresentasikan data, pengaturan dan proses bisnis; [view](structure-views.md)
adalah output yang merepresentasikan model; dan [controller](structure-controllers.md) mengelola input dan merubahnya
menjadi perintah-perintah untuk [model](structure-models.md) dan [view](structure-views.md).

Selain MVC, aplikasi Yii juga memiliki entitas berikut:

* [entry scripts](structure-entry-scripts.md): Ini adalah skrip PHP yang diakses secara langsung oleh pengguna.
  Ini bertugas untuk memulai siklus penanganan _request_.
* [applications](structure-applications.md): Ini adalah objek yang dapat diakses secara global, yang mengelola _component_ aplikasi
  dan mengaturnya untuk memenuhi sebuah _request_.
* [application components](structure-application-components.md): Ini adalah objek-objek yang didaftarkan pada objek _application_ dan
  menyediakan beragam layanan untuk memenuhi _request_.
* [modules](structure-modules.md): Ini adalah paket _(package)_ mandiri yang berisikan MVC lengkap.
  Sebuah aplikasi boleh diistilahkan sebagai module-module yang telah diorganisir.
* [filters](structure-filters.md): Ini merepresentaikan kode yang mutlak untuk dijalakan sebelum dan sesudah
  penanganan dari tiap-tiap _request_ yang dikelola oleh _controller_.
* [widgets](structure-widgets.md): Ini adalah objek-objek yang dapat ditanam kedalam [views](structure-views.md). Ini
  dapat mengandung logika _controller_ dan dapat digunakan berulang-ulang pada _view_ yang berbeda.

Diagram dibawah ini menunjukkan struktur statis dari sebuah aplikasi:

---

### Guide Ja Caching Overview (`docs/guide-ja/caching-overview.md`)

キャッシュ
==========

キャッシュはウェブ・アプリケーションのパフォーマンスを向上させるための安価で効果的な方法です。
比較的静的なデータをキャッシュに格納し、要求に応じてキャッシュからそれを取得します。
これによって、アプリケーションは、毎回一からデータを生成した場合に必要になるであろう時間を節約することができます。

キャッシュはアプリケーション内のさまざまなレベルと場所で使用することができます。
例えばサーバ・サイドでの低いレベルでは、データベースから取得した最新の記事情報リストのような
基本的なデータを格納するためにキャッシュを使用することが出来ます。
より高いレベルでは、ウェブ・ページの断片または全体、例えば、最新の記事のレンダリング結果を格納するためにキャッシュを使用することが出来ます。
クライアント・サイドでは、最近訪れたページの内容をブラウザのキャッシュに格納するために、HTTP キャッシュを使用することができます。

Yii はこれら全てのキャッシュ機構をサポートしています:

* [データ・キャッシュ](caching-data.md)
* [フラグメント・キャッシュ](caching-fragment.md)
* [ページ・キャッシュ](caching-page.md)
* [HTTP キャッシュ](caching-http.md)

---

### Guide Ja Helper Overview (`docs/guide-ja/helper-overview.md`)

ヘルパ
======

> Note: このセクションはまだ執筆中です。

Yii は、一般的なコーディングのタスク、例えば、文字列や配列の操作、HTML コードの生成などを手助けする多くのクラスを提供しています。
これらのヘルパ・クラスは `yii\helpers` 名前空間の下に編成されており、すべてスタティックなクラス
(すなわち、スタティックなプロパティとメソッドのみを含み、インスタンス化すべきでないクラス) です。

ヘルパ・クラスは、そのスタティックなメソッドの一つを直接に呼び出すことによって使用します。例えば、

```php
use yii\helpers\Html;

echo Html::encode('Test > test');
```

> Note: [ヘルパ・クラスをカスタマイズする](#customizing-helper-classes) ことをサポートするために、Yii はコア・ヘルパ・クラスのすべてを二つのクラスに分割しています。
> すなわち、基底クラス (例えば `BaseArrayHelper`) と具象クラス (例えば `ArrayHelper`) です。
> ヘルパを使うときは、具象クラスのみを使うべきであり、基底クラスは決して使ってはいけません。


コア・ヘルパ・クラス
--------------------

以下のコア・ヘルパ・クラスが Yii のリリースにおいて提供されています。

- [配列ヘルパ](helper-array.md)
- Console
- FileHelper
- FormatConverter
- [Html ヘルパ](helper-html.md)
- HtmlPurifier
- Imagine (yii2-imagine エクステンションによって提供)
- Inflector
- [Json](helper-json.md)
- Markdown
- StringHelper
- [Url ヘルパ](helper-url.md)
- VarDumper


ヘルパ・クラスをカスタマイズする <span id="customizing-helper-classes"></span>
------------------------------

コア・ヘルパ・クラス (例えば [[yii\helpers\ArrayHelper]]) をカスタマイズするためには、
そのヘルパに対応する基底クラス (例えば [[yii\helpers\BaseArrayHelper]]) を拡張するクラスを作成して、名前空間も含めて、
対応する具象クラス (例えば [[yii\helpers\ArrayHelper]]) と同じ名前を付けます。
このクラスが、フレームワークのオリジナルの実装を置き換えるものとしてセットアップされます。

次の例は、[[yii\helpers\ArrayHelper]] クラスの [[yii\helpers\ArrayHelper::merge()|merge()]]
メソッドをカスタマイズする方法を示すものです。

```php
<?php

namespace yii\helpers;

class ArrayHelper extends BaseArrayHelper
{
    public static function merge($a, $b)
    {
        // あなた独自の実装
    }
}
```

あなたのクラスを `ArrayHelper.php` という名前のファイルに保存します。このファイルはどこに置いても構いません。例えば、`@app/components` に置くことにしましょう。

次に、アプリケーションの [エントリ・スクリプト](structure-entry-scripts.md) で、
次のコード行を `yii.php` ファイルをインクルードする行の後に追加して、[Yii クラス・オートローダ](concept-autoloading.md) に、
フレームワークから本来のヘルパ・クラスをロードする代りに、あなたのカスタム・クラスをロードすべきことを教えます。

```php
Yii::$classMap['yii\helpers\ArrayHelper'] = '@app/components/ArrayHelper.php';
```

ヘルパ・クラスのカスタマイズは、ヘルパの既存の関数の振る舞いを変更したい場合にだけ役立つものであることに注意してください。
アプリケーションの中で使用する関数を追加したい場合は、
そのための独立したヘルパを作成する方が良いでしょう。

---

### Guide Ja Runtime Overview (`docs/guide-ja/runtime-overview.md`)

概要
====

Yii のアプリケーションがリクエストを処理するときは、毎回、同じようなワーク・フローになります。

1. ユーザが [エントリ・スクリプト](structure-entry-scripts.md) `web/index.php` にリクエストをします。
2. エントリ・スクリプトは、アプリケーションの [構成情報](concept-configurations.md) をロードして、
   リクエストを処理するための [アプリケーション](structure-applications.md) のインスタンスを作成します。
3. アプリケーションは、[リクエスト](runtime-requests.md) アプリケーション・コンポーネントの助けを借りて、
   リクエストされた [ルート](runtime-routing.md) を解決します。
4. アプリケーションはリクエストを処理するための [コントローラ](structure-controllers.md) のインスタンスを作成します。
5. コントローラは [アクション](structure-controllers.md) のインスタンスを作成して、アクションのためのフィルタを実行します。
6. [フィルタ](structure-filters.md)のどれかが失敗すると、アクションはキャンセルされます。
7. すべてのフィルタを無事に通ったら、アクションが実行されます。
8. アクションはデータ[モデル](structure-models.md)を、おそらくはデータベースから、ロードします。
9. アクションはデータ・モデルを[ビュー](structure-views.md)に提供して、ビューをレンダリングします。
10. レンダリングの結果は [レスポンス](runtime-responses.md) アプリケーション・コンポーネントに返されます。
11. レスポンス・コンポーネントがレンダリングの結果をユーザのブラウザに送信します。

次の図は、アプリケーションがどのようにしてリクエストを処理するかを示すものです。



このセクションでは、これらのステップのいくつかについて、どのように動作するかを詳細に説明します。

---

### Guide Ja Security Overview (`docs/guide-ja/security-overview.md`)

セキュリティ
============

十分なセキュリティは、すべてのアプリケーションの健全さと成功のために欠くことが出来ないものです。
不幸なことに、理解が不足しているためか、実装の難易度が高すぎるためか、セキュリティのことになると手を抜く開発者がたくさんいます。
Yii によって駆動されるあなたのアプリケーションを可能な限り安全にするために、Yii はいくつかの優秀な使いやすいセキュリティ機能を内蔵しています。

* [認証](security-authentication.md)
* [権限付与](security-authorization.md)
* [パスワードを扱う](security-passwords.md)
* [暗号化](security-cryptography.md)
* [ビューのセキュリティ](structure-views.md#security)
* [認証クライアント](https://github.com/yiisoft/yii2-authclient/blob/master/docs/guide-ja/README.md)
* [ベスト・プラクティス](security-best-practices.md)
* [信頼できるプロキシとヘッダ](runtime-requests.md#trusted-proxies)

---

### Guide Ja Structure Overview (`docs/guide-ja/structure-overview.md`)

概要
====

Yii のアプリケーションは [モデル・ビュー・コントローラ (MVC)](https://ja.wikipedia.org/wiki/Model_View_Controller) アーキテクチャ・パターンに従って編成されています。
[モデル](structure-models.md) は、データ、ビジネス・ロジック、規則を表現します。
[ビュー](structure-views.md) は、モデルの出力表現です。
そして [コントローラ](structure-controllers.md) は入力を受け取って、それを [モデル](structure-models.md) と [ビュー](structure-views.md) のためのコマンドに変換します。

MVC 以外にも、Yii のアプリケーションは下記の要素を持っています。

* [エントリ・スクリプト](structure-entry-scripts.md): エンド・ユーザから直接アクセスできる PHP スクリプトです。
  これはリクエスト処理サイクルを開始する役目を持っています。
* [アプリケーション](structure-applications.md): グローバルにアクセス可能なオブジェクトであり、
  アプリケーション・コンポーネントを管理し、連携させて、リクエストに応えます。
* [アプリケーション・コンポーネント](structure-application-components.md): アプリケーションと共に登録されたオブジェクトであり、
  リクエストに応えるための様々なサービスを提供します。
* [モジュール](structure-modules.md): それ自身に完全な MVC を含む自己完結的なパッケージです。
  アプリケーションは複数のモジュールとして編成することが出来ます。
* [フィルタ](structure-filters.md): 各リクエストが実際に処理される前と後に、
  コントローラから呼び出される必要があるコードを表現します。
* [ウィジェット](structure-widgets.md): [ビュー](structure-views.md) に埋め込むことが出来るオブジェクトです。
  コントローラのロジックを含むことが可能で、異なるビューで再利用することが出来ます。

下の図がアプリケーションの静的な構造を示すものです。

---

### Guide Ja Test Overview (`docs/guide-ja/test-overview.md`)

テスト
======

テストはソフトウェア開発の重要な部分です。
気付いているか否かにかかわらず、私たちは継続的にテストをしています。
例えば、PHP でクラスを書くとき、私たちはステップごとにデバッグしたり、または単純に `echo` 文や `die` 文を使ったりして、実装が最初の計画通りに動作することを検証します。
ウェブ・アプリケーションの場合は、何らかのテスト・データをフォームに入力して、ページが期待通りにユーザと相互作用をすることを確認します。

テストを実行するプロセスを自動化して、何かを検証する必要があるときは、いつでも、
それを代行してくれるコードを呼び出すだけでよいようにすることが出来ます。
結果が計画したものと合致することを検証するコードが *テスト* と呼ばれ、それを作成して更に実行するプロセスが *テスト自動化* として知られています。
このテストの章の主題は、このテストの自動化です。


## テストとともに開発する

テスト駆動開発 (TDD) とビヘイビア駆動開発 (BDD) のソフトウェア開発手法においては、実際のコードを書く前に、
コードの断片または全体の機能の振る舞いを一連のシナリオまたはテストとして記述します。
そして、その後で初めて、テストに合格するように実装を作成して、
意図された振る舞いが達成されていることを検証します。

一つの機能を開発するプロセスは以下のようになります。

- 実装されるべき機能を記述するテストを作成する。
- 新しいテストを走らせて、失敗することを確認する。まだ実装がないので、これは予期された結果です。
- 新しいテストに合格するための単純なコードを書く。
- 全てのテストを走らせて、全てが合格することを確認する。
- コードを改良して、それでも全てのテストが OK であることを確認する。

完了すれば、別の機能または改良のために、このプロセスを再び繰り返します。
既存の機能が変更される場合は、テストも変更されなければなりません。

> Tip: 多数の小さくて単純なイテレーションを繰り返すために時間を取られていると感じる場合は、テスト・シナリオのカバー範囲を広くして、テストを再度実行するまでの作業量を増やしてみてください。
> デバッグばかりやっている場合は、逆に範囲を狭めてみてください。

全ての実装作業の前にテストを作成する理由は、そうすれば、その後で、
達成したい事柄に集中して「どのようにするか」に没頭することが出来るからです。
通常、そのようにすることは、良い抽象化、機能修正時の容易なテスト保守、また、結合度の低いコンポーネントにつながります。

ですから、このような手法の長所を要約すると次のようになります。

- 一時に一つの事柄に集中できるため、計画と実装がより良いものになる。
- より多くの機能をより詳細にテストでカバーできる。つまり、テストが OK なら何も問題がないと期待できる。

通常は、長い期間で見れば、かなり時間を節約する効果があります。

## いつ、どうやって、テストするか

上記で説明したテスト・ファーストの手法は長期間にわたる比較的複雑なプロジェクトには合理的なものですが、簡単なプロジェクトでは、やりすぎとなるおそれもあります。
この手法が適切であることを示す指標がいくつかあります。

- プロジェクトは既に大きくて複雑である。
- プロジェクトの要求仕様が複雑になってきている。プロジェクトが継続的に大きくなっている。
- プロジェクトが長期にわたる予定である。
- 失敗のコストが高すぎる。

既存の実装の振る舞いをカバーするテストを作成することは、何も悪いことではありません。

- プロジェクトはレガシーなものであるが、段階的に刷新される予定である。
- 従事すべきプロジェクトを得たが、それにはテストがなかった。

どんな形式の自動化テストもやりすぎになる、という場合もあるでしょう。

- プロジェクトが単純で、この先も、複雑になる心配はない。
- これ以上かかわることはない一度限りのプロジェクトである。

ただ、このような場合であっても、時間に余裕があれば、テストを自動化することは良いことです。

## 参考

- Test Driven Development: By Example / Kent Beck. ISBN: 0321146530.

---

### Guide Pl Caching Overview (`docs/guide-pl/caching-overview.md`)

Pamięć podręczna
================

Mechanizmy wykorzystujące pamięć podręczną pozwalają na poprawienie wydajności aplikacji sieciowej w tani i efektywny sposób. 
Zapisanie statycznych danych w pamięci podręcznej, zamiast generowania ich od podstaw przy każdym wywołaniu, pozwala na znaczne zaoszczędzenie czasu odpowiedzi aplikacji.

Zapis pamięci podręcznej może odbywać się na wielu poziomach i w wielu miejscach aplikacji. Po stronie serwera, na niskim poziomie, 
można wykorzystać pamięć podręczną do zapisania podstawowych danych, takich jak zbiór informacji o najnowszych artykułach pobieranych z bazy danych. 
Na wyższym poziomie, pamięci podręcznej można użyć do przechowania części bądź całości strony www, na przykład w postaci rezultatu wyrenderowania 
listy ww. najświeższych artykułów. Po stronie klienta, pamięć podręczna HTTP przeglądarki może zapisać zawartość ostatnio odwiedzonej strony.

Yii wpiera wszystkie te mechanizmy zapisu w pamięci podręcznej:

* [Pamięć podręczna danych](caching-data.md)
* [Pamięć podręczna fragmentów](caching-fragment.md)
* [Pamięć podręczna stron](caching-page.md)
* [Pamięć podręczna HTTP](caching-http.md)

---

### Guide Pl Helper Overview (`docs/guide-pl/helper-overview.md`)

Klasy pomocnicze
================

> Note: Ta sekcja jest w trakcie tworzenia.

Yii jest wyposażone w wiele klas upraszczających pisanie często wykorzystywanych zadań w kodzie, takich jak manipulowanie ciągami znaków bądź tablicami, generowanie kodu HTML, itp.
Te pomocnicze klasy znajdują się w przestrzeni nazw `yii\helpers` i wszystkie są klasami statycznymi (czyli zawierają wyłącznie statyczne właściwości i nie powinny być tworzone ich 
instancje).

Aby skorzystać z klasy pomocnicznej, należy bezpośrednio wywołać jedną z jej statycznych metod, jak w przykładzie poniżej:

```php
use yii\helpers\Html;

echo Html::encode('Test > test');
```

> Note: W celu zapewnienia możliwości [dostosowania klas pomocniczych do własnych potrzeb](#customizing-helper-classes), Yii rozdziela każdą z ich wbudowanych wersji 
> na dwie klasy: podstawę (np. `BaseArrayHelper`) i klasę właściwą (np. `ArrayHelper`). Kiedy chcesz użyć klasy pomocnicznej, powinieneś korzystać wyłącznie z jej właściwej wersji 
> i nigdy nie używać bezpośrednio podstawy.


Wbudowane klasy pomocnicze
--------------------------

Poniższe wbudowane klasy pomocnicze dostępne są w każdym wydaniu Yii:

- [ArrayHelper](helper-array.md)
- Console
- FileHelper
- FormatConverter
- [Html](helper-html.md)
- HtmlPurifier
- Imagine (poprzez rozszerzenie yii2-imagine)
- Inflector
- Json
- Markdown
- StringHelper
- [Url](helper-url.md)
- VarDumper


Dostosowywanie klas pomocniczych do własnych potrzeb <span id="customizing-helper-classes"></span>
----------------------------------------------------

Aby zmodyfikować wbudowaną klasę pomocniczną (np. [[yii\helpers\ArrayHelper|ArrayHelper]]), należy stworzyć nową klasę rozszerzającą odpowiednią podstawę 
(np. [[yii\helpers\BaseArrayHelper|BaseArrayHelper]]) i nazwać ją identycznie jak jej wersja właściwa (np. [[yii\helpers\ArrayHelper|ArrayHelper]]), łącznie z zachowaniem jej 
przestrzeni nazw. Ta klasa może następnie zostać użyta do zastąpienia oryginalnej implementacji we frameworku.

Poniższy przykład ilustruje w jaki sposób zmodyfikować metodę [[yii\helpers\ArrayHelper::merge()|merge()]] klasy [[yii\helpers\ArrayHelper|ArrayHelper]]:

```php
<?php

namespace yii\helpers;

class ArrayHelper extends BaseArrayHelper
{
    public static function merge($a, $b)
    {
        // zmodyfikowana wersja metody
    }
}
```

Klasę należy zapisać w pliku o nazwie `ArrayHelper.php`, który może znajdować się w dowolnym odpowiednim folderze, np. `@app/components`.

Następnie dopisujemy poniższą linijkę kodu w [skrypcie wejściowym](structure-entry-scripts.md) aplikacji po fragmencie dołączającym plik `yii.php`, 
dzięki czemu [autoloader klas Yii](concept-autoloading.md) załaduje zmodyfikowaną wersję klasy pomocniczej zamiast oryginalnej:

```php
Yii::$classMap['yii\helpers\ArrayHelper'] = '@app/components/ArrayHelper.php';
```

Należy pamiętać o tym, że modyfikowanie klasy pomocniczej jest użyteczne tylko w przypadku, gdy chcemy zmienić domyślny sposób działania jej metody. 
W przypadku dodawania do aplikacji dodatkowych funkcjonalności, lepszym pomysłem jest stworzenie całkowicie nowej, osobnej klasy pomocniczej.

---

### Guide Pl Runtime Overview (`docs/guide-pl/runtime-overview.md`)

Przegląd
========

Za każdym razem kiedy aplikacja Yii obsługuje żądanie, przetwarza je w podobny sposób.

1. Użytkownik wykonuje żądanie do [skryptu wejściowego](structure-entry-scripts.md) `web/index.php`.
2. Skrypt wejściowy ładuje [konfigurację](concept-configurations.md) aplikacji i tworzy [instancję aplikacji](structure-applications.md), aby obsłużyć zapytanie.
3. Aplikacja osiąga żądaną [ścieżkę](runtime-routing.md) za pomocą komponentu [żądania](runtime-requests.md) aplikacji.
4. Aplikacja tworzy instancję [kontrolera](structure-controllers.md), który obsłuży żądanie.
5. Kontroler tworzy instancję [akcji](structure-controllers.md) i przetwarza filtry dla akcji.
6. Jeżeli jakikolwiek filtr się nie wykona, akcja zostanie anulowana.
7. Jeżeli wszystkie filtry przejdą, akcja zostaje wykonana.
8. Akcja wczytuje model danych, być może z bazy danych.
9. Akcja renderuje widok dostarczając go z modelem danych.
10. Wyrenderowana zawartość jest zwracana do komponentu [odpowiedzi](runtime-responses.md) aplikacji.
11. Komponent odpowiedzi wysyła wyrenderowaną zawartość do przeglądarki użytkownika.



W tej sekcji opiszemy szczegóły dotyczące niektórych kroków przetwarzania żądania.

---

### Guide Pl Security Overview (`docs/guide-pl/security-overview.md`)

Bezpieczeństwo
==============

Spełnienie wymogów bezpieczeństwa jest podstawą sukcesu i długiej żywotności każdej aplikacji. Niestety, wielu deweloperów idzie 
w tym temacie drogą na skróty, czy to z powodu braku jego zrozumienia, czy też kłopotów z implementacją we własnym kodzie. 
Aby uczynić Twoją aplikację opartą na Yii tak bezpieczną, jak to tylko możliwe, Yii zapewnia kilka świetnych i jednocześnie łatwych 
w użyciu funkcjonalności służących poprawie bezpieczeństwa.

* [Uwierzytelnianie](security-authentication.md)
* [Autoryzacja](security-authorization.md)
* [Praca z hasłami](security-passwords.md)
* [Kryptografia](security-cryptography.md)
* [Bezpieczeństwo widoków](structure-views.md#security)
* [Klienty autoryzacji](https://github.com/yiisoft/yii2-authclient/blob/master/docs/guide/README.md)
* [Bezpieczeństwo w praktyce](security-best-practices.md)

---

### Guide Pl Structure Overview (`docs/guide-pl/structure-overview.md`)

Struktura aplikacji
===================

Aplikacja Yii jest zorganizowana według wzorca architektonicznego [model-widok-kontroler (MVC)](https://pl.wikipedia.org/wiki/Model-View-Controller). 
[Modele](structure-models.md) reprezentują dane, logikę biznesową i zasady walidacji, [widoki](structure-views.md) 
są odpowiedzialne za wyświetlanie informacji związanych z modelami, a [kontrolery](structure-controllers.md) przyjmują dane wejściowe 
i przekształcają je w polecenia dla [modeli](structure-models.md) i [widoków](structure-views.md).

Oprócz MVC, w aplikacjach Yii zdefiniowane są następujące struktury:

* [skrypty wejściowe](structure-entry-scripts.md): skrypty PHP dostępne bezpośrednio dla użytkowników końcowych, 
  odpowiedzialne za uruchomienie obsługi cyklu życia żądania.
* [aplikacje](structure-applications.md): globalnie dostępne obiekty koordynujące działanie i zarządzające komponentami aplikacji.
* [komponenty aplikacji](structure-application-components.md): obiekty zarejestrowane w aplikacji, zapewniające dostępność dedykowanych usług.
* [moduły](structure-modules.md): niezależne pakiety kodu zawierające kompletną wewnętrzną strukturę MVC.
  Aplikacja może być zorganizowana modułowo.
* [filtry](structure-filters.md): reprezentują kod, który musi być wykonany przed i po obsłużeniu każdego z żądań kontrolera.
* [widżety](structure-widgets.md): obiekty, które mogą być dołączone w [widokach](structure-views.md). Mogą zawierać logikę kontrolera 
  i być wykorzystane wielokrotnie w różnych miejscach.

Poniższy diagram ilustruje statyczną strukturę aplikacji:

---

### Guide Pl Test Overview (`docs/guide-pl/test-overview.md`)

Testowanie
==========

Testowanie jest istotnym elementem produkcji każdego oprogramowania. Niezależnie, czy jesteśmy tego świadomi, czy też nie, testy przeprowadzamy nieustannie.
Dla przykładu, kiedy napiszemy klasę w PHP, możemy debugować ją krok po kroku lub po prostu użyć wyrażeń jak echo lub die, aby sprawdzić, czy implementacja 
działa zgodnie z naszym początkowym planem. W przypadku aplikacji web wprowadzamy testowe dane w formularzach, aby upewnić się, że strona odpowiada tak, jak powinna.

Proces testowania może zostać zautomatyzowany, dzięki czemu za każdym razem, kiedy musimy coś sprawdzić, wystarczy wywołać kod, który zrobi to za nas. 
Kod, który weryfikuje zgodność wyniku z planowaną odpowiedzią, jest nazywany testem, a proces jego tworzenia i późniejszego wykonania jest nazywany testowaniem zautomatyzowanym, 
co jest głównym tematem tych rozdziałów.


Tworzenie kodu z testami
------------------------

Tworzenie kodu opartego na testach (Test-Driven Development, TDD) i opartego na zachowaniach (Behavior-Driven Development, BDD) jest podejściem deweloperskim 
opierającym się na opisywaniu zachowania fragmentu kodu lub też całej jego funkcjonalności jako zestawu scenariuszy lub testów przed napisaniem właściwego kodu
i dopiero potem stworzeniu implementacji, która pozwoli na poprawne przejście testów, spełniających zadane kryteria.

Proces tworzenia funkcjonalności wygląda następująco:

- Stwórz nowy test, opisujący funkcjonalność do zaimplementowania.
- Uruchom nowy test i upewnij się, że zakończy się błędem. To właściwe zachowanie, ponieważ nie ma jeszcze implementacji funkcjonalności.
- Napisz prosty kod, który przejdzie poprawnie nowy test.
- Uruchom wszystkie testy i upewnij się, że wszystkie zakończą się poprawnie.
- Ulepsz kod, sprawdzając czy testy wciąż są zdane.

Po zakończeniu proces jest powtarzany dla kolejnej funkcjonalności lub ulepszenia. Jeśli istniejąca funkcjonalność ma być zmodyfikowana,
testy powinny być również zmienione.

> **Wskazówka**: Jeśli czujesz, że tracisz czas, przeprowadzając dużo krótkich i prostych iteracji, spróbuj objąć testowym scenariuszem więcej działań,
> aby sprawdzić więcej kodu, przed ponownym uruchomieniem testów. Jeśli debugujesz zbyt dużo, spróbuj zrobić dokładnie na odwrót.

Powodem tworzenia testów przed jakąkolwiek implementacją, jest możliwość skupienia się na tym, co chcemy osiągnąć, zanim przystąpimy do "w jaki sposób to zrobić".
Zwykle prowadzi to do stworzenia lepszej warstwy abstrakcji i łatwiejszej obsługi testów w przypadku poprawek funkcjonalności.

Podsumowując, zalety takiego projektowania są następujące:

- Pozwala na skupienie się na pojedynczej rzeczy na raz, dzięki czemu pozwala na lepsze planowanie i implementacje.
- Obejmuje testami więcej funkcjonalności w większym stopniu, co oznacza, że jeśli testy zakończyły się poprawnie jest spore prawdopodobieństwo, że wszystko działa poprawnie.

Na dłuższą metę przynosi to zwykle efekt w postaci mnóstwa oszczędzonego czasu i problemów.

> **Wskazówka**: Jeśli chcesz dowiedzieć się więcej na temat reguł ustalania wymagań dla oprogramowania i modelowania istoty tego rozdziału, 
> warto zapoznać się z domenowym podejściem do tworzenia aplikacji [(Domain Driven Development, DDD)](https://pl.wikipedia.org/wiki/Domain-Driven_Design).

Kiedy i jak testować
--------------------

Podejście typu "testy najpierw" opisane powyżej, ma sens w przypadku długofalowych i relatywnie skomplikowanych projektów i może być przesadne w przypadku prostszych. 
Przesłanki, kiedy testy są odpowiednie są następujące:

- Projekt jest już duży i skomplikowany.
- Wymagania projektowe zaczynają być skomplikowane. Projekt wciąż się powiększa.
- Projekt jest planowany jako długoterminowy.
- Koszty potencjalnych błędów są zbyt duże.

Nie ma nic złego w tworzeniu testów obejmujących zachowania istniejących implementacji.

- Projekt jest oparty starszym kodzie i stopniowo przepisywany.
- Projekt, nad którym masz pracować, nie ma w ogóle testów.

W niektórych przypadkach jakakolwiek forma automatycznego testu może być nadmiarowa:

- Projekt jest prosty i nie jest rozbudowywany.
- Projekt jest jednorazowym zadaniem, które nie będzie rozwijane.

Pomimo tego, jeśli masz na to czas, automatyzacja testowania jest również dobrym pomysłem.


Biblioteka
-------------

- Test Driven Development: By Example - Kent Beck. (ISBN: 0321146530)

---

### Guide Pt BR Caching Overview (`docs/guide-pt-BR/caching-overview.md`)

Cache
=======

Cache é uma maneira simples e eficiente de melhorar o desempenho de uma aplicação Web. Ao gravar dados relativamente
estáticos em cache e servindo os do cache quando requisitados, a aplicação economiza o tempo que seria necessário para renderizar as informações do zero todas as vezes.

Cache pode ocorrer em diferentes níveis e locais em uma aplicação Web. No servidor, no baixo nível,
cache pode ser usado para armazenar dados básicos, como a informação de uma lista de artigos mais recentes trazidos
do banco de dados; e no alto nível, cache pode ser usado para armazenar fragmentos ou páginas Web inteiras, como o
resultado da renderização dos artigos mais recentes. No cliente, cache HTTP pode ser usado para manter o conteúdo da última página acessada no cache do navegador.

Yii suporta todos os quatro métodos de cache:
* [Cache de Dados](caching-data.md)
* [Cache de Fragmento](caching-fragment.md)
* [Cache de Página](caching-page.md)
* [Cache de HTTP](caching-http.md)

---

### Guide Pt BR Helper Overview (`docs/guide-pt-BR/helper-overview.md`)

Helpers
=======

> Observação: Esta seção está em desenvolvimento.

O Yii oferece muitas classes que ajudam a simplificar as tarefas comuns de codificação, como manipulação de string ou de array,
geração de código HTML, e assim por diante. Essas classes helpers (auxiliares) são organizadas no namespace `yii\helpers` e
são todas classes estáticas (o que significa que contêm apenas propriedades e métodos estáticos e não devem ser instanciadas).

Você usa uma classe helper chamando diretamente um de seus métodos estáticos, como o seguinte:

```php
use yii\helpers\Html;

echo Html::encode('Test > test');
```

> Observação: Para oferecer suporte à [personalização de classes helper](#customizing-helper-classes),  o Yii divide cada classe helper principal
  em duas classes: uma classe base (ex. `BaseArrayHelper`) e uma classe concreta (ex. `ArrayHelper`).
  Ao usar um helper, você deve usar apenas a versão concreta e nunca a classe base.


Principais Classes Helper
-------------------

As seguintes classes helper são fornecidas nas versões Yii:

- [ArrayHelper](helper-array.md)
- Console
- FileHelper
- FormatConverter
- [Html](helper-html.md)
- HtmlPurifier
- Imagine (fornecido pela extensão yii2-imagine)
- Inflector
- [Json](helper-json.md)
- Markdown
- StringHelper
- [Url](helper-url.md)
- VarDumper


Personalização de Classes Helper <span id="customizing-helper-classes"></span>
--------------------------

Para personalizar uma classe helper principal (ex. [[yii\helpers\ArrayHelper]]), você deve criar uma nova classe que 
estende da classe base correspondente ao helper (ex. [[yii\helpers\BaseArrayHelper]]) e nomear a sua classe da mesma
forma que a classe concreta correspondente (ex. [[yii\helpers\ArrayHelper]]), Essa classe será então configurada para 
substituir a implementação original da estrutura.

O exemplo a seguir mostra como personalizar o método [[yii\helpers\ArrayHelper::merge()|merge()]] da classe
[[yii\helpers\ArrayHelper]]:

```php
<?php

namespace yii\helpers;

class ArrayHelper extends BaseArrayHelper
{
    public static function merge($a, $b)
    {
        // sua implementação personalizada
    }
}
```

Salve sua classe em um arquivo chamado `ArrayHelper.php`. O arquivo pode estar em qualquer diretório, por exemplo `@app/components`.

Em seguida, no [script de entrada](structure-entry-scripts.md) da sua aplicação, adicione a seguinte linha de código
depois do include do arquivo `yii.php` para dizer ao [autoloader de classes do Yii](concept-autoloading.md) para carregar sua classe
personalizada em vez da classe Helper original do framework:

```php
Yii::$classMap['yii\helpers\ArrayHelper'] = '@app/components/ArrayHelper.php';
```

Observe que personalizar as classes Helper só é útil se você quiser mudar o comportamento de uma função existente
dos Helpers. Se você deseja adicionar outras funções para usar em sua aplicação, é melhor criar um
Helper para isso.

---

### Guide Pt BR Runtime Overview (`docs/guide-pt-BR/runtime-overview.md`)

Visão Geral
===========

Cada vez que uma aplicação Yii processa uma requisição, ele passa por um fluxo 
de trabalho parecido como o seguinte:

1. Um usuário faz uma pedido para o [script de entrada](structure-entry-scripts.md) 
   `web/index.php`.
2. O script de entrada carrega a [configuração](concept-configurations.md) da 
   aplicação e cria uma instância da [aplicação](structure-applications.md) para 
   processar o pedido.
3. A aplicação resolve a [rota](runtime-routing.md) solicitada com a ajuda do 
   componente [request](runtime-requests.md) da aplicação.
4. A aplicação cria uma instância do [controller (controlador)](structure-controllers.md) 
   para processar o pedido.
5. O controller (controlador) cria uma instância da [ação](structure-controllers.md) 
   e executar os filtros para a ação.
6. Se qualquer filtro falhar, a ação será cancelada.
7. Se todos os filtros passarem, a ação será executada.
8. A ação carrega os dados do model (modelo), possivelmente a partir de um banco 
   de dados.
9. A ação renderiza uma view (visão), com os dados fornecidos pelo model (modelo).
10. O resultado da renderização é devolvida para o componente [response](runtime-responses.md) 
    da aplicação.
11. O componente response envia o resultado da renderização para o navegador do 
    usuário.

O diagrama a seguir mostra como uma aplicação processa um pedido.



Nesta seção, descreveremos com mais detalhes como alguns destes passos trabalham.

---

### Guide Pt BR Structure Overview (`docs/guide-pt-BR/structure-overview.md`)

Visão Geral
===========

As aplicações do Yii são organizadas de acordo com o padrão de projeto
[model-view-controller (MVC)](https://pt.wikipedia.org/wiki/MVC)
(modelo-visão-controlador). Os [models](structure-models.md) representam dados,
lógica e regras de negócio; as [views](structure-views.md) são a representação
da saída dos modelos; e os [controllers](structure-controllers.md) recebem entradas
e as convertem em comandos para os [models](structure-models.md) e as [views](structure-views.md).

Além do MVC, as aplicações do Yii também possuem as seguintes entidades:

* [scripts de entrada](structure-entry-scripts.md): são scripts PHP que são
  diretamente acessíveis aos usuários finais. São responsáveis por iniciar o
  ciclo de tratamento de uma requisição.
* [aplicações](structure-applications.md): são objetos globalmente acessíveis que
  gerenciam os componentes da aplicação e os coordenam para atender às requisições.
* [componentes da aplicação](structure-application-components.md): são objetos
  registrados com as aplicações e fornecem vários serviços para atender às
  requisições.
* [módulos](structure-modules.md): são pacotes auto-contidos que contém um MVC
  completo por si sós. Uma aplicação pode ser organizada em termos de múltiplos
  módulos.
* [filtros](structure-filters.md): representam código que precisa ser chamado
  pelos controllers antes e depois do tratamento propriamente dito de cada
  requisição.
* [widgets](structure-widgets.md): são objetos que podem ser embutidos em
  [views](structure-views.md). Podem conter lógica de controller e podem ser
  reutilizados em diferentes views.

O diagrama a seguir demonstra a estrutura estática de uma aplicação:

---

### Guide Pt BR Test Overview (`docs/guide-pt-BR/test-overview.md`)

Testes
=======

O teste é uma parte importante do desenvolvimento de software. Se estamos conscientes disso ou não, Realizamos testes continuamente.
Por exemplo, enquanto escrevemos uma classe PHP, podemos depurá-lo passo a passo ou simplismente usar declarações echo ou die para verificar se a implantação está de acordo com nosso plano inicial. 
No caso de uma aplicação web, estamos entrando em alguns  testes de dados em forma de assegurar que a página interage com a gente como esperado.

O processo de teste pode ser automatizado de modo que cada momento em que precisamos para verificar alguma coisa, só precisamos chamar o código que faz isso por nós. O código que verifica o resultado coincide com o que temos planejado é chamado de teste e o processo de sua criação e posterior execução é conhecido como teste automatizado,
que é o principal tema destes capítulos de testes.


Desenvolvendo com testes
------------------

Test-Driven Development (TDD), and Behavior-Driven Development (BDD) são abordagens de desenvolvimento de software, 
descrevendo o comportamento de um trecho de código ou todo o recurso como um conjunto de cenários ou testes antes de escrever 
código real e só então criar a aplicação que permite que estes testes passem verificando se comportamento a que se destina é conseguido.

O processo de desenvolvimento de uma funcionalidade é a seguinte:

- Criar um novo teste que descreve uma funcionalidade a ser implementada.
- Execute o novo teste e verifique se ele falha. isto é esperado já que não há nenhuma implementação ainda.
- Escrever um código simples para fazer o novo teste passar.
- Executar todos os testes e garantir que todos eles passam.
- Melhorar código e certificar-se de testes ainda estão OK.

Depois feito o processo é repetido novamente para outras funcionalidades ou melhorias. 
Se uma funcionalidade existente deve ser alterada, os testes devem ser mudadas também.

> Dica:  Se você sentir que você está perdendo tempo fazendo um monte de pequenas e simples iterações, experimente cobrindo mais por você.
> Cenários de teste é para que você faça mais antes de executar testes novamente. Se você está depurando muito, tente fazer o oposto.

A razão para criar testes antes de fazer qualquer implementação é que ela nos permite focar no que queremos alcançar e totalmente mergulhar "como fazê-lo" depois.
Normalmente, leva a melhores abstrações e manutenção de teste mais fácil quando se trata de ajustes na funcionalidade ou de menos componentes acoplados.
  
Assim, para resumir as vantagens de tal abordagem são as seguintes:

- Mantém-se focado em uma coisa de cada vez que resulta em uma melhor planejamento e implementação.
- Resultados cobertos por testes para mais funcionalidade em maior detalhe, ou seja, se os testes são OK provavelmente nada está quebrado.

No longo prazo, geralmente, dá-lhe um boa melhoria na produtividade.

> Dica: Se você quiser saber mais sobre os princípios de levantamento de requisitos de software e modelagem do assunto
> esta é uma referência boa para aprender [Domain Driven Development (DDD)] (https://en.wikipedia.org/wiki/Domain-driven_design).

Quando e como testar
------------------

Enquanto a primeira abordagem de teste descrito acima faz sentido em longo prazo para projetos relativamente complexos e que seria um exagero
para os mais simples. Existem alguns indicadores de quando é apropriado:

- Projeto já é grande e complexo.
- Requisitos do projeto estão começando a ficarem complexos. Projeto cresce constantemente.
- Projeto pretende ser a longo prazo.
- O custo da falha é muito alta.

Não há nada errado na criação de testes que abrangem o comportamento de implementação existente.

- Projeto é um legado para ser gradualmente renovada.
- Você tem um projeto para trabalhar e não tem testes.

Em alguns casos, qualquer forma de teste automatizado poderia ser um exagero:

- Projeto é simples e não está ficando mais complexo.
- É um projeto emporal eque deixarão de trabalhar nele.

Ainda assim, se você tiver tempo é bom automatizar testes nestes casos também.

Outras leituras
-------------

- Test Driven Development: By Example / Kent Beck. ISBN: 0321146530.

---

### Guide Ru Caching Overview (`docs/guide-ru/caching-overview.md`)

Кэширование
==========

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

Кэширование может использоваться на различных уровнях и в различных местах веб-приложения. На стороне сервера, на более
низком уровне мы используем кэширование для хранения основных данных, таких как список последних полученных из базы
данных статьей. На более высоком уровне кэш может использоваться для хранения фрагментов или целых веб-страниц. Таких,
например, как результат рендеринга последних статьей. На стороне клиента для сохранения содержимого недавно посещенных
страниц в кэше браузера может использоваться HTTP-кэширование.

Yii поддерживает все эти механизмы кэширования:

* [Кэширование данных](caching-data.md)
* [Кэширование фрагментов](caching-fragment.md)
* [Кэширование страниц](caching-page.md)
* [HTTP-кэширование](caching-http.md)

---

### Guide Ru Helper Overview (`docs/guide-ru/helper-overview.md`)

Хелперы
=======

> Note: Этот раздел находиться в стадии разработки.

Yii предоставляет много классов, которые помогают упростить общие задачи программирования, такие как манипуляция со строками или массивами, генерация HTML-кода, и так далее. Все helper-классы организованы в рамках пространства имен `yii\helpers` и являются статическими классами
 (это означает, что они содержат в себе только статические свойства и методы, и объекты статического класса создать нельзя).

Вы можете использовать helper-класс с помощью вызова одного из статических методов, как показано ниже:

```php
use yii\helpers\Html;

echo Html::encode('Test > test');
```

> Note: Помощь в [настройке helper-классов](#customizing-helper-classes), в Yii каждый основной helper состоит из двух классов: базовый класс (например, `BaseArrayHelper`) и конкретный класс (например, `ArrayHelper`).
  Когда вы используете helper, вы должны использовать только конкретные версии классов и никогда не использовать базовые классы.


Встроенные хелперы
------------------

В этой версии Yii предоставляются следующие основные helper-классы:

- [ArrayHelper](helper-array.md)
- Console
- FileHelper
- FormatConverter
- [Html](helper-html.md)
- HtmlPurifier
- Imagine (provided by yii2-imagine extension)
- Inflector
- Json
- Markdown
- StringHelper
- [Url](helper-url.md)
- VarDumper


Настройка хелперов <span id="customizing-helper-classes"></span>
--------------------------

Для настройки основных helper-классов (например, [[yii\helpers\ArrayHelper]]), вы должны создать расширяющийся класс из помощников соответствующих базовых классов (например, [[yii\helpers\BaseArrayHelper]]) и дать похожее название вашему классу с соответствующим конкретному классу (например, [[yii\helpers\ArrayHelper]]), в том числе его пространство имен. Тогда созданный класс заменит оригинальную реализацию в фреймворке.

В следующих примерах показывается как настроить метод [[yii\helpers\ArrayHelper::merge()|merge()]]
[[yii\helpers\ArrayHelper]] класса:

```php
<?php

namespace yii\helpers;

class ArrayHelper extends BaseArrayHelper
{
    public static function merge($a, $b)
    {
        // ваша собственная реализация
    }
}
```

Сохраните ваш класс в файле с именем `ArrayHelper.php`. Файл должен находиться в другой директории, например `@app/components`.

Далее, в приложении [входной скрипт](structure-entry-scripts.md), добавьте следующую строчку кода
после подключения `yii.php` файла, которая сообщит [автозагрузка классов Yii](concept-autoloading.md) загрузить
ваш класс вместо оригинального helper-класса фреимворка:

```php
Yii::$classMap['yii\helpers\ArrayHelper'] = '@app/components/ArrayHelper.php';
```

Обратите внимание что пользовательская настройка helper-классов полезна только, если вы хотите изменить поведение существующей функции helper-классов. Если вы хотите добавить дополнительные функции, для использования в вашем приложении, будет лучше создать отдельный helper.

---

### Guide Ru Runtime Overview (`docs/guide-ru/runtime-overview.md`)

Обзор
========

Все запросы, обрабатываемые Yii приложением, проходят подобный путь.

1. Пользователь создает запрос ко [входному скрипту](structure-entry-scripts.md) `web/index.php`.
2. Входной скрипт загружает [конфигурацию](concept-configurations.md) и создает экземпляр [приложения](structure-applications.md) для обработки запроса.
3. Приложение определяет запрошенный [маршрут](runtime-routing.md) при помощи компонента [request](runtime-requests.md).
4. Приложение создает экземпляр [контроллера](structure-controllers.md) для обработки запроса.
5. Контроллер создает экземпляр [действия](structure-controllers.md) и выполняет фильтры для этого действия.
6. При неудачном выполнении любого [фильтра](structure-filters.md), действие не выполняется.
7. При успешном выполнении всех фильтров, выполняется действие.
8. Действие загружает [модель](structure-models.md) данных, возможно, из базы данных.
9. Действие рендерит [представление](structure-views.md) и передает ему модель данных.
10. Результат рендеринга передается в компонент приложения [response](runtime-responses.md).
11. Компонент response посылает готовые данные пользователю.

Ниже представлена диаграмма обработки запроса приложением.



В данном разделе описаны подробности некоторых этапов обработки запроса.

---

### Guide Ru Security Overview (`docs/guide-ru/security-overview.md`)

Безопасность
========
Хорошая безопасность жизненно важна для успеха любого приложения. К сожалению, многие разработчики не уделяют ей должного внимания. Происходит это либо из-за недостатка понимания, либо из-за того, что это слишком сложно. Чтобы сделать ваше приложение максимально безопасным, в Yii включено несколько превосходных и простых в использовании функций безопасности.

* [Аутентификация](security-authentication.md)
* [Авторизация](security-authorization.md)
* [Работа с паролями](security-passwords.md)
* [Криптография](security-cryptography.md)
* [Безопасность видов](structure-views.md#security)
* [Клиенты авторизации](https://github.com/yiisoft/yii2-authclient/blob/master/docs/guide/README.md)
* [Лучшие практики](security-best-practices.md)
* [Доверенные прокси и заголовки](runtime-requests.md#trusted-proxies)

---

### Guide Ru Structure Overview (`docs/guide-ru/structure-overview.md`)

Обзор
=====

Yii приложения организованы согласно шаблону проектирования [модель-представление-контроллер (MVC)](https://ru.wikipedia.org/wiki/Model-View-Controller).
[Модели](structure-models.md) представляют собой данные, бизнес логику и бизнес правила; [представления](structure-views.md)
отвечают за отображение информации, в том числе и на основе данных, полученных из моделей; [контроллеры](structure-controllers.md) 
принимают входные данные от пользователя и преобразовывают их в понятный для [моделей](structure-models.md) формат и команды, а также отвечают за отображение 
нужного представления.

Кроме MVC, Yii приложения также имеют следующие сущности:

* [входные скрипты](structure-entry-scripts.md): это PHP скрипты, которые доступны напрямую конечному пользователю приложения.
  Они ответственны за запуск и обработку входящего запроса;
* [приложения](structure-applications.md): это глобально доступные объекты, которые осуществляют корректную работу различных 
  компонентов приложения и их координацию для обработки запроса;
* [компоненты приложения](structure-application-components.md): это объекты, зарегистрированные в приложении и предоставляющие
  различные возможности для обработки текущего запроса;
* [модули](structure-modules.md): это самодостаточные пакеты, которые включают в себя полностью все средства для MVC.
  Приложение может быть организованно с помощью нескольких модулей;
* [фильтры](structure-filters.md): это код, который должен быть выполнен до и после обработки запроса контроллерами;
* [виджеты](structure-widgets.md): это объекты, которые могут включать в себя [представления](structure-views.md).
  Они могут содержать различную логику и быть использованы в различных представлениях.

Ниже на диаграмме представлена структурная схема приложения:

---

### Guide Ru Test Overview (`docs/guide-ru/test-overview.md`)

Тестирование
============

Тестирование является важной составляющей разработки программного обеспечения. Мы проводим тестирование непрерывно, осознаем мы это или нет. Например, когда мы пишем класс на языке PHP, мы можем отлаживать его шаг за шагом или просто использовать `echo` или `die` для проверки, что реализация работает в соответствии с намеченным планом. В случае веб приложения, мы вводим некоторые тестовые данные в форму для того, чтобы убедиться, что страница взаимодействует с нами, как ожидается.

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

Разработка с тестами
--------------------

Разработка через тестирование (TDD) и разработка через поведение (BDD) - это подходы разработки программного обеспечения, в рамках которых поведение части кода или целая фича описывается в виде набора сценариев или тестов ДО написания фактического кода и только
затем создается реализация. Тем самым мы можем использовать данные тесты для проверки, что достигается заданное поведение.

Процесс разработки фичи следующий:

- Создать новый тест, описывающий функцию, которая будет реализована.
- Запустить новый тест и убедиться, что он терпит неудачу. Это ожидаемо, т.к. на данный момент еще нет конкретной реализации.
- Написать простой код, чтобы новый тест отрабатывал без ошибок.
- Запустить все тесты и убедиться, что они отрабатывают без ошибок
- Улучшить код и убедиться, что все тесты все еще отрабатывают без ошибок

После того как это завершено, процесс повторяется снова для другой фичи или улучшения. Если существующая фича должна быть изменена, то и тесты также должны быть изменены.

> Tip: Если вы чувствуете, что вы теряете время выполняя много мелких и простых итераций, попробуйте покрыть это
> вашим тестовым сценарием перед следующим выполнением тестов. Если вы слишком много отлаживаете, попробуйте сделать обратное.

Написание тестов до реализации конкретного функционала позволяет нам сосредоточиться на том, что мы хотим достичь и полностью
погрузиться в "как это сделать" впоследствии. 

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

Таким образом, плюсы этого подхода следующие:

- Позволяет вам сосредоточиться на одной вещи, что в свою очередь приводит к улучшению планирования и реализации.
- Более подробное покрытие тестами функционала. Таким образом, если все тесты отрабатывают без ошибок, скорее всего, ничего не сломано.

В долгосрочной перспективе это, как правило, дает вам хороший эффект экономии времени.

> Tip: Если вы хотите узнать больше о принципах сбора требования программного обеспечения и моделирования
> предметной области, рекомендуем изучить [Проблемно-ориентированное проектирование (DDD)](https://en.wikipedia.org/wiki/Domain-driven_design).

Когда и как тестировать
-----------------------

Принцип разработки, описанный выше, имеет смысл применять для долгосрочных и относительно сложных проектов, в то время как для простых это может быть излишним. Есть несколько показателей того, когда данный подход уместен:

- Проект уже большой и сложный.
- Требования к проекту начинают усложняться. Проект постоянно растет.
- Долгосрочный проект.
- Цена ошибки очень высока

Нет ничего плохого в создании тестов, покрывающих поведение существующей реализации.

- Legacy-проект который постоянно обновляется.
- Вам поручили работу над проектом, в котором нет ни одного теста.

В некоторых случаях автоматизированное тестирование может быть излишним:

- Проект простой и не станет более сложным.
- Это одноразовый проект, который больше не будет дорабатываться.

Тем не менее, если у вас есть время, было бы хорошо автоматизировать тестирование и в этих случаях.

Что почитать
------------

- Экстремальное программирование. Разработка через тестирование / Кент Бек. ISBN: 0321146530.

---

### Guide Uk Structure Overview (`docs/guide-uk/structure-overview.md`)

Огляд
=====

Додатки Yii організовані згідно архітектурного шаблону [Модель-Представлення-Контролер (MVC)](https://uk.wikipedia.org/wiki/Модель-вид-контролер).
[Моделі](structure-models.md) являють собою дані, бізнес-логіку та бізнес-правила; 
[представлення](structure-views.md) відповідають за відображення даних моделей;
[контролери](structure-controllers.md) приймають вхідні дані від користувача і перетворюють їх у команди для
[моделей](structure-models.md) та [представлень](structure-views.md).

Окрім MVC, Yii додаток також має наступні сутності:

* [вхідні скрипти](structure-entry-scripts.md): це PHP-скрипти, які доступні напряму кінцевому користувачу додатка.
  Вони відповідають за запуск циклу обробки запиту.
* [додатки](structure-applications.md): це глобально доступні об’єкти, які відповідають за коректну роботу різних 
  компонентів додатка і їх координацію для обробки запиту.
* [компоненти додатку](structure-application-components.md): це об’єкти, зареєстровані в додатку і які надають
  різноманітні можливості для обробки запитів.
* [модулі](structure-modules.md): це самодостатні пакунки, що включають в себе повністю всі ресурси для MVC.
  Додаток може бути організовано за допомогою декількох модулів.
* [фільтри](structure-filters.md): це код, який повинен бути виконаний до і після обробки запиту контролерами.
* [віджети](structure-widgets.md): це об’єкти, які можуть бути вбудованими у [представлення](structure-views.md).
  Вони можуть містити логіку контролера і можуть бути повторно використаними у різних представленнях.

На наступній діаграмі наведена структурна схема додатку:

---

### Guide Vi Structure Overview (`docs/guide-vi/structure-overview.md`)

Tổng quan về kiến trúc ứng dụng
========

Các ứng dụng Yii được tổ chức dựa theo mẫu thiết kế [model-view-controller (MVC)](https://vi.wikipedia.org/wiki/MVC)
. [Models](structure-models.md) chứa nghiệp vụ logic, truy xuất database và định nghĩa các quy tắc xác thực dữ liệu; [views](structure-views.md)
đảm nhận việc hiển thị thôn tin của model; và [controllers](structure-controllers.md) có nhiệm vụ điều hướng các yêu cầu và chuyển các tương tác giữa
[models](structure-models.md) và [views](structure-views.md).

Ngoài mô hình MVC, ứng dụng Yii có những phần phần sau đây:

* [entry scripts](structure-entry-scripts.md): là file đầu tiên chứa các mã nguồn để tiếp nhận các request của người dùng.
  Thành phần này có trách nhiệm bắt đầu về chu trình xử lý các yêu cầu trong ứng dụng.
* [ứng dụng](structure-applications.md): là đối tượng có phạm vi truy cập toàn cục giúp quản lý các thành phần trong ứng dụng
  và điều hướng chúng để thực hiện các yêu cầu.
* [thành phần](structure-application-components.md): là đối tượng được đăng ký với ứng dụng
  và cung cấp những dịch vụ cho các yêu cầu xử lý .
* [modules](structure-modules.md): là những gói có chứa mô hình MVC hoàn chỉnh.
  Một ứng dụng có thể được tổ chức dưới dạng nhiều module.
* [filters](structure-filters.md): chứa những mã nguồn cần được gọi trước và sau việc xử lý của từng yêu cầu của bộ điều khiển
  handling of each request by controllers.
* [widgets](structure-widgets.md): các đối tượng được nhúng vào [views](structure-views.md). Các widget có thể chứa các nghiệp vụ logic
  và có thể tái sử dụng ở những view khác.

Mô hình sau mô tả cấu trúc ứng dụng ở dạng tĩnh:

---

### Guide Zh CN Caching Overview (`docs/guide-zh-CN/caching-overview.md`)

缓存
=======

缓存是提升 Web 应用性能简便有效的方式。
通过将相对静态的数据存储到缓存并在收到请求时取回缓存，
应用程序便节省了每次重新生成这些数据所需的时间。

缓存可以应用在 Web 应用程序的任何层级任何位置。
在服务器端，在较的低层面，缓存可能用于存储基础数据，例如从数据库中取出的最新文章列表；
在较高的层面，缓存可能用于存储一段或整个 Web 页面，
例如最新文章的渲染结果。在客户端，HTTP 缓存可能用于
将最近访问的页面内容存储到浏览器缓存中。

Yii 支持如上所有缓存机制：

* [数据缓存](caching-data.md)
* [片段缓存](caching-fragment.md)
* [页面缓存](caching-page.md)
* [HTTP 缓存](caching-http.md)

---

### Guide Zh CN Helper Overview (`docs/guide-zh-CN/helper-overview.md`)

助手类（Helpers）
==============

> Note: 这部分正在开发中。

Yii 提供许多类来简化常见编码，如对字条串或数组的操作，
HTML 代码生成，等等。这些助手类被编写在命名空间 `yii\helpers` 下，并且
全是静态类 （就是说它们只包含静态属性和静态方法，而且不能实例化）。

可以通过调用其中一个静态方法来使用助手类，如下：

```php
use yii\helpers\Html;

echo Html::encode('Test > test');
```

> Note: 为了支持 [自定义助手类](#customizing-helper-classes)，Yii 将每一个助手类
  分隔成两个类：一个基类 (例如 `BaseArrayHelper`) 和一个具体的类 (例如 `ArrayHelper`)。
  当使用助手类时，应该仅使用具体的类版本而不使用基类。


核心助手类（Core Helper Classes）
-----------------------------

Yii 发布版中提供以下核心助手类：

- [ArrayHelper](helper-array.md)
- Console
- FileHelper
- [Html](helper-html.md)
- HtmlPurifier
- Imagine（由 yii2-imagine 扩展提供）
- Inflector
- Json
- Markdown
- Security
- StringHelper
- [Url](helper-url.md)
- VarDumper


自定义助手类（Customizing Helper Classes） <span id="customizing-helper-classes"></span>
--------------------------------------

如果想要自定义一个核心助手类 (例如 [[yii\helpers\ArrayHelper]])，你应该创建一个新的类继承
helpers对应的基类 (例如 [[yii\helpers\BaseArrayHelper]]) 并同样的命
名你的这个类 (例如 [[yii\helpers\ArrayHelper]])，包括它的命名空间。这个类
会用来替换框架最初的实现。

下面示例显示了如何自定义 [[yii\helpers\ArrayHelper]] 类的
[[yii\helpers\ArrayHelper::merge()|merge()]] 方法：

```php
<?php

namespace yii\helpers;

class ArrayHelper extends BaseArrayHelper
{
    public static function merge($a, $b)
    {
        // 你自定义的实现
    }
}
```

将你的类保存在一个名为 `ArrayHelper.php` 的文件中。该文件可以在任何目录，例如 `@app/components`。

接下来，在你的应用程序 [入口脚本](structure-entry-scripts.md) 处，在引入的 `yii.php` 文件后面
添加以下代码行，用 [Yii 自动加载器](concept-autoloading.md) 来加载自定义类
代替框架的原始助手类：

```php
Yii::$classMap['yii\helpers\ArrayHelper'] = '@app/components/ArrayHelper.php';
```

注意，自定义助手类仅仅用于如果你想要更改助手类中
现有的函数的行为。如果你想为你的应用程序添加附加功能，最好为它创建一个单独的
助手类。

---

### Guide Zh CN Runtime Overview (`docs/guide-zh-CN/runtime-overview.md`)

运行机制概述
========

每一次 Yii 应用开始处理 HTTP 请求时，它都会进行一个近似的流程。

1. 用户提交指向 [入口脚本](structure-entry-scripts.md) `web/index.php` 的请求。
2. 入口脚本会加载 [配置数组](concept-configurations.md) 并创建一个
   [应用](structure-applications.md) 实例用于处理该请求。
3. 应用会通过 [request（请求）](runtime-requests.md) 应用组件
   解析被请求的 [路由](runtime-routing.md)。
4. 应用创建一个 [controller（控制器）](structure-controllers.md) 实例具体处理请求。
5. 控制器会创建一个 [action（动作）](structure-controllers.md) 实例并为该动作执行相关的 Filters（访问过滤器）。
6. 如果任何一个过滤器验证失败，该动作会被取消。
7. 如果全部的过滤器都通过，该动作就会被执行。
8. 动作会加载一个数据模型，一般是从数据库中加载。
9. 动作会渲染一个 View（视图），并为其提供所需的数据模型。
10. 渲染得到的结果会返回给 [response（响应）](runtime-responses.md) 应用组件。
11. 响应组件会把渲染结果发回给用户的浏览器。

下面的示意图展示了应用是如何处理一个请求的。



在这个版块中，我们会更加详细地描述某些步骤的具体运作。

---

### Guide Zh CN Security Overview (`docs/guide-zh-CN/security-overview.md`)

安全（Security）
==============

良好的安全性对于任何应用的健康和成功都至关重要。
不幸的是，许多开发人员在安全方面偷工减料，要么是由于缺乏理解，要么是由于实现过于困难。 
为了尽可能保证您的 Yii 应用程序的安全，Yii 包含了一些优秀且易于使用的安全功能。

* [认证](security-authentication.md)
* [授权](security-authorization.md)
* [使用密码](security-passwords.md)
* [加密](security-cryptography.md)
* [视图安全](structure-views.md#security)
* [身份验证客户端](https://github.com/yiisoft/yii2-authclient/blob/master/docs/guide/README.md)
* [最佳实践](security-best-practices.md)
* [受信任的代理和头文件](runtime-requests.md#trusted-proxies)

---

### Guide Zh CN Structure Overview (`docs/guide-zh-CN/structure-overview.md`)

总览
========

Yii 应用参照[模型-视图-控制器 （MVC）](https://zh.wikipedia.org/wiki/MVC)
设计模式来组织。 [模型](structure-models.md)代表数据、业务逻辑和规则；
[视图](structure-views.md)展示模型的输出；[控制器](structure-controllers.md)
接受出入并将其转换为[模型](structure-models.md)和[视图](structure-views.md)命令。

除了 MVC, Yii 应用还有以下部分：

* [入口脚本](structure-entry-scripts.md)：终端用户能直接访问的 PHP 脚本，
  负责启动一个请求处理周期。
* [应用](structure-applications.md)：能全局范围内访问的对象，
  管理协调组件来完成请求.
* [应用组件](structure-application-components.md)：在应用中注册的对象，
  提供不同的功能来完成请求。
* [模块](structure-modules.md)：包含完整 MVC 结构的独立包，
  一个应用可以由多个模块组建。 
* [过滤器](structure-filters.md)：控制器在处理请求之前或之后
  需要触发执行的代码。
* [小部件](structure-widgets.md)：可嵌入到[视图](structure-views.md)中的对象，
  可包含控制器逻辑，可被不同视图重复调用。

下面的示意图展示了 Yii 应用的静态结构：

---

### Guide Zh CN Test Overview (`docs/guide-zh-CN/test-overview.md`)

测试
=======

测试是软件开发的一个重要组成部分。不管我们是否意识到，我们一直在不断地进行测试。
例如，当我们在用 PHP 写一个类的时候，我们可能用 echo 或者 die 语句一步一步简单的调试
验证我们实现的代码是否按照最初的计划工作。在开发 web 应用的时候，我们在表单中输入
一些测试数据来确保页面能够如预期那样和我们进行交互。

测试过程可能是自动的，所以每次我们需要验证的时候，我们只需要调用它就可以测试代码了。
验证代码执行结果是否符合我们的计划叫做测试，
测试过程的创建以及进一步执行叫做*自动化测试*，
这是这些测试章节的主要主题。


## 带着测试进行开发

测试驱动开发（TDD）和行为驱动开发（BDD）在开始编写实际代码之前，
首先通过描述一段代码的行为或将其作为一组场景或测试的全部特征，
然后创建符合这些测试预期验证
的行为实现。

开发一个功能的过程如下：

- 创建一个描述一个功能被实现测试。
- 运行这个测试来确保功能失败，因为这是没有实现之前的预期。
- 编写简单代码确保这个测试通过。
- 运行所有测试确保所有测试都通过。
- 优化代码确保测试依然可以通过。

走完上面的过程之后，为其他功能或者扩展重复上面测试过程。如果功能发生变化，测试也需
要跟着变化。

> Tip: 如果你觉得你做一些很小很简单的迭代是在浪费时间，请尝试覆盖更多的测试
> 场景，这样你就可以在执行测试之前做更多的尝试。如果你的调试过多，试着做相反的工作。

在做一些具体的实现之前创建测试的原因是，这允许我们后期专注于我们想要的实现，并且
可以花费更多的精力到实现细节。在涉及功能调整的时候，这会使得抽象更合理、测试维护
更简单或者使得耦合元件更少。

这种做法的优点如下：

- 在计划和实现发生变更的时候，可以让你在同一时间只专注于一件事情。
- 更多功能更详细的覆盖测试的结果，如果测试都通过好比再也没有什么问题了。

在很长一段时间内，这通常会给你提供一个有效的时间节省。

## 什么时候测试，怎么测试？

在测试的时候，对于一些相对复杂的项目上面的内容是非常有意义的，但对于一些比较
简单的项目就做的有些极端了。适用场景如下：

- 项目已经很大且复杂。
- 项目需求开始变得复杂起来。项目不断发展。
- 项目历时很长。
- 失败的代价非常高。

在现有的实现行为中进行覆盖测试是非常适合的。

- 项目是一个逐步更新的遗产。
- 你有一个还没有经过测试的项目要做。

在一些情况下，任何形式的自动化测试都是过于极端的：

- 项目很简单，也不会变得复杂。
- 过期不再工作的一次性项目。

假如你有很多的时间，在这种情况下进行自动测试也很好。

## 深度阅读

- 测试驱动开发：示例 / Kent Beck。 ISBN：0321146530。

---

### Guide Caching Overview (`docs/guide/caching-overview.md`)

Caching
=======

Caching is a cheap and effective way to improve the performance of a Web application. By storing relatively
static data in cache and serving it from cache when requested, the application saves the time that would be
required to generate the data from scratch every time.

Caching can occur at different levels and places in a Web application. On the server-side, at the lower level,
cache may be used to store basic data, such as a list of most recent article information fetched from database;
and at the higher level, cache may be used to store fragments or whole of Web pages, such as the rendering result
of the most recent articles. On the client-side, HTTP caching may be used to keep most recently visited page content in
the browser cache.

Yii supports all these caching mechanisms:

* [Data caching](caching-data.md)
* [Fragment caching](caching-fragment.md)
* [Page caching](caching-page.md)
* [HTTP caching](caching-http.md)

---

### Guide Helper Overview (`docs/guide/helper-overview.md`)

Helpers
=======

> Note: This section is under development.

Yii provides many classes that help simplify common coding tasks, such as string or array manipulations,
HTML code generation, and so on. These helper classes are organized under the `yii\helpers` namespace and
are all static classes (meaning they contain only static properties and methods and should not be instantiated).

You use a helper class by directly calling one of its static methods, like the following:

```php
use yii\helpers\Html;

echo Html::encode('Test > test');
```

> Note: To support [customizing helper classes](#customizing-helper-classes), Yii breaks each core helper class
  into two classes: a base class (e.g. `BaseArrayHelper`) and a concrete class (e.g. `ArrayHelper`).
  When you use a helper, you should only use the concrete version and never use the base class.


Core Helper Classes
-------------------

The following core helper classes are provided in the Yii releases:

- [ArrayHelper](helper-array.md)
- Console
- FileHelper
- FormatConverter
- [Html](helper-html.md)
- HtmlPurifier
- Imagine (provided by yii2-imagine extension)
- Inflector
- [Json](helper-json.md)
- Markdown
- StringHelper
- [Url](helper-url.md)
- VarDumper


Customizing Helper Classes <span id="customizing-helper-classes"></span>
--------------------------

To customize a core helper class (e.g. [[yii\helpers\ArrayHelper]]), you should create a new class extending
from the helpers corresponding base class (e.g. [[yii\helpers\BaseArrayHelper]]) and name your class the same
as the corresponding concrete class (e.g. [[yii\helpers\ArrayHelper]]), including its namespace. This class
will then be set up to replace the original implementation of the framework.

The following example shows how to customize the [[yii\helpers\ArrayHelper::merge()|merge()]] method of the
[[yii\helpers\ArrayHelper]] class:

```php
<?php

namespace yii\helpers;

class ArrayHelper extends BaseArrayHelper
{
    public static function merge($a, $b)
    {
        // your custom implementation
    }
}
```

Save your class in a file named `ArrayHelper.php`. The file can be in any directory, for example `@app/components`.

Next, in your application's [entry script](structure-entry-scripts.md), add the following line of code
after including the `yii.php` file to tell the [Yii class autoloader](concept-autoloading.md) to load your custom
class instead of the original helper class from the framework:

```php
Yii::$classMap['yii\helpers\ArrayHelper'] = '@app/components/ArrayHelper.php';
```

Note that customizing of helper classes is only useful if you want to change the behavior of an existing function
of the helpers. If you want to add additional functions to use in your application, you may be better off creating a separate
helper for that.

---

### Guide Runtime Overview (`docs/guide/runtime-overview.md`)

Overview
========

Each time when a Yii application handles a request, it undergoes a similar workflow.

1. A user makes a request to the [entry script](structure-entry-scripts.md) `web/index.php`.
2. The entry script loads the application [configuration](concept-configurations.md) and creates
   an [application](structure-applications.md) instance to handle the request.
3. The application resolves the requested [route](runtime-routing.md) with the help of
   the [request](runtime-requests.md) application component.
4. The application creates a [controller](structure-controllers.md) instance to handle the request.
5. The controller creates an [action](structure-controllers.md) instance and performs the filters for the action.
6. If any [filter](structure-filters.md) fails, the action is cancelled.
7. If all filters pass, the action is executed.
8. The action loads a data [model](structure-models.md), possibly from a database.
9. The action renders a [view](structure-views.md), providing it with the data model.
10. The rendered result is returned to the [response](runtime-responses.md) application component.
11. The response component sends the rendered result to the user's browser.

The following diagram shows how an application handles a request.



In this section, we will describe in detail how some of these steps work.

---

### Guide Security Overview (`docs/guide/security-overview.md`)

Security
========

Good security is vital to the health and success of any application. Unfortunately, many developers cut corners when it
comes to security, either due to a lack of understanding or because implementation is too much of a hurdle. To make your
Yii powered application as secure as possible, Yii has included several excellent and easy to use security features.

* [Authentication](security-authentication.md)
* [Authorization](security-authorization.md)
* [Working with Passwords](security-passwords.md)
* [Cryptography](security-cryptography.md)
* [Views security](structure-views.md#security)
* [Auth Clients](https://github.com/yiisoft/yii2-authclient/blob/master/docs/guide/README.md)
* [Best Practices](security-best-practices.md)
* [Trusted proxies and headers](runtime-requests.md#trusted-proxies)

---

### Guide Structure Overview (`docs/guide/structure-overview.md`)

Overview
========

Yii applications are organized according to the [model-view-controller (MVC)](https://wikipedia.org/wiki/Model-view-controller)
architectural pattern. [Models](structure-models.md) represent data, business logic and rules; [views](structure-views.md)
are output representation of models; and [controllers](structure-controllers.md) take input and convert
it to commands for [models](structure-models.md) and [views](structure-views.md).

Besides MVC, Yii applications also have the following entities:

* [entry scripts](structure-entry-scripts.md): they are PHP scripts that are directly accessible by end users.
  They are responsible for starting a request handling cycle.
* [applications](structure-applications.md): they are globally accessible objects that manage application components
  and coordinate them to fulfill requests.
* [application components](structure-application-components.md): they are objects registered with applications and
  provide various services for fulfilling requests.
* [modules](structure-modules.md): they are self-contained packages that contain complete MVC by themselves.
  An application can be organized in terms of multiple modules.
* [filters](structure-filters.md): they represent code that need to be invoked before and after the actual
  handling of each request by controllers.
* [widgets](structure-widgets.md): they are objects that can be embedded in [views](structure-views.md). They
  may contain controller logic and can be reused in different views.

The following diagram shows the static structure of an application:

---

### Guide Test Overview (`docs/guide/test-overview.md`)

Testing
=======

Testing is an important part of software development. Whether we are aware of it or not, we conduct testing continuously.
For example, when we write a class in PHP, we may debug it step by step or simply use `echo` or `die` statements to verify
the implementation works according to our initial plan. In the case of a web application, we're entering some test data
in forms to ensure the page interacts with us as expected.

The testing process could be automated so that each time when we need to verify something, we just need to call up
the code that does it for us. The code that verifies the result matches what we've planned is called *test* and
the process of its creation and further execution is known as *automated testing*, which is the main topic of these
testing chapters.


## Developing with tests

Test-Driven Development (TDD) and Behavior-Driven Development (BDD) are approaches of developing
software by describing behavior of a piece of code or the whole feature as a set of scenarios or tests before
writing actual code and only then creating the implementation that allows these tests to pass verifying that intended
behavior is achieved.

The process of developing a feature is the following:

- Create a new test that describes a feature to be implemented.
- Run the new test and make sure it fails. It is expected since there's no implementation yet.
- Write simple code to make the new test pass.
- Run all tests and make sure they all pass.
- Improve code and make sure tests are still OK.

After it's done the process is repeated again for another feature or improvement. If the existing feature is to be changed,
tests should be changed as well.

> Tip: If you feel that you are losing time doing a lot of small and simple iterations, try covering more by your
> test scenario so you do more before executing tests again. If you're debugging too much, try doing the opposite.

The reason to create tests before doing any implementation is that it allows us to focus on what we want to achieve
and fully dive into "how to do it" afterwards. Usually it leads to better abstractions and easier test maintenance when
it comes to feature adjustments or less coupled components.

So to sum up the advantages of such approach are the following:

- Keeps you focused on one thing at a time which results in improved planning and implementation.
- Results in test-covering more features in greater detail i.e. if tests are OK most likely nothing's broken.

In the long term it usually gives you a good time-saving effect.

## When and how to test

While the test first approach described above makes sense for long term and relatively complex projects it could be overkill
for simpler ones. There are some indicators of when it's appropriate:

- Project is already large and complex.
- Project requirements are starting to get complex. Project grows constantly.
- Project is meant to be long term.
- The cost of the failure is too high.

There's nothing wrong in creating tests covering behavior of existing implementation.

- Project is a legacy one to be gradually renewed.
- You've got a project to work on and it has no tests.

In some cases any form of automated testing could be overkill:

- Project is simple and isn't getting any more complex.
- It's a one-time project that will no longer be worked on.

Still if you have time it's good to automate testing in these cases as well.

## Further reading

- Test Driven Development: By Example / Kent Beck. ISBN: 0321146530.

---

### Internals Ja Getting Started (`docs/internals-ja/getting-started.md`)

Yii 2 の開発を始めよう
=====================

環境をセットアップする方法については、[Yii 2 寄稿者のための Git ワークフロー](git-workflow.md) を参照してください。

---

### Internals Pl Getting Started (`docs/internals-pl/getting-started.md`)

Jak zacząć proces współtworzenia Yii 2
======================================

Zobacz [cykl produkcyjny Git dla kontrybutorów Yii 2](git-workflow.md), aby zapoznać się z informacjami o konfiguracji środowiska deweloperskiego.

---

### Internals Ru Getting Started (`docs/internals-ru/getting-started.md`)

Подготовка к разработке Yii 2
=====================================

Смотрите [Рабочий процесс Git для разработчиков Yii 2](git-workflow.md) о том, как подготовить ваше рабочее окружение.

---

### Internals Sr Latn Getting Started (`docs/internals-sr-Latn/getting-started.md`)

Kako započeti sa Yii 2 razvojem
===============================

Pogledajte [Git proces rada za Yii 2 saradnike](git-workflow.md) o tome kako podesiti vaše okruženje.

---

### Internals Uk Getting Started (`docs/internals-uk/getting-started.md`)

Підготовка до розробки Yii 2
============================

Інформація про те, як налаштувати середовище для розробки представлена у розділі [Робота з Git для учасників Yii 2](git-workflow.md).

---

### Internals Getting Started (`docs/internals/getting-started.md`)

Getting started with Yii 2 development
======================================

See [Git workflow for Yii 2 contributors](git-workflow.md) on how to set up your environment.

---

### Documentation Style Guide (`docs/documentation_style_guide.md`)

# Yii Documentation Style Guide

Guidelines to go by when writing or editing any Yii documentation.

*This needs to be expanded.*

## General Style

* Try to use an active voice.
* Use short, declarative sentences.
* Demonstrate ideas using code as much as possible.
* Never use "we". It's the Yii development team or the Yii core team. Better yet to put things in terms of the framework or the guide.
* Use the Oxford comma (e.g., "this, that, and the other" not "this, that and the other").

## Formatting

* Use *italics* for emphasis, never capitalization, bold, or underlines.

## Lists

* Numeric lists should be complete sentences that end with periods.
* Bullet lists should be fragments that end with semicolon except the last item, which should end with a period.

## Blocks

Blocks use the Markdown `> Type: `. There are four block types:

* `Warning`, for bad security things and other problems
* `Note`, to emphasize key concepts, things to avoid
* `Info`, general information (an aside); not as strong as a "Note"
* `Tip`, pro tips, extras, can be useful but may not be needed by everyone all the time

The sentence after the colon should begin with a capital letter.

When translating documentation, these Block indicators should not be translated.
Keeps them intact as they are and only translate the block content.
For translating the `Type` word, each guide translation should have a `blocktypes.json` file
containing the translations. The following shows an example for German:

```json
{
    "Warning:": "Achtung:",
    "Note:": "Hinweis:",
    "Info:": "Info:",
    "Tip:": "Tipp:"
}
```

## References

* Yii 2.0 or Yii 2 (not Yii2 or Yii2.0)
* Each "page" of the guide is referred to as a "section".
* References to Code objects:
  - Refer to classes using the full namespace: `yii\base\Model`
  - Refer to class properties using the static syntax even if they are not static: `yii\base\Model::$validators`
  - Refer to class methods using the static syntax even if they are not static and include parenthesis to make it clear, that it is a method: `yii\base\Model::validate()`
  - references to code objects should be written in `[[]]` to generate links to the API documentation. E.g. `[[yii\base\Model]]`, `[[yii\base\Model::$validators]]`, or `[[yii\base\Model::validate()]]`.

## Capitalizations

* Web, not web
* the guide or this guide, not the Guide

## Validating the docs

The following are some scripts that help find broken links and other issues in the guide:

Find broken links (some false-positives may occur):

    grep -rniP "\[\[[^\],']+?\][^\]]"  docs/guide*
    grep -rniP "[^\[]\[[^\]\[,']+?\]\]"  docs/guide*
    
## Attribution of Translators

The names of the translators will be listed among the guide authors in the
rendered versions of the guide.
Therefor in each guide directory for a different language than english a `translators.json` file
should be created that contains an array of names of the people who have participated in the translation.

```json
[
  "Jane Doe",
  "John Doe"
]
```

If you have contributed a significant part to the translation, feel free to send a pull request adding your name.

---

### Guide Ar Intro Yii (`docs/guide-ar/intro-yii.md`)

# <div dir="rtl">ما هي بيئة العمل Yii</div>

<p dir="rtl">Yii هو إطار PHP عالي الأداء يعتمد على المكونات لتطوير تطبيقات الويب الحديثة بسرعة.
إن الاسم "Yii" (يُنطق بـ "يي" أو "[جي:]" يعني "بسيطًا وتطوريًا" باللغة الصينية. ومن الممكن ايضا
    اعتباره اختصارًا لـ <b>Yes It Is</b>!</p>


# <div dir="rtl">ما هي أفضل التطبيقات أو البرمجيات التي يمكن برمجتها وتتناسب مع ال Yii</div>

<p dir="rtl">
Yii هو إطار عام لبرمجة الويب ، مما يعني أنه يمكن استخدامه لتطوير كافة أنواع
تطبيقات الويب باستخدام PHP. وذلك بسبب البنية القائمة على  البنية التركيبة لبيئة العمل وترابطها مع المكونات والتخزين المؤقت، وهو مناسب بشكل خاص لتطوير portals, forums, content management systems (CMS), e-commerce projects, RESTful Web services. وما إلى ذلك.
</p>


# <div dir="rtl">كيف يمكن مقارنة بيئة العمل الخاصة بال Yii مع الأطر أو بيئات العمل الأخرى؟</div>

<p dir="rtl">
    إذا كنت بالفعل على دراية بإطار العمل الأخرى ، فيمكنك معرفة كيف تتم مقارنة ال Yii:
</p>

<ul  dir="rtl">
    <li> مثل معظم أطر عمل ال PHP ، يطبق Yii النمط المعماري MVC (Model-View-Controller).</li>
<li> ال Yii يتبنى الفلسفة التي تقول أن الشيفرة البرمجية يجب أن تكتب بأسهل طريقها وادقها، ولكنها بذات الوقت يجب أن تكون أنيقة الكتابة مظهرا ومضمونا (شكلا وتطيبقا).</li>
<li> ال Yii هو إطار متكامل  (full stack) يوفر العديد من الميزات الجاهزة للإستخدام والمعدة مسبقا، مثل ال query builders وال ActiveRecord لقواعد البيانات العلاقئية (relational) وغير العلائقية (Nosql)، بالإضافة الى دعم وتجهيز ال RESTful API  والتخزين المؤقت (caching) وغيرها الكثير. </li> 
<li> من مميزات ال Yii إمكانية التعديل (استبدال جزء معين أو تخيصيص وإضافة) جزء معين على أغلب ال Yii core code، وبالإضافة الى هذا، يمكنك بناء ملحقات برمجية اعتمادا على ال core code، ومن ثم نشر هذه الشيفرة وتوزيعها واستخدامها دون وجود أي مشاكل أو صعوبة تذكر.</li>
<li> الأداء العالي هو الهدف الأساسي من ال Yii.</li>
    </ul>

<p dir="rtl">
ال Yii إطار عمل صمم من قبل فريق برمجي متكامل، فهو ليس مجرد عمل فردي ،  بل يتكون من <a href="https://www.yiiframework.com/team">فريق تطوير أساسي وقوي</a> ، بالإضافة إلى منتدى كبير
من المهنيين الذين يساهمون باستمرار في تطوير هذا الإطار. فريق المطورين الخاص بال Yii
يراقب عن كثب أحدث اتجاهات تطوير الويب وأفضل الممارسات والمميزات التي
وجدت في الأطر والمشاريع الأخرى. وتدرج بانتظام بإضافة أفضل الممارسات والميزات الى ال Yii عبر واجهات بسيطة وأنيقة.
</p>



# <div dir="rtl">الإصدارات الخاصة بال Yii</div>

<p dir="rtl">
    يتوفر لدى Yii حاليًا إصداران رئيسيان: 1.1 و 2.0. الإصدار 1.1 هو الجيل القديم وهو الآن في وضع الصيانة. الإصدار 2.0 هو إعادة كتابة وهيكلة كاملة لل Yii، تم  اعتماد أحدث التقنيات والبروتوكولات فيها مثل  including Composer, PSR, namespaces, traits والكثير من الأمور الأخرى، وفي هذه الإرشادات، سيكون الكلام كله موجها الى الإصدار الثاني من بيئة العمل ال Yii.
</p>

# <div dir="rtl">المتطلبات الأساسية للعمل على إطار ال Yii</div>

<ul dir="rtl">
    <li>الإصدار PHP 7.4.0 أو أكثر</li>
    <li>المعرفة الأساسية بمفاهيم البرمجة كائنية التوجه OOP</li>
    <li>المعرفة بآخر وأحدث التقنيات الموجودة بال php مثل ال namespaces, traits، الفهم لهذه المفاهيم سيسهل عليك العمل كثيرا</li>
</ul>

<p dir="rtl">
    ملاحظة: يمكن التحقق من توافق المتطلبات الخاصة بك مع ال yii من خلال الدخول الى الصفحة requirement الموجودة بال yii
    </p>

---

### Guide Ar Start Databases (`docs/guide-ar/start-databases.md`)

# <div dir="rtl">التعامل مع قواعد البيانات</div>

<p dir="rtl">
    في هذا الجزء التعليمي ستتعلم آلية إنشاء صفحة جديدة تعرض بيانات يتم جلبها من قاعدة البيانات  -في هذا المثال، البيانات تخص ال country-، هذه البيانات سيتم جلبها من جدول موجود في قاعدة البيانات يسمى ب <code>country</code>. لتحقيق هذا المهمة، ستقوم بعمل ال config الخاص بالإتصال بقاعدة بيانات، بالإضافة لإنشاء ال <a href="../guide/db-active-record.md">Active Record</a> class، وتعريف ال <a href="../guide/structure-controllers.md">action</a>، وإنشاء <a href="../guide/structure-views.md">view</a> لهذه الصفحة. 
</p>


<p dir="rtl">
 في هذا الشرح ستتعلم كيف يمكنك القيام بما يلي: 
</p>

<ul dir="rtl">
    <li>إعداد ال connection الخاص بقاعدة البيانات</li>
    <li> التعرف على ال active record.</li>
    <li>إنشاء جمل إستعلام عن البياتات بإستخدام ال active record class</li>
    <li>عرض البيانات داخل ال view من خلال ال paginated fashion.</li>
</ul>

<p dir="rtl">
    ملاحظة: من أجل الانتهاء من هذا الجزء التعليمي، يجب أن يكون لديك المعرفة الأساسية والخبرة باستخدام قواعد البيانات. وعلى وجه الخصوص، يجب أن تعرف كيفية إنشاء قواعد البيانات، وكيفية تنفيذ ال statements SQL باستخدام أي DB client tool.
</p>

## <div dir="rtl">إعداد قاعدة البيانات</div> <span id="preparing-database"></span>

<p dir="rtl">
    في البداية، عليك إنشاء قاعدة بيانات تسمى ب <code>yii2basic</code>، والتي ستستخدم لجلب البيانات الخاصة بالتطبيق، ويمكنك إستخدام أي من ال SQLite, MySql, PostgreSQL, MSSQL or Oracle database, ال Yii بشكل افتراضي بدعم العديد من قواعد البيانات والتي يمكنك إستخدامها مباشرة في التطبيق الخاص بك، ولتبسيط الأمور، ال MySql هي التي سيتم إستخدامها في في هذا الشرح. 
</p>

<blockquote class="info"><p dir="rtl">
    معلومة: إذا كنت ترغب بالحصول على خيارات متقدمة  مثل دعم ال <code>JSON</code> الموجود داخل MariaDB، فيمكنك من إستخدام أحد ال Extension المذكوره بالأسفل للقيام بهذه المهمة بدلا من الإستغناء عن ال MySql، فإستخدام MariaDB بدلا عن ال MySql لم يعد صحيحا تماما. 
</p></blockquote>

<p dir="rtl">
    بعد قيامك بإنشاء قاعدة البيانات، سنقوم بإنشاء جدول إسمه <code>country</code>، ومن ثم سنقوم بإدخال بعض البيانات كعينة للإختيار، وللقيام بذلك، قم بتنفيذ الأوامر التالية: 
</p>

```sql
CREATE TABLE `country` (
  `code` CHAR(2) NOT NULL PRIMARY KEY,
  `name` CHAR(52) NOT NULL,
  `population` INT(11) NOT NULL DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `country` VALUES ('AU','Australia',24016400);
INSERT INTO `country` VALUES ('BR','Brazil',205722000);
INSERT INTO `country` VALUES ('CA','Canada',35985751);
INSERT INTO `country` VALUES ('CN','China',1375210000);
INSERT INTO `country` VALUES ('DE','Germany',81459000);
INSERT INTO `country` VALUES ('FR','France',64513242);
INSERT INTO `country` VALUES ('GB','United Kingdom',65097000);
INSERT INTO `country` VALUES ('IN','India',1285400000);
INSERT INTO `country` VALUES ('RU','Russia',146519759);
INSERT INTO `country` VALUES ('US','United States',322976000);
```

<p dir="rtl">
    الآن، أصبح لديك قاعدة بيانات إسمها <code>yii2basic</code>، وتحوي بداخلها جدول بثلاث أعمدة يسمى ب <code>country</code>، وفيه 10 صفوف من البيانات.     
</p>

## <div dir="rtl">إعدادات الإتصال الخاصة بقواعد البيانات - Configuring a DB Connection</div> <span id="configuring-db-connection"></span>

<p dir="rtl">
    قبل أن تكمل الشرح، تأكد من تثبيت ال PHP <a href="https://www.php.net/manual/en/book.pdo.php">PDO</a> وال PDO driver، بالنسبة لهذا المثال، فإننا سنستخدم ال driver الخاص بال MySql وهو ال <code>pdo_mysql</code>، وهذه هي المتطلبات الأساسية لبناء أي التطبيق اذا كان التطبيق يستخدم ال relational database. 
</p>

<blockquote class="note"><p dir="rtl">
   ملاحظة: يمكنك تقعيل ال PDO مباشرة من خلال الدخول الى php.ini ومن ثم حذف الفاصلة المنقوطة قبل السطر التالي: <code>extension=php_pdo.dll</code>
    كما يمكنك تفعيل ال driver المطلوب عن طريق حذف الفاصلة المنقوطة قبل ال driver المقصود مثل: 
<code>extension=php_pdo_mysql.dll</code>
    ويمكنك الإطلاع على المزيد من هنا: 
<a href="https://www.php.net/manual/en/pdo.installation.php">pdo installation</a>    
</p></blockquote>

<p dir="rtl">
    بعد إتمام ما سبق، قم بفتح الملف <code>config/db.php</code> ومن ثم قم بتعديل ال parameters لتكون الإعدادات الخاصة بقاعدة البيانات صحيحة -الإعدادت الخاصة بك-، بشكل افتراضي، يحتوي الملف على ما يلي: 
</p>
    

```php
<?php

return [
    'class' => 'yii\db\Connection',
    'dsn' => 'mysql:host=localhost;dbname=yii2basic',
    'username' => 'root',
    'password' => '',
    'charset' => 'utf8',
];
```

<p dir="rtl">
    يمثل ملف ال <code>config/db.php</code> أداة نموذجية تعتمد على الملفات للقيام بال <a href="../guide/concept-configurations.md">configuration</a>. يقوم ملف ال configuration بتحديد ال parameters المطلوبة لإنشاء وإعداد ال instance الخاص بال <code>[[yii\db\Connection]]</code>، ومن خلالها يمكنك إجراء عمليات الإستعلام على قاعدة البيانات.
</p>

<p dir="rtl">
 الإعدادات الخاصة بالإتصال بقاعدة البيانات والمذكورة في الملف أعلاه يمكن الوصول اليها من خلال التطبيق عن طريق تنفيذ الأمر التالي
    <code>Yii::$app->db</code>
</p>

<blockquote class="info"><p dir="rtl">
    معلومة: سيتم تضمين ملف ال <code>config/db.php</code> من خلال  ال main application configuration والذي يتمثل بالملف <code>config/web.php</code>، والذي يقوم بدوره بتحديد كيف يمكن تهيئة ال instance الخاص <a href="../guide/concept-configurations.md">بالتطبيق</a>، لمزيد من المعلومات، يرجى الإطلاع على قسم ال <a href="../guide/concept-configurations.md">Configurations</a>.
</p></blockquote>

<p dir="rtl">
    إذا كنت بحاجة إلى العمل مع إحدى قواعد البيانات الغير مدعومة بشكل إفتراضي من ال Yii، فيمكنك التحقق من الإضافات التالية:
</p>

<ul dir="rtl">
    <li><a href="https://github.com/edgardmessias/yii2-informix">Informix</a></li>
<li> <a href="https://github.com/edgardmessias/yii2-ibm-db2">IBM DB2</a></li>
<li> <a href="https://github.com/edgardmessias/yii2-firebird">Firebird</a></li>
<li> <a href="https://github.com/sam-it/yii2-mariadb">MariaDB</a></li>
</ul>

## <div dir="rtl">إنشاء ال Active Record</div> <span id="creating-active-record"></span>

<p dir="rtl">
    لجلب البيانات وعرضها من جدول ال <code>country</code>، سنقوم بإضافة ال <a href="../guide/db-active-record.md">Active Record</a> الى ال class المسمى ب <code>country</code>، والموجود في المسار <code>models/Country.php</code>.
</p>

```php
<?php

namespace app\models;

use yii\db\ActiveRecord;

class Country extends ActiveRecord
{
}
```
<p dir="rtl">
    يرث ال <code>Country</code> Class ال [[yii\db\ActiveRecord]]، ولذلك، أنت لست بحاجة لكتابة أي شيفرة برمجية بداخله، فقط الشيفرة التي تشاهدها بالأعلى. سيقوم ال Yii بشكل تلقائي بالحصول على إسم الجدول في قاعدة البيانات من خلال إسم ال Class. 
</p>

<blockquote class="info"><p dir="rtl">
معلومة: إذا لم يكن من الممكن إجراء مطابقة مباشرة بين اسم ال class واسم الجدول، فيمكنك تجاوز هذه المشكلة من خلال إستخدام الدالة  [[yii\db\ActiveRecord::tableName()]] ، والتي ستقوم بعمل override على اسم الجدول. 
</p></blockquote>

<p dir="rtl">
    من خلال إستخدام ال <code>Country</code> class، يمكنك التحكم بكل سهولة بالبيانات الموجودة داخل جدول ال <code>country</code>، شاهد هذه الشيفرة البرمجية لتبسيط الفكرة:  
</p>

```php
use app\models\Country;

// get all rows from the country table and order them by "name"
$countries = Country::find()->orderBy('name')->all();

// get the row whose primary key is "US"
$country = Country::findOne('US');

// displays "United States"
echo $country->name;

// modifies the country name to be "U.S.A." and save it to database
$country->name = 'U.S.A.';
$country->save();
```

<blockquote class="info"><p dir="rtl">
    معلومة: يعتبر ال Active Record وسيلة قوية للوصول إلى بيانات قاعدة البيانات والتعامل معها بطريقة ال object oriented.
    ستجد معلومات أكثر تفصيلاً في الجزء الخاص بال <a href="../guide/db-active-record.md">Active Record</a>. بالإضافة الى ذلك، يمكنك التفاعل مباشرة مع قاعدة البيانات باستخدام lower-level data accessing والتي تسمى ب <a href="../guide/db-dao.md">Database Access Objects</a>.
</p></blockquote>

## <div dir="rtl">إنشاء ال Action</div> <span id="creating-action"></span>

<p dir="rtl">
لعرض بيانات ال country للمستخدمين، يلزمك إنشاء action جديد، وبدلاً من وضع ال action الجديد في ال <code>site</code> controller كما فعلنا في المرات السابقة، سنقوم بإنشاء controller جديد، ومن ثم سنقوم بوضع ال action بداخله، والسبب المنطقي لهذا العمل أنك ستقوم بتجميع الشيفرة البرمجية المسؤولة عن أداء وظائف معينة في مكان واحد، وبهذا فإن جميع الإجرائات التي تخص ال country من المنطقي أن تكون موجودة داخل ال <code>CountryController</code>، والآن لنقم بإنشاء هذا ال controller الجديد، وال action الجديد وسيكون باسم <code>index</code>، كما هو موضح أدناه: 
</p>

```php
<?php

namespace app\controllers;

use yii\web\Controller;
use yii\data\Pagination;
use app\models\Country;

class CountryController extends Controller
{
    public function actionIndex()
    {
        $query = Country::find();

        $pagination = new Pagination([
            'defaultPageSize' => 5,
            'totalCount' => $query->count(),
        ]);

        $countries = $query->orderBy('name')
            ->offset($pagination->offset)
            ->limit($pagination->limit)
            ->all();

        return $this->render('index', [
            'countries' => $countries,
            'pagination' => $pagination,
        ]);
    }
}
```
<p dir="rtl">
    قم بحفظ الشيفرة البرمجية التي بالأعلى داخل هذا الملف <code>controllers/CountryController.php</code>
</p>

<p dir="rtl">
    يقوم ال <code>index</code> action باستخدام ال <code>Country::find()</code>، وهذه الدالة موجودة من ضمن ال <code>active record</code>، وتقوم هذه الدالة على بناء الإستعلام الخاص بقاعدة البيانات مما يسمح باسترجاع جميع البيانات الموجودة بداخل جدول ال country، ولتحديد الحد الأعلى المسموح إرجاعه في كل request، يمكنك إستخدام ال <code>[[yii\data\Pagination]]</code> object كوسيلة مساعدة، ويقدم هذا ال object غرضين أساسيين وهما: 
</p>

<ul dir="rtl">
    <li>كتابة جملة استعلام محددة بعدد صفوف معين، وتبدأ من مكان معين، ويتم ذلك من خلال ال <code>offset</code> وال <code>limit</code>، وبهذا التعيين فأنت ستقوم بإرجاع صفحة واحدة من البيانات وفي كل مرة سيتم عرض 5 صفوف على الأكثر. </li>
    <li>كما يستخدم في صفحة ال view لعرض ال pager مع قائمة بال page buttons، وذلك كما ستشاهد في الجزء التالي من هذا الموضوع. </li>
</ul>

<p dir="rtl">
    في نهاية الشيفرة البرمجية الموجودة في ال <code>index</code> action، نقوم باستدعاء صفحة ال view المسمية ب <code>index</code>، ومن ثم نقوم بإرسال معلومات ال country المنظمة على شكل صفحات (pagination) ومن ثم عرضها. 
</p>


## <div dir="rtl"> إنشاء View </div> <span id="creating-view"></span>

<p dir="rtl">
    الآن، سنقوم بإنشاء صفحة ال view والتي ستقوم بعرض المعلومات الخاصة بال country والقادمة من ال index action، ولذلك توجه الى المسار <code>views</code>, ومن ثم قم بإنشاء مجلد جديد بداخله باسم <code>country</code>، هذا المجلد سيحوي جمع ال views التي سيتم إستدعائها من ال <code>country</code> controller>. الآن، قم بإنشاء الصفحة index.php بداخل المسار <code>views/country</code>، ومن ثم قم بكتابة هذه الشيفرة البرمجية بداخلها: 
</p>

```php
<?php
use yii\helpers\Html;
use yii\widgets\LinkPager;
?>
<h1>Countries</h1>
<ul>
<?php foreach ($countries as $country): ?>
    <li>
        <?= Html::encode("{$country->code} ({$country->name})") ?>:
        <?= $country->population ?>
    </li>
<?php endforeach; ?>
</ul>

<?= LinkPager::widget(['pagination' => $pagination]) ?>
```

<p dir="rtl">
    في هذه الصفحة، هناك جزئيين رئيسيين، الجزء الأول هو المسؤول عن طباعة المعلومات الخاصة بال country داخل قائمة من نوع ul، والجزء الثاني عبارة عن widget يستخدم المعلومات الخاصة بال pagination والتي تم إرسالها من ال action، ليقوم بعد ذلك بعرض قائمة من ال page buttons، والتي بدورها ستقوم بعمل تحديث للمعلومات الموجودة بالصفحة بنائا على الصفحة المطلوبة، هذا ال widget يسمى ب <code>LinkPager -[[yii\widgets\LinkPager]]-</code>.
</p>

## <div dir="rtl">لنجرب المثال</div> <span id="trying-it-out"></span>

<p dir="rtl">
    لتشاهد آلية العمل لهذا المثال، والنتائج المتعلقة به، يمكنك إستخدام المتصفح والدخول الى الرابط التالي:
</p>

```
https://hostname/index.php?r=country%2Findex
```



<p dir="rtl">
في البداية، ستشاهد البيانات الخاصة بخمسة دول، وأسفل هذه الدول، ستشاهد pager فيه 4 أزرار، اذا قمت بالضغط على الزر رقم 2، فإنك ستشاهد المعلومات الخاصة بخمسة دول أخرى، والتي تمثل صفوف أخرى من البيانات تم جلبها من قاعدة البيانات. 
<br />
تابع بعناية أكبر وستجد أن عنوان ال URL في المتصفح قد تغير أيضًا:
</p>

```
https://hostname/index.php?r=country%2Findex&page=2
```

<p dir="rtl">
    بالخفاء، يقوم ال <code>[[yii\data\Pagination|Pagination]]</code> بتقديم الدعم اللازم لكل الوظائف المطلوب تنفيذها لعمل الترقيم الخاص بال pagination: 
</p>

<ul dir="rtl">
    <li>في البداية، يمثل ال  [[yii\data\Pagination|Pagination]] الصفحة الأولى التي تعكس جملة الإستعلام SELECT مع الجدول country مع العبارة <code>LIMIT 5 OFFSET 0</code>. ونتيجة لذلك، سيتم جلب البلدان الخمسة الأولى وعرضها.</li>
    <li>ال [[yii\widgets\LinkPager|LinkPager]] widget يقوم على إستدعاء الأزرار الخاصة بأرقام الصفحات والتي يتم إنشاء ال Url الخاص بها من خلال ال [[yii\data\Pagination::createUrl()|Pagination]]، هذه ال Url تحتوي على parameter يسمى ب <code>page</code>، والذي يمثل بدورة مجموعة من الأرقام المختلفة والتي تمثل صفحات تعرض بيانات مختلفة كما هو في مثالنا عندما قمنا بالضغط على رقم 2.</li>
    <li>عند قيامك بالنقر على الزر رقم 2، سينطلق request جديد الى ال <code>country/index</code> route، وحينها يقوم ال [[yii\data\Pagination|Pagination]] على قرائة ال <code>page</code> parameter من ال URL ,من ثم يقوم بتغيير رقم الصفحة الحالية الى الرقم الجديد، وهنا الرقم الجديد هو 2 بدلا من 1. كما أن جملة الإستعلام الجديدة ستحوي الشرط التالي <code>LIMIT 5 OFFSET 5</code> لتقم بذلك بجلب الصفوف الخمسة الأخرى من البلدان لعرضها.</li>
</ul>

## <div dir="rtl">الخلاصة</div> <span id="summary"></span>

<p dir="rtl">
    في هذا الجزء من التوثيق، لقد تعلمنا كيف يمكننا التعامل مع قواعد البيانات، وكيف يمكننا جلب البيانات وعرضها وتجزئتها  لصفحات من خلال إستخدام ال [[yii\data\Pagination]] وال [[yii\widgets\LinkPager]].
</p>

<p dir="rtl">
  في الجزء القادم من هذا التوثيق، ستتعلم كيف يمكنك إستخدام إخدى الوسائل المميزة والموجودة في ال Yii لإنشاء الشيفرة البرمجية الخاصة بك، والتي يطلق عليها اسم <a href="https://www.yiiframework.com/extension/yiisoft/yii2-gii/doc/guide">Gii</a>، هذه الأداة ستساعدك على إنشاء وتنفيذ الشيفرات البرمجية التي يكثر كتابتها وإستخدامها بشكل دوري، مثل مجموعة العمليات Create-Read-Update-Delete، والتي يتم اختصارها ب CRUD، هذه الأداة ستقوم بالتعامل مع البيانات الموجدة بقاعدة البيانات، وفي الحقيقة، الشيفرة البرمجية الذي قمت بكتابته بالأعلى، يمكنك إنشائه بسهولة من خلال ال Gii بنقرة زر، لذلك فلننطلق الى الجزء التالي بأسرع وقت.  
</p>

---

### Guide Ar Start Forms (`docs/guide-ar/start-forms.md`)

# <div dir="rtl">العمل مع ال Forms</div>

<p dir="rtl">
في هذا الموضوع سنتعلم كيفية إنشاء صفحة تحتوي على form للحصول على البيانات من خلال المستخدمين، وستعرض هذه الصفحة form يحتوي على حقل لإدخال الإسم وحقل إدخال للبريد الإلكتروني.
وبعد الحصول على المعلومات الخاصة بهذه الحقول من المستخدم، ستقوم الصفحة بطباعة القيم التي تم إدخالها. 
</p>

<p dir="rtl">
    في هذا الشرح، ستقوم بإضافة <a href="../guide/structure-controllers.md">action</a> وصحفتين <a href="../guide/structure-views.md">views</a>، وستتعرف أيضا على طريقة إنشاء ال <a href="../guide/structure-models.md">model</a>.
</p>

<p dir="rtl">
من خلال هذا البرنامج التعليمي ، ستتعلم كيفية:
</p>

<ul dir="rtl">
    <li>إنشاء model لتمثيل البيانات التي تم إدخالها من خلال المستخدم عن طريق ال form.</li>
    <li>إنشاء rules للتحقق من صحة البيانات التي تم إدخالها.</li>
    <li>بناء html form داخل صفحة ال view.</li>
</ul>

## <div dir="rtl">إنشاء ال Model</div> <span id="creating-model"></span>

<p dir="rtl">
    يتم تمثيل البيانات التي يتم طلبها من خلال المستخدم عن طريق ال <code>EntryForm</code> model class  كما هو موضح أدناه، ويتم حفظ هذا الملف داخل المسار models، ويكون إسم ال model ومساره في مثالنا هذا هو  <code>models/EntryForm.php</code>. يرجى الرجوع إلى صفحة ال <a href="../guide/concept-autoloading.md">Class Autoloading</a> للحصول على مزيد من التفاصيل حول طريقة التعامل مع التسمية الخاصة بال class في Yii. 
</p>

```php
<?php

namespace app\models;

use Yii;
use yii\base\Model;

class EntryForm extends Model
{
    public $name;
    public $email;

    public function rules()
    {
        return [
            [['name', 'email'], 'required'],
            ['email', 'email'],
        ];
    }
}
```

<p dir="rtl">
    هذا ال class يرث ال [[yii\base\Model]], وهو base class تم تصميمه من خلال ال Yii, وبشكل عام وظيفته هي تثمثيل البيانات الخاصة بأي نموذج.
</p>

<blockquote class="info"><p dir="rtl">
معلومة: يتم إستخدام ال  [[yii\base\Model]] كأصل لل model class <b>ولا</b> يرتبط بجداول قواعد البيانات. ويستخدم ال  [[yii\db\ActiveRecord]]  بالشكل الإعتيادي ليكون هو الأصل الذي من خلاله يتم الإرتباط بجداول بقواعد البيانات. 
</p></blockquote>

<p dir="rtl">
    يحتوي class ال <code>EntryForm</code> على متغيرين إثنين من نوع Public، هما <code>name</code> و <code>email</code>، واللذان يستخدمان في تخزين البيانات التي أدخلها المستخدم. كما يحتوي أيضًا على method باسم <code>rules()</code>، والتي تُرجع مجموعة
الشروط الخاصة بالبيانات للتحقق من صحتها. والشيفرة البرمجية الموجودة داخل ال rules method تعني: 
</p>

<ul dir="rtl">
    <li>كل من ال <code>name</code> وال <code>email</code> حقول الزامية (required).</li>
    <li>ال <code>email</code> حقل يجب أن يحتوي بداخله قيمة صحيحة تعبر عن البريد الإلكتروني (القواعد النحوية لكتابة البريد الإلكتروني).</li>
</ul>

<p dir="rtl">
    إذا كان لديك object من ال  <code>EntryForm</code> ويحتوي على البيانات التي أدخلها المستخدم،  فيمكنك حينها إستدعاء الدالة  [[yii\base\Model::validate()|validate()]] للتحقق من صحة البيانات. اذا فشلت عملية التحقق من صحة البيانات، فسيؤدي ذلك إلى تغيير قيمة ال  [[yii\base\Model::hasErrors|hasErrors]] إلى <code>true</code> ، بالإضافة الى ذلك يمكنك التعرف الى الأخطاء المتعلقة بهذه البيانات من خلال الدالة [[yii\base\Model::getErrors|errors]].
</p>

```php
<?php
$model = new EntryForm();
$model->name = 'Qiang';
$model->email = 'bad';
if ($model->validate()) {
    // Good!
} else {
    // Failure!
    // Use $model->getErrors()
}
```


## <div dir="rtl">إنشاء Action</div> <span id="creating-action"></span>

<p dir="rtl">
    الآن، ستحتاج إلى إنشاء <code>action</code> جديد في ال <code>site</code> controller وليكن إسمه <code>entry</code>، والذي سيقوم بدوره باستخدام ال model الجديد الذي قمنا بإنشائه. هذه العملية تم شرحها سابقا في الجزء التالي من التوثيق <a href="start-hello.md">Saying Hello - قل مرحبا</a>.
</p>

```php
<?php

namespace app\controllers;

use Yii;
use yii\web\Controller;
use app\models\EntryForm;

class SiteController extends Controller
{
    // ...existing code...

    public function actionEntry()
    {
        $model = new EntryForm();

        if ($model->load(Yii::$app->request->post()) && $model->validate()) {
            // valid data received in $model

            // do something meaningful here about $model ...

            return $this->render('entry-confirm', ['model' => $model]);
        } else {
            // either the page is initially displayed or there is some validation error
            return $this->render('entry', ['model' => $model]);
        }
    }
}
```
<p dir="rtl">
    أولا، يقوم ال action بإنشاء object من ال  <code>EntryForm</code>. ثم يحاول تعبئة البيانات لل object من خلال ال <code>$ _POST</code>، والتي يتم تقديمها في ال Yii من خلال ال [[yii\web\Request::post()]].
إذا تم ملء ال object بنجاح (على سبيل المثال، إذا قام المستخدم بإدخال البيانات داخل ال form ومن ثم قام بإرسالها(submitted html form))، فسيتم استدعاء ال [[yii\base\Model::validate()|validate()]] من خلال ال action للتأكد من صلاحية القيم المدخلة.
</p>


<blockquote class="info"><p dir="rtl">
    معلومة: يمثل التعبير Yii::$app ال  <a href="../guide/structure-applications.md">Application</a> instance الذي يمكن الوصول اليه من خلال ال singleton <br />(singleton globally accessible). وهو أيضا  <a href="../guide/concept-service-locator.md">service locator</a>  بحيث يوفر الدعم لل components مثل ال request, response, db..الخ، لدعم وظائف محددة. مثلا في المثال الموجود في الأعلى، فإن ال request هو component من ال application instance والذي يستخدم للوصول الى البيانات الموجودة داخل ال $_POST. 
</p></blockquote>

<p dir="rtl">
    إذا كان كل شيء على ما يرام، فسوف يقوم ال action بجلب ال view التالية: <code>entry-confirm</code>، وذلك لتأكيد أن العملية قد تمت بنجاح بالنسبة للمستخدم، أما إن كانت البيانات غير صحيحة، أو لم يتم إرسال أي بيانات، فإن ال view <code>entry</code> هي التي سيتم جلبها وعرضها للمستخدم، حيث يتم عرض ال Html form، مع أي رسائل تحذير بخصوص الأخطاء التي تم العثور عليها من عملية التحقق.
</p>

<blockquote class="note"><p dir="rtl">
ملاحظة: في هذا المثال البسيط، نعرض صفحة التأكيد فقط عند إرسال البيانات بشكل صحيح. عند الممارسة العملية، يجب عليك استخدام [[yii\web\Controller::refresh()|refresh()]] أو [[yii\web\Controller::redirect()|redirect()]] لتجنب أي مشكلة تحصل عن طريق ال resubmission والتي تندرج تحت العنوان <a href="https://en.wikipedia.org/wiki/Post/Redirect/Get">form resubmission problems</a>.
</p></blockquote>

## <div dir="rtl">إنشاء ال views</div> <span id="creating-views"></span>

<p dir="rtl">
    أخيرا، سنقوم بإنشاء صفحتين لل views الأولى بإسم <code>entry-confirm</code> والثانية <code>entry</code>. وهاتين الصفحتين سيتم جلبهم من خلال ال <code>entry</code> action. 
</p>

<p dir="rtl">
    ال <code>entry-confirm</code> ستقوم بكل بساطة بعرض الإسم والبريد الإلكتروني الذي تم إدخالهم من قبل المستخدم. ويجب حفظ هذه الصفحة بالمسار التالي: <code>views/site/entry-confirm.php</code> 
</p>

```php
<?php
use yii\helpers\Html;
?>
<p>You have entered the following information:</p>

<ul>
    <li><label>Name</label>: <?= Html::encode($model->name) ?></li>
    <li><label>Email</label>: <?= Html::encode($model->email) ?></li>
</ul>
```
<p dir="rtl">
   صفحة ال <code>entry</code> ستقوم بعرض ال HTML form. هذه الصفحة يجب أن يتم حفظها داخل المسار التالي: <code>views/site/entry.php</code>
</p>

```php
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
?>
<?php $form = ActiveForm::begin(); ?>

    <?= $form->field($model, 'name') ?>

    <?= $form->field($model, 'email') ?>

    <div class="form-group">
        <?= Html::submitButton('Submit', ['class' => 'btn btn-primary']) ?>
    </div>

<?php ActiveForm::end(); ?>
```
<p dir="rtl">
    تستخدم ال view أسلوب مميز لبناء ال Forms، وذلك عن طريق ال <a href="../guide/structure-widgets.md">widget</a> الذي يسمى ب  [[yii\widgets\ActiveForm|ActiveForm]]. إن الأسلوب المستخدم في هذا ال widget يقوم على إستخدام كل من الدالة <code>begin()</code> و <code>end()</code>  لجلب ال opening  وال closing form tags على التوالي (فتحة ال tag، ثم الإغلاق الخاص بهذا ال tag)، وبين الفتحة والإغلاق يمكنك إنشاء الحقول عن طريق إستخدام الدالة [[yii\widgets\ActiveForm::field()|field()]]. في هذا المثال كان الحقل الأول في ال form يشير الى name data، والثاني يشير الى ال email data، وبعد هذه الحقول ستجد الدالة المستخدمة لإنشاء ال Submit button وهي [[yii\helpers\Html::submitButton()]].
</p>

## <div dir="rtl">لنجرب المثال</div> <span id="trying-it-out"></span>

<p dir="rtl">
 لتشاهد آلية العمل لهذا المثال، والنتائج المتعلقة به، يمكنك إستخدام المتصفح والدخول الى الرابط التالي:
</p>

```
https://hostname/index.php?r=site%2Fentry
```

<p dir="rtl">
عند دخولك الى الرابط السابق، سترى صفحة تعرض Html form يحتوي على حقلين لإدخال المعلومات. أمام كل حقل إدخال ستجد label يشير إلى البيانات المطلوب إدخالها. إذا قمت بالنقر فوق الزر "submit" بدون
أي إدخال، أو إذا لم تقم بكتابة عنوان البريد الإلكتروني بشكل صحيح، فستظهر لك رسالة خطأ بجوار الحقل المقصود.
</p>



<p dir="rtl">
    بعد إدخالك لإسم وبريد الكتروني صحيح، وقيامك بالنقر على زر submit، فإنك ستشاهد صفحة جديدة تقوم بعرض البيانات التي قمت بإدخالها.
</p>



## <div dir="rtl">كيف ظهر الخطأ؟ هل هو سحر؟!</div> <span id="magic-explained"></span>

<p dir="rtl">
قد تتساءل كيف يعمل ال Html form بالخفاء، وقد يبدو ذلك سحرا للوهلة الأولى، فهو يعرض ال label لكل حقل إدخال، ويعرض رسائل الخطأ إذا لم تقم بإدخال البيانات بشكل صحيح، وكل ذلك دون الحاجة لإعادة تحميل الصفحة.
</p>

<p dir="rtl">
    إن السحر الموجود لدينا هنا، هو كيفية العمل الخاصة بالشيفرة البرمجية لل form،  والتي تعمل بالخفاء، إن إجراء التحقق عن صحة البيانات يتم في البداية من جانب العميل -client side- وذلك باستخدام الجافا سكربت، ومن ثم -بعد تجاوز التحقق الخاص بالجافا سكربت- بتم تنفيذ التحقق من جانب ال server-side عبر ال PHP. ال  [[yii\widgets\ActiveForm]] ذكية بما فيه الكفاية لاستخراج ال rule الخاصة بالتحقق والتي قمت بإنشائها وتعريفها داخل ال <code>EntryForm</code>، ومن ثم تحويل هذه القواعد إلى شيفرة برمجية بالجافا سكربت قابلة للتنفيذ، ومن ثم استخدام هذه الشيفرة من قبل الجافا سكربت لإجراء التحقق من صحة البيانات. في حال قمت بإيقاف الجافا سكربت في المتصفح الخاص بك، سوف يستمر إجراء التحقق من جانب الخادم -server side-، كما هو موضح في ال action المسمى <code>actionEntry()</code>. وهذا يضمن صحة البيانات في جميع الظروف.
</p>

<blockquote class="warning"><p dir="rtl">
    تحذير: التحقق من جانب العميل -client side-  يوفر تجربة أفضل للمستخدم، لكن يجب الأخذ بعين الإعتبار أن التحقق من جانب الخادم -server- مطلوب دائمًا، سواء تم التحقق من جانب العميل أم لا.
</p></blockquote>

<p dir="rtl">
    يتم إنشاء ال labels الخاصة بحقول الإدخال بواسطة الدالة <code>field()</code>، وذلك من خلال إستخدام أسماء ال property الموجودة داخل ال model. على سبيل المثال، سيتم إنشاء ال label التالي <code>Name</code> للproperty التالية: <code>name</code>.
</p>

<p dir="rtl">
    كما يمكنك تعديل ال label الإفتراضي لأي حقل من خلال الشيفرة البرمجية التالية:
</p>

```php
<?= $form->field($model, 'name')->label('Your Name') ?>
<?= $form->field($model, 'email')->label('Your Email') ?>
```

<blockquote class="info"><p dir="rtl">
    معلومة: يوفر ال Yii العديد من ال widgets لمساعدتك في إنشاء views معقدة وديناميكية بسرعة. كما أنك ستتعلم في وقت لاحق كيف يمكنك إنشاء widget جديد، وستكتشف أن الموضوع سهل وبسيط، مما سيدفعك إلى كتابة الشيفرة البرمجية الخاصة بك داخل ال widget، والذي بدوره سيجعل من هذه الشيفرة قابلة للتطوير والإستخدام في أكثر من مكان في المستقبل. 
</p></blockquote>

## <div dir="rtl">الخلاصة</div> <span id="summary"></span>

<p dir="rtl">
    في هذا الجزء من التوثيق، تحدثنا عن كل جزء في ال MVC architectural pattern، لقد تعلمت الآن كيف يمكنك إنشاء model class ليقوم بتمثيل البيانات الخاصة بالمستخدمين، ومن ثم التحقق منها.   
</p>

<p dir="rtl">
    لقد تعلمت أيضًا كيفية الحصول على البيانات من المستخدمين، وكيفية عرض البيانات مرة أخرى في المتصفح. هذه المهمة يمكن أن تأخذ الكثير من الوقت عند تطوير أي تطبيق، ولكن، يوفر ال Yii العديد من ال widgets القوية، والتي تجعل من هذه المهمة أمرا سهلا للغاية.
</p>

<p dir="rtl">
    في الجزء القادم من هذا التوثيق، ستتعلم كيف يمكنك التعامل مع قواعد البيانات، والتي سنحتاجها -غالبا- مع كل تطبيق ستعمل عليه تقريبا. 
</p>

---

### Guide Ar Start Gii (`docs/guide-ar/start-gii.md`)

# <div dir="rtl">إنشاء الشيفرة البرمجية من خلال ال gii</div>

<p dir="rtl">
    في هذا الجزء التعليمي سنتعرف على آلية التعامل مع ال <a href="https://www.yiiframework.com/extension/yiisoft/yii2-gii/doc/guide">Gii</a>، والذي يستخدم لإنتاج الشيفرة البرمجية الخاصة بمعظم الميزات والخصائص المشتركة في أغلب المواقع بشكل تلقائي، بالإضافة الى ذلك، فإن استخدام ال Gii لإنشاء الشيفرة البرمجية بشكل تلقائي يمثل مجموعة من المعلومات الصحيحة التي بتم إدخالها إعتمادا على التعليمات الموجودة في ال Gii Web Pages.
</p>

<p dir="rtl">
    من خلال هذا البرنامج التعليمي، ستتعلم كيفية:
</p>

<ul dir="rtl">
    <li>تفعيل ال Gii داخل التطبيق الخاص بك</li>
    <li>إستخدام ال Gii لإنشاء ال Active Record class</li>
    <li>إستخدام ال Gii لإنشاء الشيفرة البرمجية الخاصة بال CRUD إعتمادا على الجداول الموجودة في قاعدة البيانات</li>
    <li>تخصيص (customize) الشيفرة البرمجية التي سيتم إنتاجها من خلال ال Gii.</li>
</ul>

## <div dir="rtl">البدء باستخدام ال Gii</div> <span id="starting-gii"></span>

<p dir="rtl">
    يتم تقديم ال <a href="https://www.yiiframework.com/extension/yiisoft/yii2-gii/doc/guide">Gii</a> داخل على ال Yii على أنه <a href="../guide/structure-modules.md">module</a>، ويمكنك تفعيله من خلال الإعدادات الخاصة به والتي تجدها داخل ال application، وبالتحديد داخل ال property التالية [[yii\base\Application::modules|modules]]، واعتمادا على كيفية إنشائك للمشروع، فيمكنك إيجاد الشيفرة البرمجية التالية موجودة بشكل مسبق داخل ال <code>config/web.php</code>:  
</p>

```php
$config = [ ... ];

if (YII_ENV_DEV) {
    $config['bootstrap'][] = 'gii';
    $config['modules']['gii'] = [
        'class' => 'yii\gii\Module',
    ];
}
```

<p dir="rtl">
    في الإعدادت الموجودة في الأعلى، فإن التطبيق سيقوم بتضمين وتفعيل ال gii في حال كانت الحالة الخاصة بالتطبيق هي <a href="../guide/concept-configurations.md#environment-constants">development enviroment</a>، بالإضافة الى ذلك، فإنه يجب تضمين واستخدام ال module <code>gii</code>، والموجود ضمن ال class التالي [[yii\gii\Module]]. 
</p>


<p dir="rtl">
    اذا قمت بالتحقق من ال <a href="../guide/structure-entry-scripts.md">entry script</a> وبالتحديد صفحة ال <code>web/index.php</code> في التطبيق الخاص بك، ستجد هذه الأسطر، والتي يجب أن تجعل من ال <code>YII_ENV_DEV</code> ذات قيمة <code>true</code>.
</p>

```php
defined('YII_ENV') or define('YII_ENV', 'dev');
```

<p dir="rtl">
    كل الشكر لهذا السطر البرمجي، التطبيق الآن أصبح بحالة ال development mode، وأصبح لديك ال Gii enabled بالفعل، والآن، يمكنك الوصول الى ال Gii من خلال عنوان ال URL التالي:     
</p>

```
https://hostname/index.php?r=gii
```

<blockquote class="note"><p dir="rtl">
    ملاحظة: إذا كنت تحاول الوصول إلى Gii  من جهاز آخر غير ال localhost، فسيتم رفض الوصول افتراضيًا لأغراض أمنية، ولكن، يمكنك إعداد ال Gii لإضافة مجموعة من ال IP Addresses المسموح لها بالوصول وذلك من خلال: 
</p></blockquote>

```php
'gii' => [
    'class' => 'yii\gii\Module',
    'allowedIPs' => ['127.0.0.1', '::1', '192.168.0.*', '192.168.178.20'] // عدل هذه حسب إحتياجاتك
],
```




## <div dir="rtl">إنشاء ال Active Record Class من خلال ال Gii</div> <span id="generating-ar"></span>

<p dir="rtl">
    لإستخدام ال Gii لإنشاء ال Active Record class, قم باختيار ال "Model Generator" (من خلال النقر على الرابط الموجود بالصفحة الرئيسية لل Gii)، ومن ثم قم بتعبئة ال form كما يلي: 
</p>

<ul dir="rtl">
    <li>إسم الجدول: <code>country</code></li>
    <li><code>Country</code> :Model Class</li>
</ul>



<p dir="rtl">
    والآن، قم بالنقر على الزر "Preview"، ستشاهد الآن <code>models/Country.php</code> قد تم إنشائها وإضافتها الى قائمة النتائج، اذا قمت بالنقر على إسم ال class، فإن المحتوى الخاص بهذا ال class سيتم عرضه.
</p>

<p dir="rtl">
    عند استخدام ال Gii، إذا كنت قد قمت بالفعل بإنشاء نفس الملف وستقوم بعمل overwriting عليه، فيمكنك النقر على زر <code>diff</code> الموجود بعد إسم ال class، لتشاهد الفرق بين الشيفرة البرمجية الحالية، والشيفرة البرمجية الجديدة. 
</p>



<p dir="rtl">
    عند قيامك بعمل overwriting على ملف موجود، قم بالضغط على ال ckeckbox الموجودة بجانب كلمة overwrite، ومن ثم قم بالنقر على زر "Generate", اذا كان هذا الملف جديد، وغير موجود مسبقا، فيمكنك النقر مباشرة على "Generate"، بعد ذلك ستشاهد صفحة ال confirmation والتي تبين الشيفرات البرمجية التي تم إنشائها بنجاح.
</p>

<p dir="rtl">
    بعد فيامك بالنقر على زر Generate، فإنك ستشاهد صفحة ال confirmation page، والتي تقوم بدورها بتوضيح الشيفرات البرمجية التي تم إنشائها بنجاح، واذا كان الملف موجود، فإنك ستشاهد أيضا رسالة تعلمك بأن الملف قد تم تعديله وتمت إضافة الشيفرة الجديدة مكان القديمة.
</p>

## <div dir="rtl">إنشاء ال CRUD Code</div> <span id="generating-crud"></span>

<p dir="rtl">
    ال CRUD هي اختصار ل Create, Read, Update, And Delete (إنشاء، وقرائة، وتحديث، وحذف)، والتي تمثل أكثر المهمات المطلوبة للتعامل مع البيانات على مواقع الويب. ولإنشاء ال CRUD باستخدام ال Gii، قم باختيار ال "CRUD Generator" (من خلال النقر على الرابط الموجود بالصفحة الرئيسية لل Gii)، وهنا وبالبنسبة للمثال الخاص بال "country"، يمكنك تعبئة ال from بما يلي:
</p>

* Model Class: `app\models\Country`
* Search Model Class: `app\models\CountrySearch`
* Controller Class: `app\controllers\CountryController`



<p dir="rtl">
    بعد ذلك، قم بالنقر على زر ال "Preivew"، وستشاهد قائمة بالملفات التي سيتم إنشائها كما في الصورة أدناه.
</p>



<p dir="rtl">
    اذا قمت إنشاء الصفحتين <code>controllers/CountryController.php</code> و <code>views/country/index.php</code> عند حديثنا سابقا عند موضوع (التعامل مع قواعد البيانات)، فقم بالضغط على ال "overwrite" ليتم إستبدالهم. (الصفحات القديمة لا توجد فيها كل الخصائص التي سيتم إنتاجها من خلال ال Gii CRUD).
</p>

## <div dir="rtl"> لنجرب المثال </div> <span id="trying-it-out"></span>

<p dir="rtl">
لتشاهد آلية العمل لهذا المثال، والنتائج المتعلقة به، يمكنك إستخدام المتصفح والدخول الى الرابط التالي:
</p>

```
https://hostname/index.php?r=country%2Findex
```

<p dir="rtl">
    عند دخولك إلى الرابط أعلاه، ستشاهد مجموعة الدول التي تم إستدعائها من جدول ال country من قاعدة البيانات، ويمكنك التعامل مع هذا ال grid من حيث الترتيب أو التصفية بنائا على الشروط التي ستقوم بإدخالها في مربعات النص أعلى الأعمدة.
</p>

<p dir="rtl">
لكل دولة تم جلبها وعرضها داخل ال Grid، هناك مجموعة من الخيارات التي يمكنك التعامل معها بشكل إفتراضي، مثل ال view لعرض التفاصيل الخاصة بالدولة المختارة، أو تحديث المعلومات، الخاصة بالدولة، أو حذف هذه الدولة، بالإضافة إلى ذلك يمكنك النقر على "Create Country" الموجودة في أعلى ال Grid والتي ستأخذك بدورها الى صفحة تحتوي form لإنشاء ال country.
</p>





<p dir="rtl">
    فيما يلي قائمة بالملفات التي تم إنشاؤها من خلال ال Gii، في حالة رغبتك في التحقق من كيفية عمل هذه الميزات والإطلاع على الشيفرة البرمجية وتخصيصها حسب الرغبة:
</p>

* Controller: `controllers/CountryController.php`
* Models: `models/Country.php` and `models/CountrySearch.php`
* Views: `views/country/*.php`

<blockquote class="info"><p dir="rtl">
معلومة: تم تصميم ال Gii لتكون أداة إنشاء شيفرات برمجية قابلة للتخصيص بشكل كبير للغاية. اذا قمت باستخدامه بحكمة،فإنك ستقوم بتسريع وتيرة التطوير الخاصة بالتطبيق الخاص بك. لمزيد من التفاصيل، يرجى الذهاب إلى الجزء الخاص بال  <a href="https://www.yiiframework.com/extension/yiisoft/yii2-gii/doc/guide">Gii</a>. 
</p></blockquote>

## <div dir="rtl">الخلاصة</div> <span id="summary"></span>

<p dir="rtl">
في هذا الجزء من التوثيق، لقد تعلمنا آلية استخدام ال Gii لإنشاء الشيفرة البرمجية الخاصة بال CRUD، وتحدثنا عن الوظائف التي تقوم فيها، وكيف يمكننا من خلالها إتمام العمليات الخاصة بالبيانات من إدخال وتحديث وحذف وعرض للبيانات من قاعدة البيانات.
</p>

---

### Guide Ar Start Hello (`docs/guide-ar/start-hello.md`)

# <div dir="rtl">قل مرحبا - Saying Hello</div>

<p dir="rtl">
    في هذا الموضوع سنتعرف على كيفية إنشاء صفحة "Hello" جديدة في التطبيق الذي قمت بتثبيته، ولتحقيق ذلك، يجب عليك القيام بإنشاء <a href="../guide/structure-controllers.md#creating-actions">action</a> و <a href="../guide/structure-views.md">view</a> لهذه الصفحة:
</p>

<ul dir="rtl">
    <li>سيقوم التطبيق بإرسال ال request الخاص بالصفحة إلى ال action.</li>
    <li>وسيقوم ال action بدوره في جلب ال view التي تعرض كلمة "Hello" إلى المستخدم النهائي.</li>
</ul>

<p dir="rtl">
    من خلال هذا البرنامج التعليمي ، ستتعلم ثلاثة أشياء: 
</p>

<ol dir="rtl">
    <li>كيفية إنشاء <a href="../guide/structure-controllers.md#creating-actions">action</a> ليقوم بإستقبال ال request ومن ثم الرد (respond) عليها.</li>
    <li>كيفية إنشاء <a href="../guide/structure-views.md">view</a> وإضافة المحتوى الى ال respond.</li>
    <li>و كيفية إنشاء التطبيق لل requests التي يوجهها لل <a href="../guide/structure-controllers.md#creating-actions">actions</a>. </li>
</ol>

##  <div dir="rtl">إنشاء ال Action</div> <span id="creating-action"></span>

<p dir="rtl">
    لإنشاء صفحة "Hello"، ستقوم بإنشاء <code>say</code> <a href="../guide/structure-controllers.md#creating-actions">action</a> والذي بدوره سيقوم  بقراءة ال <code>message</code> parameter من ال request، ومن ثم عرض ال <code>message</code> مرة أخرى إلى المستخدم. إذا كان ال request لا يحمل معه ال message parameter فإن ال action سيقوم بطباعة message إفتراضية وهي "Hello".
</p>

<blockquote class="info"><p dir="rtl">
    معلومة: ال <a href="../guide/structure-controllers.md#creating-actions">Actions</a> هي الكائنات(objects) التي يمكن للمستخدمين من الوصول اليها وتنفيذ ما في بداخلها بشكل مباشر.  يتم تجميع هذه ال Actions بواسطة ال <a href="../guide/structure-controllers.md">controllers</a>. ونتيجة لذلك فإن ال response الراجعة للمستخدم ستكون هي نتيجة التنفيذ الخاصة بال action. 
</p></blockquote>

<p dir="rtl">
    يجب تعريف ال actions داخل ال <a href="../guide/structure-controllers.md">controller</a>، ولتبسيط الفكرة، سنقوم بتعريف ال <code>say</code> action داخل أحد ال controller الموجود مسبقا وهو ال <code>siteController</code>. هذا ال controller ستجده داخل المسار <code>controllers/siteController.php</code>. ومن هنا سنبدأ بإضافة ال action الجديد: 
</p>

```php
<?php

namespace app\controllers;

use yii\web\Controller;

class SiteController extends Controller
{
    // ...existing code...

    public function actionSay($message = 'Hello')
    {
        return $this->render('say', ['message' => $message]);
    }
}
```

<p dir="rtl">
    في الشيفرة البرمجية السابقة ، تم تعريف ال <code>say</code> action من خلال إنشاء الدالة <code>actionSay</code> داخل الكلاس  <code>siteController</code>. يستخدم ال Yii كلمة action ك prefix للدوال للتميز بين الدوال ال action و ال non-action في ال controller، كما يستخدم الإسم الخاص بال action مباشرة بعد ال prefix، ويتم عمل mapping بين ال action method name وال action id ليستطيع المستخدم من الوصول للدالة المنشئة من خلال ال action id. 
</p>

<p dir="rtl">
    عندما يتعلق الأمر بتسمية ال action الخاصة بك، يجب عليك  أن تفهم كيف يقوم ال Yii بالتعامل مع ال action id، ال action id يجب أن يكون دائما أحرف lower case، وإذا إحتوى ال action id على عدة كلمات فإن الفاصل بينهم سيكون الداش (dashes)  مثل  <code>create-comment</code>، ويتم ربط ال action id بال action method name من  خلال حذف ال dashes من ال IDs، ويتم عمل capitalizing لأول خرف من كل كلمة، وإضافة ال prefix الى الناتج السابق من التحويل. مثال: ال action id المسمى ب <code>create-comment</code> سيتم تحويله الى ال action method name التالي: <code>actionCreateComment</code>. 
</p>

<p dir="rtl">
    في المثال السابق، يقوم ال action method على إستقبال parameter يسمى ب <code>$message</code>، والذي يملك قيمة إفتراضية وهي <code>"Hello"</code> (وهي مشابة تماما لطريقة وضع القيم الإفتراضية لل argument في ال PHP). عندما يستقبل التطبيق ال request ويحدد أن ال action المطلوب للتعامل مع الطلب (request) هو <code>say</code>، فإن التطبيق سيقوم بإسناد القيمة الموجودة بال request الى ال parameter الموجود بال action بشرط أن يكون الإسم الموجود بال request هو نفسه الموجود في ال action. ولتبسيط الموضوع يمكن القول أن ال request اذا احتوى على كلمة <code>message</code> وقيمة هذا ال parameter هي <code>"GoodBye"</code>، فإن ال <code>$message</code> الموجودة في ال action ستصبح قيمتها <code>"GoodBye"</code>.  
</p>


<p dir="rtl">
    من خلال ال action method، يتم استدعاء ال  [[yii\web\Controller::render()|render()]] لتقديم
الملف الخاص بال view والمسمى هنا ب <code>say</code>. أيضا فإن ال <code>message</code> يتم تمرريرها الى ال view مما يسمح لك باستخدام هذا ال parameter داخل ال view. النتيجة المرجعة لل view تتم معالجتها وإرجاعها من خلال ال action method، وهذه النتائج سيتم إستقبالها من خلال المتصفح الخاص بالمستخدم ليتم عرضها وكأنها (جزء من صفحة Html كاملة). 
</p>

## <div dir="rtl">إنشاء ال View</div> <span id="creating-view"></span>

<p dir="rtl">
    ال <a href="../guide/structure-views.md">Views</a> هي شيفرات برمجية كتبت ﻹنشاء المحتوى المناسب بنائا على ال response الراجع اليها من خلال ال action. 
    بالنسبة إلى مثال "Hello" ، الآن سنقوم بإنشاء view مسمى ب <code>say</code>، والذي سيقوم بدوره بطباعة ال <code>message</code> التي تم إستلامها من ال action، شاهد المثال: 
</p>


```php
<?php
use yii\helpers\Html;
?>
<?= Html::encode($message) ?>
```

<p dir="rtl">
    صفحة ال view <code>say</code> يجب أن يتم حفظها داخل المسار التالي: <code>views/site/say.php</code>. عندما يتم إستدعاء الدالة [[yii\web\Controller::render()|render()]] من قبل ال action، فإنه سينظر للمسار على الشكل التالي: <code>views/ControllerID/ViewName.php</code>، بحيث يكون في مثالنا السابق ال ContollerID هو ال <code>site</code> وال viewName هو <code>say</code>.
</p>

<p dir="rtl">
    ملاحظة:  في الشيفرة البرمجية أعلاه، تكون ال <code>message</code> مضمنة داخل ال  [[yii\helpers\Html::encode()]] قبل أن يتم طباعتها، هذا الأمر ضروري لأن ال parameter التي تأتي من المستخدم النهائي لا يجب الوثوق بها،  فهي يمكن أن تحتوي على شيفرات برمجية تستغل الضعف الحاص بك بموضوع الأمان مثل <a href="https://en.wikipedia.org/wiki/Cross-site_scripting">vulnerable to XSS attack</a> عن طريق دمج JS code مع ال parameter. 
</p>

<p dir="rtl">
    وبطبيعة الحال، يمكنك وضع المزيد من المحتوى في صفحة ال <code>say</code> view. ويمكن أن يتكون هذا المحتوى من HTML tag و plain text وحتى PHP statements.
في الواقع، تعد ال <code>say</code> view مجرد شيفرة برمجية بلغة ال PHP والتي يتم تنفيذها بواسطة [[yii\web\Controller::render()|render()]].
المحتوى الذي سيتم طباعته من خلال ال view سيتم إرجاعه الى التطبيق من خلال ال response، وسيقوم التطبيق بدوره بإخراج هذه النتيجة إلى المستخدم النهائي.
</p>


## <div dir="rtl">تطبيق المثال</div> <span id="trying-it-out"></span>
-------------

<p dir="rtl">
بعد إنشاء ال action وصفحة ال view،  يمكنك الوصول إلى الصفحة الجديدة عن طريق  عنوان URL التالي:    
</p>

```
https://hostname/index.php?r=site%2Fsay&message=Hello+World
```



<p dir="rtl">
    سينتج عن هذا ال URL صفحة تعرض "Hello World". هذه الصفحة لديها نفس ال Header و ال Footer لصفحات التطبيق الأخرى.
</p>

<p dir="rtl">
    إذا قمت بحذف ال <code>message</code> parameter من ال URL ، فسترى الصفحة تعرض كلمة <code>" Hello "</code> فقط. ويرجع ذلك إلى أن "message" يتم تمريرها ك parameter إلى ال  <code>actionSay()</code>، وعندما يتم حذفها، سيتم استخدام القيمة الافتراضية وهي <code>"Hello"</code> بدلاً من ذلك.
</p>

<blockquote class="info"><p dir="rtl">
    معلومة: تتشارك الصفحة الجديدة مع الصفحات الأخرى بالتطبيق بنفس ال Header وال Footer وذلك بسبب الدالة  [[yii\web\Controller::render() | render ()]] والتي ستقوم بشكل تلقائي بتضمين النتيجة الخاصة بصفحة ال view <code>say</code> مع صفحة ال <a href="../guide/structure-views.md#layouts">Layout</a>، والتي يمكنك أن تجدها داخل المسار التالي: <code>views/layouts/main.php</code>
</p></blockquote>

<p dir="rtl">
    ال <code>r</code> الموجودة في ال URL أعلاه يتطلب الكثير من الشرح. ولكن باختصار يمكن القوم أنها اختصار ل <a href="../guide/runtime-routing.md">route</a> ، وهو معرف فريد من نوعه(unique ID) للتطبيق بحيث يقوم بالتأشير على ال action، والصيغة الخاصة بال route هي <code>ControllerID/ActionID</code>. عندما يتلقى التطبيق request، فإنه سيتم التحقق من <code>r</code> parameter، فيقوم باستخدام الجزء <code>ControllerID</code> لتحديد ال controller class المطلوب ليقوم بعمل instance منه، ومن ثم يقوم ال controller باستخدام ال <code>"ActionID"</code> لتحديد ال action المطلوب والذي سيقوم بالعمل الفعلي.
 في المثال الخاص بنا، فإن ال route هو  <code>"site/say"</code>، وهذا ال route يتم معالجته ليستدعي ال controller class المسمى ب <code>SiteController</code> و ال action المسمى ب <code>actionSay</code> داخل هذا ال controller، ونتيجة لذلك سيتم فعليا إستدعاء الدالة  <code>SiteController::actionSay()</code> لتقوم بمعالجة ال request كما يلزم. 
</p>

<blockquote><p dir="rtl">
    معلومة: مثل ال actions، تحتوي ال controllers أيضًا على Uniquely IDs يتم تعريفها واستخدامها من خلال التطبيق. تستخدم ال Controllers IDs نفس قواعد التسمية الخاصة بال action IDs، ويتم ذلك من خلال حذف ال dashes و capitalizing أول حرف من كل كلمة، ثم إضافة كلمة <code>Controller</code> الى الإسم الناتج -وهنا الإختلاف عن ال action ID-. مثال: ال controller ID المسمى ب <code>"post-comment"</code> ستم معالجته ليصبح <code>PostCommentController</code>. 
</p></blockquote>


## <div dir="rtl">الخلاصة</div> <span id="summary"></span>

<p dir="rtl">
    في هذا الموضوع، قمنا بالتعرف على ال controller وال view كأجزاء من MVC architectural pattern، كما قمنا بإنشاء action داخل controller موجود ليستقبل  specific request ويتحكم فيه، وقمنا أيضا بإنشاء view لعرض المحتوى. في هذا المثال البسيط، لم نتطرق الى ال model، وقمنا فقط باستخدام  ال data بشكل مباشر من خلال ال <code>message</code> parameter. 
</p>

<p dir="rtl">
    كما تعرفنا أيضا على ال routes في ال Yii، والتي تعمل بدورها كجسر بين ال user request وال controller actions. 
</p>

<p dir="rtl">
    في الموضوع القادم، ستتعلم كيف يمكنك إنشاء model وكيف يمكنك إنشاء صفحة جديدة تحتوي على Html form.
</p>

---

### Guide Ar Start Installation (`docs/guide-ar/start-installation.md`)

# <div dir="rtl">تثبيت ال Yii</div>

<p dir="rtl">يمكنك تثبيت ال Yii بطريقتين ، الأولى باستخدام مدير الحزم <a href="https://getcomposer.org">Composer</a> أو عن طريق تنزيل Archive File. الطريقة الأولى هي الطريقة المفضلة للعمل، ، لأنها تتيح لك تثبيت [<a href="../guide/structure-extensions.md">extensions</a> - ملحقات أو اضافات] جديدة، أو تحديث إطار العمل Yii ببساطة عن طريق تشغيل أمر واحد فقط.
</p>

<p dir="rtl">
    التثبيت الإفتراضي لل Yii ينتج عنه بنية تركيبة منظمة ومرتبة للمجلدات والملفات التي بداخلها، ويوفر هذا الكلام بعض المميزات التي يتم إضافتها وإنشائها بشكل تلقائي مثل صفحة تسجيل الدخول، ونموذج اتصل بنا...الخ، هذا الأمر سيشكل نقطة إنطلاق جيدة لبدء العمل على أي مشروع.
</p>
    
<p dir="rtl">
    في هذه الصفحة من التوثيق سنقوم بشرح ووصف كيف يمكن تثبيت إطار العمل Yii وبالتحديد Yii2 Basic Project Template.
    هناك Template آخر موجود بإطار العمل Yii وهو <a href="https://www.yiiframework.com/extension/yiisoft/yii2-app-advanced/doc/guide">Yii2 Advanced Project Template</a>، وهو الأفضل للعمل وإنشاء المشاريع لفريق عمل برمجي، ولتطوير المشاريع متعددة الطبقات(multiple tires). 
</p>

<blockquote class="info"><p dir="rtl">
معلومة: قالب المشروع الأساسي (Basic) مناسب لتطوير 90% من تطبيقات الويب. ويختلف القالب المتقدم (Advanced Template) عن القالب الأساسي في كيفية تنظيم وهيكلة الشيفرة البرمجية.
اذا كنت جديدا في عالم تطوير تطبيقات الويب باستخدام ال Yii، فإننا نوصيك بقوة بأن تستخدم القالب الأساسي في بناء المشروع الخاص بك.
</p></blockquote>


## <div dir="rtl">تثبيت ال Yii من خلال (Composer)</div> <span id="installing-via-composer"></span>

### <div dir="rtl">تثبيت ال Composer</div>

<p dir="rtl">
إن لم يكن لديك Composer مثبت مسبقا، فيمكنك السير بخطوات تثبيته من خلال الدخول الى هذا الرابط <a href="https://getcomposer.org/download/">https://getcomposer.org/download/</a>.
لتثبيت ال Composer في كل من نظامي Linux و Max OS X، يمكنك تنفيذ الأوامر التالية: 
</p>

```bash
curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer
```
<p dir="rtl">
    ولنظام ويندوز يمكنك تثبيت ال <a href="https://getcomposer.org/Composer-Setup.exe">Composer-Setup.exe</a> ومن ثم عمل run 
</p>

<p dir="rtl">
يرجى الدخول الى <a href="https://getcomposer.org/doc/articles/troubleshooting.md">Troubleshooting section of the Composer Documentation</a> في حال واجهتك أي مشاكل متعلقة بال composer, وإذا كنت مستخدمًا جديدًا لل composer، ننصحك أيضًا بقراءة <a href="https://getcomposer.org/doc/01-basic-usage.md">قسم الاستخدام الأساسي</a> على الأقل من التوثيف الخاص بال composer. 
</p>

<p dir="rtl">
    في هذا الدليل ، نفترض أنك قمت بتثبيت ال composer على مستوى جميع المشاريع (<a href="https://getcomposer.org/doc/00-intro.md#globally">globally</a>)  بحيث تكون أوامر ال composer متاحة لجميع المشاريع من أي مكان. أما إذا كنت تستخدم ال composer.phar لمسار محدد فقط(local directory)،  فيجب عليك ضبط  الأومر وفقًا لذلك.
</p>

<p dir="rtl">
إذا كان ال composer مثبتًا من قبل، فتأكد من استخدام إصدار حديث. يمكنك تحديث ال composer عن طريق تنفيذ الأمر التالي <code>composer self-update</code>
</p>

<blockquote class="note"><p dir="rtl">
  ملاحظة مهمة: أثناء تثبيت ال Yii ، سيحتاج ال composer إلى طلب(request) الكثير من المعلومات من ال Github Api. يعتمد عدد الطلبات على عدد dependencies التي يمتلكها التطبيق الخاص بك، وقد يكون هذا العدد أكبر من الحد المسموح به من قبل ال Github Api <b>(Github API rate limit)</b>. إذا وصلت الى الحد الأعلى المسموح به من الطلبات، فقد يطلب منك ال composer بيانات تسجيل الدخول إلى Github، وذلك للحصول على رمز (token) للدخول إلى Github Api. اذا كانت عمليات الإتصال سريعة، فقد تصل إلى هذا الحد(limit) قبل أن يتمكن ال composer من التعامل معه ، لذالك نوصي بتكوين رمز الدخول(access token) قبل تثبيت ال Yii. يرجى الرجوع إلى التوثيق الخاص بال Composer والإطلاع على التعليمات الخاصة <a href="https://getcomposer.org/doc/articles/troubleshooting.md#api-rate-limit-and-oauth-tokens">Github API tokens</a> للحصول على الإرشادات اللازمة للقيام بذلك. 
</p></blockquote>

### <div dir="rtl">تثبيت ال Yii</div> <span id="installing-from-composer"></span>

<p dir="rtl">
    من خلال ال Composer، يمكنك الآن تثبيت ال Yii من خلال تنفيذ سطر الأوامر التالي داخل أي مسار يمكن الوصول اليه من قبل الويب
</p>

```bash
composer create-project --prefer-dist yiisoft/yii2-app-basic basic
```
<p dir="rtl">
      سطر الأوامر السابق سيقوم بتثبيت أحدث نسخة مستقرة(stable) من إطار العمل Yii داخل مسار جديد اسمه basic، ويمكنك التعديل على سطر الأوامر السابق لتغيير اسم المشروع لأي اسم ترغب فيه.  
</p>

<blockquote class="info"><p dir="rtl">
معلومة: اذا واجهتك أي مشكلة عند تنفيذ السطر `composer create-project` فيمكنك الذهاب إلى <a href="https://getcomposer.org/doc/articles/troubleshooting.md">قسم استكشاف الأخطاء في ال composer</a>.
في معظم الأخطاء الشائعة، وعند حل المشكلة أو الخطأ، يمكنك إكمال التثبيت من خلال الدخول الى المسار `basic` ومن ثم تنفيذ الأمر التالي: `composer update`.
</p></blockquote>

<blockquote class="tip"><p dir="rtl">
    تلميح: اذا كنت ترغب بتثبيت أحدث نسخة خاصة بالمطورين من ال Yii، فيمكنك ذلك من خلال إضافة الخيار <a href="https://getcomposer.org/doc/04-schema.md#minimum-stability">stability</a> وذلك من خلال سطر الأوامر التالي:
</p></blockquote>  

```bash
    composer create-project --prefer-dist --stability=dev yiisoft/yii2-app-basic basic
```
<blockquote class="note"><p dir="rtl">
    ملاحظة: نسخة المطورين من ال Yii يجب أن يتم إستخدامها للمواقع الإلكترونية التي لن تصدر كنسخة نهائية للمستخدم(Not for production) لأن ذلك يمكن أن يسبب بإيقاف المشروع أو الشيفرة البرمجية الخاصة بك. 
</p></blockquote>

### <div dir="rtl">تثبيت ال Yii من خلال ال Archive File</div> <span id="installing-from-archive-file"></span>
--------------------------

<p dir="rtl">
يتضمن تثبيت Yii من ملف أرشيف ثلاث خطوات وهي:
</p>
<ol dir="rtl">
<li> تثبت الملف من خلال الموقع الرسمي <a href="https://www.yiiframework.com/download/">yiiframework.com</a>.</li>
<li> قم بفك ضغط الملف الذي تم تنزيله إلى مجلد يمكن الوصول إليه عبر الويب.</li>
<li> قم بتعديل ملف <code>config/web.php</code> عن طريق إدخال secret key ل<code> cookieValidationKey</code>
(يتم ذلك تلقائيًا إذا قمت بتثبيت ال Yii باستخدام Composer): </li>
</ol>

   ```php
   // !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
   'cookieValidationKey' => 'enter your secret key here',
   ```


### <div dir="rtl">خيارات تثبيت أخرى</div> <span id="other-installation-options"></span>
--------------------------

<p dir="rtl">
توضح تعليمات التثبيت أعلاه كيفية تثبيت ال Yii ، والذي يقوم أيضًا بإنشاء تطبيق ويب أساسي(basic).
هذا النهج هو نقطة انطلاق جيدة لمعظم المشاريع، صغيرة كانت أو كبيرة. خصوصا اذا كنت قد بدأت تعلم ال Yii من وقت قريب.
<br /><br />
لكن، هناك خيارات أخرى متاحة لتثبيت ال Yii وهي: 
</p>

<ul dir="rtl">
<li> إذا كنت ترغب فقط في تثبيت ال core لإطار العمل Yii، وترغب ببناء المكونات الخاصة بإطار العمل كما ترغب أنت وبطريقتك أنت، يمكنك اتباع التعليمات كما هو موضح في هذه الصفحة <a href="../guide/tutorial-start-from-scratch.md"> Building Application from Scratch</a>.</li>
<li> إذا كنت تريد البدء بتطبيق أكثر تعقيدًا وأكثر إحترافية، ويتناسب بشكل أفضل مع وجود فريق عمل تقني،
فأنت اذا سترغب بتثبيت ال <a href="https://github.com/yiisoft/yii2-app-advanced/blob/master/docs/guide/README.md">Advanced Project Template</a>
</li>
</ul>


### <div dir="rtl">تثبيت ال Assets</div> <span id="installing-assets"></span>
--------------------------

<p dir="rtl">
    تعتمد ال Yii على حزم <a href="https://bower.io/">Bower</a> و/أو <a href="https://www.npmjs.com/">NPM</a> لتثبيت مكتبات ال (CSS و JavaScript). ويستخدم ال composer للحصول على هذه المكتبات ، مما يسمح بالحصول على إصدارات ال PHP و CSS/JavaScript في نفس الوقت. ويمكن تحقيق ذلك إما عن طريق استخدام <a href="https://asset-packagist.org/">asset-packagist.org</a> أو من خلال ال <a href="https://github.com/fxpio/composer-asset-plugin">composer asset plugin</a>، يرجى الرجوع إلى <a href="../guide/structure-assets.md">Assets documentation</a> لمزيد من التفاصيل.
<br /><br />
قد ترغب في إدارة ال assets عبر  ال native Bower/NPM أو استخدام ال CDN أو تجنب تثبيت ال assets بالكامل من حلال ال Composer ، ويمكن ذلك من خلال إضافة الأسطر التالية إلى "composer.json":
</p>

```json
"replace": {
    "bower-asset/jquery": ">=1.11.0",
    "bower-asset/inputmask": ">=3.2.0",
    "bower-asset/punycode": ">=1.3.0",
    "bower-asset/yii2-pjax": ">=2.0.0"
},
```

<blockquote class="note"><p dir="rtl">
ملاحظة: في حالة تجاوز تثبيت ال assets عبر ال Composer، فأنت المسؤول عن تثبيت ال assets وحل مشكلات التعارض بين الإصدارات والمكتبات المختلفة. وكن مستعدًا لعدم تناسق محتمل بين ملفات ال asstes والإضافات المختلفة.
</p></blockquote>

### <div dir="rtl">التحقق من التثبيت</div> <span id="verifying-installation"></span>
--------------------------

<p dir="rtl">
    بعد الانتهاء من التثبيت، ستحتاج الى القيام بإعداد خادم الويب الخاص بك(your web server) (انظر القسم التالي) أو قم باستخدام <a href="https://www.php.net/manual/en/features.commandline.webserver.php">built-in PHP web server</a> عن طريق تنفيذ الأمر التالي داخل المسار web في المشروع الخاص بك: 
</p>
 
```bash
php yii serve
```

<blockquote class="note"><p dir="rtl">
ملاحظة: افتراضيًا ال HTTP-server يعمل على البورت 8080. ومع ذلك ، إذا كان هذا البورت قيد الاستخدام بالفعل أو كنت ترغب في تشغيل أكثر من تطبيق بهذه الطريقة، حينها سيلزمك تحديد البورت الذي يجب استخدامه. ما عليك سوى إضافة --port:
</p></blockquote>

```bash
php yii serve --port=8888
```
<p dir="rtl">
    يمكنك استخدام الرابط الموجود في الأسفل للوصول الى تطبيق ال Yii الذي قمت بتثبيته وتنفيذ الأوامر السابقة عليه.
</p>

```
http://localhost:8080/
```



<p dir="rtl">
    اذا كانت كل الإعدادات السابقة تعمل بشكل صحيح، فيجب أن ترى الصورة الموجودة بالأعلى "Congratulations!" على المتصفح. إذا لم يكن كذلك، يرجى التحقق مما إذا كان تثبيت الPHP الخاص بك متوافق مع متطلبات ال Yii. يمكنك التحقق من ذلك باستخدام أحد الأساليب التالية:
</p>

<ul dir="rtl">
    <li>قم بنسخ الملف <code>/requirements.php</code> الى المسار <code>/web/requirements.php</code> بحيث يمكنك الوصول الى الصفحة من خلال الرابط التالي: <code>http://localhost/requirements.php</code></li>
    <li>قم بتنفيذ الأوامر التالية: <br /><code>
        cd basic
        </code><br /><code>php requirements.php</code></li>
</ul>

<p dir="rtl">
    يجب عليك أن تقوم بتثبيت وإعداد ال PHP الخاص بك بحيث تلبي الحد الأدنى من متطلبات ال Yii. الأهم من ذلك يجب أن يكون الإصدار الخاص بال PHP أعلى أو يساوي 5.4. من الناحية المثالية أحدث إصدار  يعمل مع ال Yii هو ال PHP 7. يجب عليك أيضًا تثبيت ال <a href="https://www.php.net/manual/en/pdo.installation.php">PDO PHP Extension</a>.
</p>


### <div dir="rtl">إعداد ال Web Servers</div> <span id="configuring-web-servers"></span>
-----------------------

<blockquote class="info"><p dir="rtl">
معلومة: يمكنك تخطي هذا الجزء الآن إذا كنت تختبر فقط إطار العمل Yii دون أي نية لنشر هذا التطبيق على الويب(بدون رفع التطبيق على production server).
</p></blockquote>

<p dir="rtl">
    يجب أن يعمل التطبيق الذي تم تثبيته وفقًا للتعليمات المذكورة أعلاه مع أي من الخوادم ال <a href="https://httpd.apache.org/">Apache HTTP</a> أو ال <a href="https://nginx.org/">Nginx HTTP</a> في كل من أنظمة التشغيل Windows, Mac OS X أو Linux ممن لديها إصدار أعلى أو يساوي PHP 5.4، كما أن ال Yii 2.0 متوافق مع ال Facebook <a href="https://hhvm.com/">HHVM</a>، لكن، يجب أن تأخذ بعين الإعتبار أن ال HHVM يسلك في بعض الأحيان بطريقة مختلفة عن ال Native PHP، لذلك يجب أن تأخذ عناية إضافية عندما تعمل على ال HHVM.
</p>

<p dir="rtl">
    على ال production server، قد ترغب في إعداد خادم الويب الخاص بك بحيث يمكن الوصول إلى التطبيق
الخاص بك عبر ال URL التالي <code>https://www.example.com/index.php</code> بدلاً من <code>https://www.example.com/basic/web/index.php</code>. هذا الكلام يتطلب إنشاء إعداد يقوم بتوجيه ال document root الموجود على ال web server الى مجلد ال basic/web، كما قد ترغب أيضا بإخفاء ال <code>index.php</code> من ال URL كما هو موضح في ال <a href="../guide/runtime-routing.md">Routing and URL Creation</a>. في هذا الموضوع ستتعلم كيف يمكنك إعداد ال Apache أو ال Nginx server لتحقيق هذه الأهداف. 
</p>

<blockquote class="info"><p dir="rtl">
    معلومة: من خلال تعيين ال <code>basic/web</code> ك <code>document root</code>، فإنك بذلك تمنع أيضًا المستخدمين النهائيين من الوصول الى الشيفرة البرمجية الخاصة بالتطبيق الخاص بك، وتمنعهم من الوصول الى الملفات الحساسة والمهمة والمخزنة في sibling directories من <code>basic/web</code>، ويعبر رفض الوصول الى المجلدات الأخرى تحسينا أمنيا مهما، يساعد في الحفاظ على مستوى أعلى من الحماية.
</p></blockquote>

<blockquote class="info"><p dir="rtl">
معلومة: إذا كان سيتم تشغيل التطبيق الخاص بك في بيئة استضافة مشتركة(shared hosting) حيث ليس لديك الصلاحية لتعديل الإعدادات الخاصة بال web server، ستحتاج حينها الى تعديل في البنية الخاصة بالمشروع للحصول على أفضل أمان ممكن. يرجى الرجوع إلى <a href="../guide/tutorial-shared-hosting.md">Shared Hosting Environment</a> لمزيد من المعلومات. 
</p></blockquote>

<blockquote class="info"><p dir="rtl">
    معلومة: إذا كنت تقوم بتشغيل تطبيق ال Yii بوجود ال proxy، فقد تحتاج إلى إعداد التطبيق ليكون ضمن ال <a href="../guide/runtime-requests.md#trusted-proxies">trusted proxies and header</a>.
</p></blockquote>

### <div dir="rtl">الإعدادات الموصى بها لل Apache</div> <span id="recommended-apache-configuration"></span>
-----------------------

<p dir="rtl">
    استخدم الإعدادات التالية في ملف ال <code>httpd.conf</code> في Apache أو ضمن إعدادات ال virtual host.
    ملاحظة:  يجب عليك استبدال المسار التالي <code>path/to/basic/web</code> بالمسار الفعلي للتطبيق الخاص بك وصولا الى ال <code>basic/web</code>.
</p>

```apache
# Set document root to be "basic/web"
DocumentRoot "path/to/basic/web"

<Directory "path/to/basic/web">
    # use mod_rewrite for pretty URL support
    RewriteEngine on
    # If a directory or a file exists, use the request directly
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    # Otherwise forward the request to index.php
    RewriteRule . index.php

    # if $showScriptName is false in UrlManager, do not allow accessing URLs with script name
    RewriteRule ^index.php/ - [L,R=404]

    # ...other settings...
</Directory>
```


### <div dir="rtl">الإعدادات الموصى بها لل Nginx</div> <span id="recommended-nginx-configuration"></span>
-----------------------

<p dir="rtl">
    لاستخدام <a href="https://wiki.nginx.org/">Nginx</a>، يجب تثبيت PHP على أنه <a href="https://www.php.net/install.fpm">FPM SAPI</a>، ويمكنك استخدام إعدادات ال Nginx التالية، مع الإنتباه على استبدال المسار من  <code>path/to/basic/web</code> الى المسار الفعلي  وصولا إلى <code>basic/web</code> بالإضافة الى إستبدال <code>mysite.test</code> إلى ال hostname الخاص بالتطبيق.
</p>


```nginx
server {
    charset utf-8;
    client_max_body_size 128M;

    listen 80; ## listen for ipv4
    #listen [::]:80 default_server ipv6only=on; ## listen for ipv6

    server_name mysite.test;
    root        /path/to/basic/web;
    index       index.php;

    access_log  /path/to/basic/log/access.log;
    error_log   /path/to/basic/log/error.log;

    location / {
        # Redirect everything that isn't a real file to index.php
        try_files $uri $uri/ /index.php$is_args$args;
    }

    # uncomment to avoid processing of calls to non-existing static files by Yii
    #location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ {
    #    try_files $uri =404;
    #}
    #error_page 404 /404.html;

    # deny accessing php files for the /assets directory
    location ~ ^/assets/.*\.php$ {
        deny all;
    }

    location ~ \.php$ {
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_pass 127.0.0.1:9000;
        #fastcgi_pass unix:/var/run/php5-fpm.sock;
        try_files $uri =404;
    }

    location ~* /\. {
        deny all;
    }
}
```
<p dir="rtl">
    عند استخدامك لهذا الإعداد، يجب عليك أيضًا تعيين <code>cgi.fix_pathinfo = 0</code> في ملف php.ini
    من أجل تجنب العديد من طلبات ال <code>stat()</code>  الغير الضرورية للنظام.
</p>

<p dir="rtl">
    لاحظ أيضًا أنه عند تشغيل خادم HTTPS، تحتاج إلى إضافة  <code>fastcgi_param HTTPS on;</code>
بحيث يمكنك إكتشاف إذا ما كان الاتصال آمنًا أم لا.
</p>

---

### Guide Ar Start Looking Ahead (`docs/guide-ar/start-looking-ahead.md`)

# <div dir="rtl">ماذا الآن - الخطوة القادمة</div>

<p dir="rtl">
إذا قمت بقرائة الفصل الخاص ب "البداية من هنا"، فأنت الآن قادر على بناء تطبيق Yii متكامل، لقد تعلمت كيف يمكنك تنفيذ وإستخدام أكثر الخصائص والمميزات المشتركة، مثل جلب البيانات من قاعدة البيانات، وأخذ البيانات من المستخدمين، ومن ثم عرضها، كما تعلمت كيف يمكنك تقسيم البيانات الى صفحات، وقمنا باستخدام ال <a href="https://www.yiiframework.com/extension/yiisoft/yii2-gii/doc/guide">Gii</a> وتعلمنا كيف يمكننا إنشاء شيفرة برمجية من خلاله بشكل تلقائي، ومن الممارسة تعلمنا أن إنشاء الشيفرة البرمجية من خلال ال Gii يجعل من عملية تطوير المواقع والوظائف المطلوبة أمرا بسيطا وسهلا للغابة، كل ما عليك القيام به هو تعبئة ال forms.
</p>

<p dir="rtl">
    في هذا الجزء من التوثيق سنعرض ملخص للمصادر المتاحة لل Yii، والتي ستساعدك في تحسين إنتاجيتك عند إستخدامك لبيئة العمل Yii. 
</p>

<ul dir="rtl">
    <li>
        التوثيق
        <ul>
            <li><a href="https://www.yiiframework.com/doc-2.0/guide-README.html">The Definitive Guide - الدليل الشامل</a>: كما يشير الإسم، فإن هذا الدليل يحدد آلية عمل ال Yii بدقة عالية، ويوفر إرشادات حول كيفية إستخدام ال Yii، هذا الجزء الأكثر أهمية في ال Yii، والذي يجب عليك قرائته قبل كتابة أي Yii code (ملاحظة: جزء البداية من هنا، والذي قمنا بدراسته هو أحد هذه الأجزاء، ومن أهمها للبدء بإنشاء التطبيقات من خلال ال Yii).</li>
            <li><a href="https://www.yiiframework.com/doc-2.0/index.html">The Class Reference - المرجع الخاص بال Class</a> في هذا الجزء يتم تحديد الية إستخدام كل Class يقدمه ال Yii، في العادة يتم إستخدام هذا المرجع عند كتابة شيفرة برمجية وأنت ترغب في فهم آلية العمل ل Class معين، أو Method, او فهم Proporty معينة...الخ، من الأفضل إستخدام المرجع الخاص بال Class فقط عند فهم آلية العمل لل Yii. </li>
            <li><a href="https://www.yiiframework.com/wiki/?tag=yii2">The Wiki Articles - مقالات الويكي</a> مقالات الويكي هي مجموعة من الخبرات العملية للمستخدمين، تمت كتابتها ونشرها على شكل مقالات لمشاركة الخبرات، ومعظم هذه الكتابات تكون مثل الوصفات الخاصة بالطبخ، موجودة لخدمة هدف معين، وحل مشكلة محددة باستخدام ال Yii، وبالرغم من أن هذه الكتابات قد لا تكون بجودة ودقة الدليل الشامل، الا أنها قد تغطي مواضيع أكثر، وتطرح أيضا حلولا مباشرة للإستخدام.</li>
            <li><a href="https://www.yiiframework.com/doc/">الكتب</a></li>
        </ul>
    </li>
    <li><a href="https://www.yiiframework.com/extensions/">Extensions - الملحقات</a>: تفتخر ال Yii بوجود مكتبة ضخمة من الملحقات التي تمت برمجتها وإضافتها من قبل المستخدمين المتطوعين الذين شاركوا أعمالهم وطورها لتجعل مهمة المطورين الآخرين أسهل وأسرع في تطوير التطبيفات المبنية بواسطة ال Yii.</li>
    <li>
        المجتمع
        <ul>
            <li>المنتدى: <a href="https://forum.yiiframework.com/">https://forum.yiiframework.com/</a></li>
            <li>IRC chat: The #yii channel on the Libera (ircs://irc.libera.chat:6697/yii)</li>
            <li>Slack chanel: <a href="https://yii.slack.com">https://yii.slack.com</a></li>
            <li>Gitter chat: <a href="https://gitter.im/yiisoft/yii2">https://gitter.im/yiisoft/yii2</a></li>
            <li>GitHub: <a href="https://github.com/yiisoft/yii2">https://github.com/yiisoft/yii2</a></li>
            <li>Facebook: <a href="https://www.facebook.com/groups/yiitalk/">https://www.facebook.com/groups/yiitalk/</a></li>
            <li>Twitter: <a href="https://twitter.com/yiiframework">https://twitter.com/yiiframework</a></li>
            <li>LinkedIn: <a href="https://www.linkedin.com/groups/yii-framework-1483367">https://www.linkedin.com/groups/yii-framework-1483367</a></li>
            <li>Stackoverflow: <a href="https://stackoverflow.com/questions/tagged/yii2">https://stackoverflow.com/questions/tagged/yii2</a></li>
        </ul>
    </li>
</ul>

---

### Guide Ar Start Prerequisites (`docs/guide-ar/start-prerequisites.md`)

# <div dir="rtl">ماذا يجب أن تعرف قبل البدء بال Yii</div>

<p dir="rtl">
    منحنى التعلم الخاص بال Yii ليس حادًا مثل أطر PHP الأخرى، ولكن لا يزال هناك بعض الأشياء التي يجب أن تتعلمها قبل البدء بـال Yii.
</p>

## <div dir="rtl">PHP</div>

<p dir="rtl">
    ال Yii هو إطار عمل PHP، لذا تأكد من قراءة وفهم المرجع الرسمي الخاص بلغة ال <a href="https://www.php.net/manual/en/langref.php">PHP</a>. عند البدء بتطوير المشاريع أو التطبيقات باستخدام ال Yii ، ستكتب التعليمات البرمجية بطريقة كائنية التوجه OOP، لذا تأكد من أنك على دراية بـمفاهيم ال <a href="https://www.php.net/manual/en/language.oop5.basic.php">OOP</a> وكذلك ال <a href="https://www.php.net/manual/en/language.namespaces.php">namespaces</a>.
</p>

## <div dir="rtl">البرمجة كائنية التوجه object oriented programming</div>

<p dir="rtl">
    كمبرمج أو مطور يرغب بالعمل على ال Yii، يجب عليك أن تمتلك المعرفة الأساسية للبرمجة كائنية التوجه OOP. إذا لم تكن على دراية بها ، فيمكنك تعلم ذلك من خلال واحدة من هذه الدورات المنتشرة مثل هذه الدورة من <a href="https://code.tutsplus.com/tutorials/object-oriented-php-for-beginners--net-12762">tuts+</a>.<br />
ملاحظة: كلما زاد تعقيد التطبيق أو المشروع الذي تعمل عليه، كلما احتجت الى مستوى أعلى وإحترافي أكثر من مفاهيم ال OOP لحل وإدارة التعقديات التي ستترب على مثل هذه المشاريع.
</p>

## <div dir="rtl">Command line and composer</div>

<p dir="rtl">تستخدم ال Yii بشكل كبير de-facto standard PHP package manager، ال <a href="https://getcomposer.org/">Composer</a>، لذلك تأكد من قرائتك وفهمك لهذا الموضوع قبل أن تبدء. بالإضافة الى ذلك إذا لم تكن على دراية باستخدام سطر الأوامر (command line) ، فقد حان الوقت لبدء المحاولة. بمجرد تعلم الأساسيات ، لن ترغب في العمل بدون إستخدام سطر الأوامر.<br />
ال composer: ويترجم حرفيا الى كلمة "الملحن"، وهي عبارة عن أداة لإدارة المشاريع البرمجية والتي تسمح لك بتحديث وتنزيل المكتبات البرمجية المطلوبة للمشروع الخاص بك.  
</p>

---

### Guide Ar Start Workflow (`docs/guide-ar/start-workflow.md`)

# <div dir="rtl">تشغيل التطبيقات</div>

<p dir="rtl">
بعد تثبيت ال Yii، سيكون لديك تطبيق Yii جاهز للعمل عليه ويمكن الوصول إليه عبر
الرابط التالي:  <code>https://hostname/basic/web/index.php</code>  أو <code>https://hostname/index.php</code> إعتمادا على الإعدادات
الخاصة بك (إعدادت ال web server). في هذا الجزء سنستعرض الوظائف ال built-in الموجودة في التطبيق الإفتراضي لإطار العمل Yii، وكيف يقوم بتنظيم الشيفرة البرمجية، وكيف يعالج (handling) هذا التطبيق الطلبات (requests) بشكل عام.
</p>

<blockquote class="info"><p dir="rtl">
    معلومة: من أجل تبسيط الطرح، ومن خلال هذا البرنامج التعليمي " Getting Started - البداية من هنا"، من المفترض أنك قمت بتعيين <code>basic/web</code> ك <code>document root</code> لل Web server، وقد قمت أيضا بإعداد ال Url الذي يسمح لك بالوصول الى التطبيق المثبت من خلاله ليكون على الشكل التالي: <code>https://hostname/index.php</code> أو ما شابه ذلك.
اذا لم تقم بذلك، ولتلبية إحتياجاتك في هذا البرنامج التعليمي، يرجى ضبط ال Url كما هو موضح في هذه الصفحة.
يمكنك معرفة الضبط الخاص بال Web server من هنا:  <a href="start-installation.md">تثبيت ال Yii </a>
</p></blockquote>

<p dir="rtl">
ملاحظة: بخلاف إطار العمل نفسه(Yii framework)، بعد تثبيت ال template الخاص بالمشروع، يكون كل شيء في هذا التطبيق يخصك أنت، بحيث تملك الحرية في إضافة أو حذف أو تعديل كل ما تحتاج اليه.
</p>


## <div dir="rtl">خصائص / وظائف التطبيق المثبت - Functionality</div> <span id="functionality"></span>

<p dir="rtl">
    يحتوي ال Basic ِApplication Template الذي قمنا بتثبيته على أربع صفحات:
</p>

<ul dir="rtl">
    <li>الصفحة الرئيسية(Homepage): يتم عرض هذه الصفحة من خلال الرابط التالي <code>https://hostname/index.php</code> </li>
    <li>صفحة من نحن(About)</li>
    <li>صفحة اتصل بنا (Contact): في هذه الصفحة يتم عرض form يسمح للأعشاء بالإتصال بك من خلال البريد الإلكتروني.</li>
    <li>صفحة تسجيل الدخول (Login): في هذه الصفحة يتم عرض form يسمح للأعضاء بالحصول على الإذن لإستخدام الخصائص التي لا يجوز لغيرهم من الوصول اليها، قم بتجربة تسجيل الدخول من خلال استخدام <code>admin/admin</code> ولاحظ أن كلمة "Login" ستختفي من القائمة الرئيسية وستظهر محلها الكلمة "Logout"</li>
</ul>

<p dir="rtl">
هذه الصفحات تشترك بامتلاكها common header and footer -الترويسة أعلى الصفحة، والذيل أسفل الصفحة-. ويحتوي ال header على القائمة الرئيسية (main menu) والتي بدورها تسمح لك بالتنقل بين الصفحات المختلفة.
</p>

<p dir="rtl">
    أيضا، يجب عليك أن تنظر الى ال toolbar الموجود في أسفل نافذة المتصفح. ال <a href="https://github.com/yiisoft/yii2-debug/blob/master/docs/guide/README.md">debugger tool</a> هذه تعتبر كأداة مفيدة مقدمة من ال Yii لتسجيل وعرض الكثير من المعلومات وتصحيح الأخطاء، مثل  log messages, response statuses, the database queries run وما إلى ذلك.
</p>

<p dir="rtl">
    بالإضافة إلى ال  web application، يوجد هناك "console script" يسمى ب <code>yii</code>، والذي ستجده في المسار الرئيسي للتطبيق. هذا السكربت يمكن استخدامه لتشغيل المهام التي تعمل في الخفاء (background)  أو لتنفيذ مهام الصيانة (ال maintenance). <br /> ستجد الوصف الخاص بهذا السكربت  
    داخل هذه الصفحة <a href="tutorial-console.md">Console Application Section</a>.
</p>



## <div dir="rtl">هيكلية التطبيق - Application Structure</div> <span id="application-structure"></span>

<p dir="rtl">
    أكثر المسارات والملفات أهمية الموجودة داخل التطبيق (بافتراض أن ال application's root directory هو <code>basic</code>) هي:  
</p>

```
basic/                  application base path
    composer.json       used by Composer, describes package information
    config/             contains application and other configurations
        console.php     the console application configuration
        web.php         the Web application configuration
    commands/           contains console command classes
    controllers/        contains controller classes
    models/             contains model classes
    runtime/            contains files generated by Yii during runtime, such as logs and cache files
    vendor/             contains the installed Composer packages, including the Yii framework itself
    views/              contains view files
    web/                application Web root, contains Web accessible files
        assets/         contains published asset files (javascript and css) by Yii
        index.php       the entry (or bootstrap) script for the application
    yii                 the Yii console command execution script
```

<p dir="rtl">
بشكل عام، يمكن تقسيم الملفات داخل التطبيق إلى نوعين: الاول تجده تحت المسار التالي: <code>basic/web</code> والثاني تجده بالمسارات الأخرى.<br />
وبنائا على ذلك، فإنه من الممكن الوصول إلى النوع الأول مباشرة عبر ال HTTP (أي من خلال المتصفح) ، بينما لا يمكن أن يكون ذلك للنوع الثاني.
</p>

<p dir="rtl">
    يعتمد ال Yii على إستخدام ال MVC، وال MVC هو أحد ال Architectural Pattern، وهي اختصار ل <a href="https://wikipedia.org/wiki/Model-view-controller">model-view-controller</a>،
هذا الأسلوب ينعكس في تنظيم المسارات الخاصة بالملفات كما في الشكل أعلاه. يحتوي المسار <code>models</code> على جميع الكلاس <a href="../guide/structure-models.md">(model classes)</a> ، ويحتوي مسار ال <code>views</code> على جميع الصفحات التي ستستخدم في العرض <a href="../guide/structure-controllers.md">(view scripts)</a>، ويحتوي مسار ال<code>controllers</code> على
    جميع <a href="../guide/structure-views.md">(controller classes)</a> 
</p>

<p dir="rtl">
    يوضح المخطط التالي ال static structure للتطبيق. 
</p>



<p dir="rtl">
    يحتوي كل تطبيق على نص برمجي يستخدم للدخول الى التطبيق (كبوابة بعدها يظهر التطبيق للناظر)، ويسمى هذا الجزء بال entry script، وهو يمثل الصفحة <code>web/index.php</code>، ويعد هذا المدخل النص البرمجي الوحيد الذي يمكن الوصول إليه من خلال ال PHP في التطبيق، ويعمل هذا ال entry script على أخذ ال request ومن ثم إنشاء instance خاص بالتطبيق ليستطيع التعامل معه (التعامل مع التطبيق ومكوناته).
    يقوم <a href="../guide/structure-applications.md">application</a> على معالجة ال request بمساعدة من ال <a href="../guide/concept-components.md">components</a>، ومن ثم بقوم التطبيق بإرسال ال request الى عناصر ال MVC، كما يتم استخدام ال <a href="../guide/structure-widgets.md">Widgets</a> في ال <a href="../guide/structure-views.md">views</a> للمساعدة في إنشاء العناصر المعقدة والمتغيرة (Complex &amp; Dynamic user interface) لواجهة المستخدم.
</p>

## <div dir="rtl">دورة الحياة الخاصة بال request</div> <span id="request-lifecycle"></span>

<p dir="rtl">
يوضح المخطط التالي كيفية معالجة التطبيق ل request معين.
</p>



<ol dir="rtl">
    <li>يقوم المستخدم بعمل request لل <a href="../guide/structure-entry-scripts.md">entry script</a> <code>web/index.php</code>.</li>
    <li>يقوم ال entry script على جلب <a href="../guide/concept-configurations.md">الإعدادات</a> الخاصة بالتطبيق ومن ثم إنشاء ال instance الخاص بالتطبيق ليستطيع التحكم ب request وإدارتها.</li>
    <li>يقوم التطبيق بمعالجة ال <a href="../guide/runtime-routing.md">requested route</a> بمساعدة من ال <a href="../guide/runtime-requests.md">request</a> application component.</li>
    <li>يقوم التطبيق على إنشاء instance من ال <a href="../guide/structure-controllers.md">controller</a> للتحكم بال request.</li>
    <li>يقوم ال controller على إنشاء <a href="../guide/structure-controllers.md">action</a> instance مع مجموعة من الفلاتر(المرشحات) الخاصة بهذا ال action.</li>
    <li>في حالة فشل أي فلتر، يتم إلغاء الإجراء.</li>
    <li>في حال نجاح جميع الفلاتر ، يتم تنفيذ الإجراء.</li>
    <li>يقوم ال action بجلب بعض البيانات الخاصة بال models, وفي الغالب ستكون من قاعدة البيانات إن أمكن ذلك.</li>
    <li>سيقوم ال action بجلب ال view ليقوم بتقديم البيانات التي تم جلبها لل view.</li>
    <li>عملية الجلب السابقة ستقوم على إرجاع النتائج الى <a href="../guide/runtime-responses.md">response</a> application component</li>
    <li>بعد ذلك سيقوم ال response component بإرسال النتيجة النهائية الى المتصفح الخاص بالمستخدم. </li>
</ol>

---

### Guide De Blocktypes.Json (`docs/guide-de/blocktypes.json`)

{
    "Warning:": "Achtung:",
    "Note:": "Hinweis:",
    "Info:": "Info:",
    "Tip:": "Tipp:"
}

---

### Guide De Intro Yii (`docs/guide-de/intro-yii.md`)

Was ist Yii?
============

Yii ist ein leistungsstarkes, komponentenbasiertes PHP-Framework zur schnellen Entwicklung moderner Webanwendungen.
Der Name Yii (ausgesprochen `Ji` oder `[ji:]`) bedeutet im Chinesischen "einfach und evolutionär". Er kann außerdem
als Akronym für **Yes It Is!** (zu Deutsch **Ja, ist es!**) verstanden werden.


Wofür ist Yii am besten geeignet?
---------------------------------

Yii ist universell einsetzbar: Mit ihm lassen sich Webanwendungen aller Art entwickeln. Dank seiner komponentenbasierten
Architektur und seiner ausgefeilten Caching-Unterstützung eignet es sich besonders für umfangreiche Anwendungen wie
Portale, Foren, Content-Management-Systeme (CMS), E-Commerce-Projekte, RESTful Web Services und vieles mehr.


Wie unterscheidet sich Yii von anderen Frameworks?
--------------------------------------------------

Wenn Sie bereits mit einem anderen Framework vertraut sind, wird es Sie vermutlich interessieren, wie Yii im Vergleich
dazu abschneidet:

- Wie die meisten PHP-Frameworks implementiert Yii das Architekturmuster MVC (Model-View-Controller) und fördert eine
  Organisation des Codes, die auf diesem Muster basiert.
- Yii vertritt die Philosophie, dass Code auf eine einfache und dennoch elegante Weise geschrieben werden sollte.
  Yii wird nie versuchen, Strukturen zu verkomplizieren, nur um ein bestimmtes Entwurfsmuster strikt einzuhalten.
- Yii ist ein Full-Stack-Framework: Seine Komponenten decken alle Schichten einer Anwendung ab und bieten viele
  bewährte und sofort einsatzbereite Funktionen, darunter Query Builder und ActiveRecord für relationale und
  NoSQL-Datenbanken, Unterstützung für die Entwicklung von RESTful APIs, mehrstufiges Caching und mehr.
- Yii ist sehr gut erweiterbar. Sie können fast jeden Teil des Kerncodes anpassen oder ersetzen. Sie können außerdem
  die solide Erweiterungsarchitektur von Yii nutzen, um weiterverteilbare Erweiterungen einzusetzen oder zu entwickeln.
- Hohe Performance ist immer ein vorrangiges Ziel von Yii.

Yii ist keine One-Man-Show, sondern wird von einem [starken Kern-Entwicklerteam](https://www.yiiframework.com/team/)
sowie einer [großen Community](https://github.com/yiisoft/yii2/graphs/contributors) von Fachleuten unterstützt, die
ständig zur Entwicklung von Yii beitragen. Das Yii-Entwicklerteam behält die neuesten Webentwicklungstrends sowie die
Best Practices und Funktionen im Auge, die in anderen Frameworks und Projekten zu finden sind. Die relevantesten
Best Practices und Funktionen, die anderswo zu finden sind, werden regelmäßig in das Kernframework integriert und über
einfache und elegante Schnittstellen zugänglich gemacht.


Yii-Versionen
-------------

Yii steht derzeit in zwei Major-Versionen zur Verfügung: 1.1 und 2.0. Version 1.1 ist die alte Generation und befindet
sich nun im Wartungsmodus. Version 2.0 ist eine komplette Neufassung von Yii, die die neuesten Technologien und
Protokolle aufgreift, einschließlich Composer, PSR, Namespaces, Traits usw. Version 2.0 ist die aktuelle Generation
des Frameworks und wird in den nächsten Jahren der Hauptfokus der Entwicklung sein.
In diesem Handbuch geht es hauptsächlich um die Version 2.0.

> Info: Mit Yii3 ist inzwischen auch die nächste Generation des Frameworks verfügbar. Sie wird in diesem Handbuch
> nicht behandelt. Weitere Informationen finden Sie im [Handbuch zu Yii3](https://yiisoft.github.io/docs/guide/).


Anforderungen und Voraussetzungen
---------------------------------

Yii 2.0 erfordert PHP 7.4.0 oder höher und läuft am besten mit der neuesten Version von PHP. Detailliertere
Informationen über die Anforderungen einzelner Funktionen erhalten Sie, indem Sie den "Requirement Checker" ausführen,
der in jedem Yii-Release enthalten ist.

Die Verwendung von Yii erfordert Grundkenntnisse in der objektorientierten Programmierung (OOP), da es sich bei Yii um
ein rein OOP-basiertes Framework handelt. Yii 2.0 nutzt auch die neuesten Funktionen von PHP, wie z. B.
[Namespaces](https://www.php.net/manual/de/language.namespaces.php) und
[Traits](https://www.php.net/manual/de/language.oop5.traits.php). Das Verständnis dieser Konzepte wird Ihnen helfen,
sich leichter in Yii 2.0 zurechtzufinden.

---

### Guide De Start Gii (`docs/guide-de/start-gii.md`)

Code generieren mit Gii
=======================

Dieser Abschnitt beschreibt, wie [Gii](https://www.yiiframework.com/extension/yiisoft/yii2-gii/doc/guide) zur
automatischen Generierung von Code verwendet werden kann, der gängige Webseitenfunktionen abdeckt. Die Verwendung von
Gii erfordert nur die Eingabe der richtigen Informationen, wie auf den Gii-Seiten beschrieben.

In diesem Tutorial lernen Sie:

* die Aktivierung von Gii in Ihrer Anwendung
* die Verwendung von Gii zur Generierung einer Active-Record-Klasse
* die Verwendung von Gii zur Generierung des Codes zur Implementierung von CRUD-Operationen für eine Datenbanktabelle
* die individuelle Anpassung des Codes, der von Gii generiert wird


Gii starten <span id="starting-gii"></span>
-----------

[Gii](https://www.yiiframework.com/extension/yiisoft/yii2-gii/doc/guide) wird als [Modul](structure-modules.md) für Yii
angeboten. Sie können Gii durch die Konfiguration der [[yii\base\Application::modules|modules]]-Eigenschaft der
Anwendung aktivieren. Abhängig davon, wie Sie Ihre Anwendung aufgesetzt haben, finden Sie den folgenden Code
möglicherweise bereits in der Konfigurationsdatei `config/web.php`:

```php
$config = [ ... ];

if (YII_ENV_DEV) {
    $config['bootstrap'][] = 'gii';
    $config['modules']['gii'] = [
        'class' => 'yii\gii\Module',
    ];
}
```

Die obenstehende Konfiguration legt fest, dass die Anwendung in der
[Entwicklungsumgebung](concept-configurations.md#environment-constants) ein Modul mit dem Namen `gii` lädt, das durch
die Klasse [[yii\gii\Module]] abgebildet wird.

Prüfen Sie das [Einstiegsskript](structure-entry-scripts.md) `web/index.php` Ihrer Anwendung. Dort finden Sie die
folgende Zeile, die im Wesentlichen bewirkt, dass `YII_ENV_DEV` den Wert `true` hat:

```php
defined('YII_ENV') or define('YII_ENV', 'dev');
```

Aufgrund dieser Zeile befindet sich Ihre Anwendung im Entwicklungsmodus. Dadurch ist sichergestellt, dass Gii mittels
obenstehender Konfiguration aktiviert wird. Sie können nun mittels folgender URL darauf zugreifen:

```
https://hostname/index.php?r=gii
```

> Note: Falls Sie von einem anderen Computer als `localhost` auf Gii zugreifen, wird Ihnen der Zugriff aus
> Sicherheitsgründen standardmäßig verweigert. Fügen Sie Ihre IP-Adresse wie folgt zu den `allowedIPs` hinzu, um den
> Zugriff zu erlauben:
>
```php
'gii' => [
    'class' => 'yii\gii\Module',
    'allowedIPs' => ['127.0.0.1', '::1', '192.168.0.*', '192.168.178.20'] // Passen Sie dies an Ihre Bedürfnisse an
],
```




Generieren einer Active-Record-Klasse <span id="generating-ar"></span>
-------------------------------------

Um mittels Gii eine Active-Record-Klasse zu generieren, klicken Sie auf den "Model Generator"-Link auf der Startseite
von Gii. Füllen Sie das Formular daraufhin wie folgt aus:

* Table Name: `country`
* Model Class: `Country`



Klicken Sie dann auf den "Preview"-Button. Daraufhin sehen Sie in der Ergebnisliste die zu erstellende Datei
`models/Country.php`. Klicken Sie auf den Dateinamen, um sich eine Vorschau des Inhalts der Datei anzusehen.

Wenn bereits eine Datei mit demselben Namen existiert und Sie diese überschreiben würden, können Sie vorher auf den
`diff`-Button neben dem Dateinamen klicken, um sich die Unterschiede zwischen dem zu generierenden Code und der
bestehenden Version anzusehen.



Zum Überschreiben einer existierenden Datei aktivieren Sie die Checkbox neben "overwrite" und klicken Sie dann auf den
"Generate"-Button. Beim Generieren einer neuen Datei können Sie einfach auf den "Generate"-Button klicken.

Daraufhin erscheint eine Seite, die Ihnen bestätigt, dass der Code erfolgreich generiert wurde. Falls die Datei bereits
existierte, erscheint zusätzlich eine Meldung, dass diese mit dem neu generierten Code überschrieben wurde.


Generieren von CRUD-Code <span id="generating-crud"></span>
------------------------

CRUD steht für Create, Read, Update und Delete. Dies sind die englischen Begriffe für die vier Standardaufgaben in der
Datenverarbeitung der meisten Webseiten. Um mittels Gii Code mit CRUD-Funktionalität zu generieren, klicken Sie auf
"CRUD Generator" auf der Startseite von Gii. Im "country"-Beispiel füllen Sie das Formular wie folgt aus:

* Model Class: `app\models\Country`
* Search Model Class: `app\models\CountrySearch`
* Controller Class: `app\controllers\CountryController`



Klicken Sie dann auf den "Preview"-Button. Daraufhin sehen Sie eine Liste der zu generierenden Dateien (siehe Bild
unten).



Falls Sie zuvor den Controller `controllers/CountryController.php` und die Datei `views/country/index.php` erstellt
haben (im Datenbank-Abschnitt des Handbuchs), aktivieren Sie die Checkboxen "overwrite", um die beiden Dateien zu
ersetzen (die bisherigen Versionen bieten keine vollständige CRUD-Unterstützung).


Probieren Sie es aus <span id="trying-it-out"></span>
--------------------

Um die generierten Dateien in Aktion zu sehen, navigieren Sie in Ihrem Browser zu folgender URL:

```
https://hostname/index.php?r=country%2Findex
```

Sie sehen hier eine Datentabelle, die Ihnen die Länder aus der Datenbanktabelle anzeigt. Sie können die Daten sortieren
oder durch die Eingabe von Filterbedingungen im Tabellenkopf filtern.

Für jedes Land in der Tabelle gibt es rechts Aktionslinks zum Anzeigen der Details, zum Bearbeiten oder zum Löschen des
Datensatzes. Sie können auch auf den "Create Country"-Button oberhalb der Tabelle klicken, um ein Formular zum Anlegen
eines neuen Landes zu öffnen.





Für den Fall, dass Sie die Dateien analysieren oder verändern möchten, finden Sie nachfolgend eine Liste der Dateien,
die von Gii generiert wurden:

* Controller: `controllers/CountryController.php`
* Models: `models/Country.php` und `models/CountrySearch.php`
* Views: `views/country/*.php`

> Info: Gii ist so aufgebaut, dass es einfach angepasst und erweitert werden kann. Durch kluges Einsetzen von Gii
> kann sich Ihr Entwicklungsprozess drastisch verkürzen. Weitere Informationen finden Sie im Abschnitt
> [Gii](https://www.yiiframework.com/extension/yiisoft/yii2-gii/doc/guide).


Zusammenfassung <span id="summary"></span>
---------------

In diesem Abschnitt haben Sie gelernt, wie man mit Gii Code generieren kann, der die vollständige CRUD-Funktionalität
für die in einer Datenbanktabelle gespeicherten Inhalte implementiert.

---

### Guide De Start Looking Ahead (`docs/guide-de/start-looking-ahead.md`)

Ausblick
========

Wenn Sie sich durch das gesamte "Einstieg"-Kapitel durchgearbeitet haben, haben Sie nun eine fertige Yii-Anwendung
erstellt. Dabei haben Sie gelernt, häufig benötigte Funktionen wie z. B. das Erfassen von Benutzerdaten mittels
HTML-Formularen, das Lesen von Daten aus einer Datenbank und deren seitenweise Darstellung umzusetzen. Sie wissen jetzt
auch, wie man mittels [Gii](https://www.yiiframework.com/extension/yiisoft/yii2-gii/doc/guide) automatisch Code
generieren kann. Die Verwendung von Gii zur Code-Generierung macht einen Großteil Ihres Webentwicklungsprozesses so
einfach wie das Ausfüllen einiger Formulare.

Dieser Abschnitt fasst die verfügbaren Yii-Ressourcen zusammen, die Ihnen helfen, bei der Verwendung des Frameworks
produktiver zu sein.

* Dokumentation
    - [Das umfassende Handbuch](https://www.yiiframework.com/doc-2.0/guide-README.html):
      Wie der Name vermuten lässt, definiert dieses Handbuch genau, wie Yii funktionieren soll, und bietet eine
      allgemeine Anleitung zur Verwendung von Yii. Es ist das wichtigste Yii-Tutorial, und Sie sollten es lesen, bevor
      Sie Yii-Code schreiben.
    - [Die Klassenreferenz](https://www.yiiframework.com/doc-2.0/index.html):
      Hier finden Sie die Dokumentation aller Klassen, die von Yii bereitgestellt werden. Sie kommt hauptsächlich dann
      zur Anwendung, wenn Sie beim Programmieren die Verwendung bestimmter Klassen, Methoden oder Eigenschaften
      verstehen möchten. Die Verwendung dieser Dokumentation empfiehlt sich erst, wenn Sie ein Kontextverständnis des
      gesamten Frameworks entwickelt haben.
    - [Die Wiki-Artikel](https://www.yiiframework.com/wiki/?tag=yii2):
      Die Wiki-Artikel wurden von Yii-Benutzern auf Basis ihrer eigenen Erfahrungen geschrieben. Die meisten dieser
      Artikel sind im Stile von "Kochrezepten" verfasst und demonstrieren damit exemplarisch die Lösung eines
      spezifischen Problems mittels Yii. Während die Qualität dieser Artikel unter Umständen die des Handbuchs nicht
      erreicht, sind sie insofern nützlich, als sie ein breiteres Themenspektrum abdecken und oftmals
      "Ready-to-use"-Lösungen anbieten.
    - [Bücher](https://www.yiiframework.com/books)
* [Erweiterungen](https://www.yiiframework.com/extensions/):
  Yii bietet eine Bibliothek mit tausenden Erweiterungen, die von Yii-Benutzern beigesteuert wurden und einfach in Ihre
  Anwendungen integriert werden können. Damit lässt sich Ihr Entwicklungsprozess weiter beschleunigen und vereinfachen.
* Gemeinschaft
    - Forum: <https://forum.yiiframework.com/>
    - IRC-Chat: Der #yii-Channel im Libera-Netzwerk (<ircs://irc.libera.chat:6697/yii>)
    - Slack-Channel: <https://www.yiiframework.com/go/slack>
    - Gitter-Chat: <https://gitter.im/yiisoft/yii2>
    - GitHub: <https://github.com/yiisoft/yii2>
    - Facebook: <https://www.facebook.com/groups/yiitalk/>
    - Twitter: <https://twitter.com/yiiframework>
    - LinkedIn: <https://www.linkedin.com/groups/yii-framework-1483367>
    - Stackoverflow: <https://stackoverflow.com/questions/tagged/yii2>

---

### Guide Es Blocktypes.Json (`docs/guide-es/blocktypes.json`)

{
    "Warning:": "Aviso:",
    "Note:": "Nota:",
    "Info:": "Información:",
    "Tip:": "Consejo:"
}

---

### Guide Es Caching Data (`docs/guide-es/caching-data.md`)

Almacenamiento de Datos en Caché
================================

El almacenamiento de datos en caché trata del almacenamiento de alguna variable PHP en caché y recuperarla más tarde del mismo. También es la base de algunas de las características avanzadas de almacenamiento en caché, tales como [el almacenamiento en caché de consultas a la base de datos](#query-caching) y [el almacenamiento en caché de contenido](caching-page.md).

El siguiente código muestra el típico patrón de uso para el almacenamiento en caché, donde la variable `$cache` se refiere al [componente caché](#cache-components):

```php
// intenta recuperar $data de la caché
$data = $cache->get($key);

if ($data === false) {

    // $data no ha sido encontrada en la caché, calcularla desde cero

    // guardar $data en caché para así recuperarla la próxima vez
    $cache->set($key, $data);
}

// $data está disponible aquí
```


## Componentes de Caché <span id="cache-components"></span>

El almacenamiento de datos en caché depende de los llamados *cache components* (componentes de caché) los cuales
representan diferentes tipos de almacenamiento en caché, como por ejemplo en memoria, en archivos o en base de datos.

Los Componentes de Caché están normalmente registrados como [componentes de la aplicación](structure-application-components.md) para que de esta forma puedan
ser configurados y accesibles globalmente. El siguiente código muestra cómo configurar el componente de aplicación
`cache` para usar [memcached](https://memcached.org/) con dos servidores caché:

```php
'components' => [
    'cache' => [
        'class' => 'yii\caching\MemCache',
        'servers' => [
            [
                'host' => 'server1',
                'port' => 11211,
                'weight' => 100,
            ],
            [
                'host' => 'server2',
                'port' => 11211,
                'weight' => 50,
            ],
        ],
    ],
],
```

Puedes acceder al componente de caché usando la expresión  `Yii::$app->cache`.

Debido a que todos los componentes de caché soportan el mismo conjunto de APIs, podrías cambiar el componente de caché
subyacente por otro diferente mediante su reconfiguración en la configuración de la aplicación sin tener que modificar
el código que utiliza la caché. Por ejemplo, podrías modificar la configuración anterior para usar [[yii\caching\ApcCache|APC cache]]:

```php
'components' => [
    'cache' => [
        'class' => 'yii\caching\ApcCache',
    ],
],
```

> Tip: Puedes registrar múltiples componentes de aplicación de caché. El componente llamado `cache` es usado por defecto por muchas clases caché-dependiente (ej. [[yii\web\UrlManager]]).


### Almacenamientos de Caché Soportados <span id="supported-cache-storage"></span>

Yii proporciona varios componentes de caché que pueden almacenar datos en diferentes medios. A continuación
se muestra un listado con los componentes de caché disponibles:

* [[yii\caching\ApcCache]]: utiliza la extensión de PHP [APC](https://www.php.net/manual/es/book.apc.php). Esta opción puede ser considerada como la más rápida de entre todas las disponibles para una aplicación centralizada. (ej. un servidor, no dedicado al balance de carga, etc).
* [[yii\caching\DbCache]]: utiliza una tabla de base de datos para almacenar los datos. Por defecto, se creará y usará como base de datos [SQLite3](https://sqlite.org/) en el directorio runtime. Se puede especificar explícitamente que base de datos va a ser utilizada configurando la propiedad `db`.
* [[yii\caching\DummyCache]]: dummy cache (caché tonta) que no almacena en caché nada. El propósito de este componente es simplificar el código necesario para chequear la disponibilidad de caché. Por ejemplo, durante el desarrollo o si el servidor no tiene soporte de caché actualmente, puede utilizarse este componente de caché. Cuando este disponible un soporte en caché, puede cambiarse el componente correspondiente. En ambos casos, puede utilizarse el mismo código `Yii::$app->cache->get($key)` para recuperar un dato sin la preocupación de que `Yii::$app->cache` pueda ser `null`.
* [[yii\caching\FileCache]]: utiliza un fichero estándar para almacenar los datos. Esto es adecuado para almacenar grandes bloques de datos (como páginas).
* [[yii\caching\MemCache]]: utiliza las extensiones de PHP [memcache](https://www.php.net/manual/es/book.memcache.php) y [memcached](https://www.php.net/manual/es/book.memcached.php). Esta opción puede ser considerada como la más rápida cuando la caché es manejada en una aplicación distribuida (ej. con varios servidores, con balance de carga, etc..)
* [[yii\redis\Cache]]: implementa un componente de caché basado en [Redis](https://redis.io/) que almacenan pares clave-valor (requiere la versión 2.6.12 de redis).
* [[yii\caching\WinCache]]: utiliza la extensión de PHP [WinCache](https://iis.net/downloads/microsoft/wincache-extension) ([ver también](https://www.php.net/manual/es/book.wincache.php)).

> Tip: Puedes utilizar diferentes tipos de almacenamiento de caché en la misma aplicación. Una estrategia común es la de usar almacenamiento de caché en memoria para almacenar datos que son pequeños pero que son utilizados constantemente (ej. datos estadísticos), y utilizar el almacenamiento de caché en archivos o en base de datos para guardar datos que son grandes y utilizados con menor frecuencia (ej. contenido de página).


## API de Caché <span id="cache-apis"></span>

Todos los componentes de almacenamiento de caché provienen de la misma clase "padre" [[yii\caching\Cache]] y por lo tanto soportan la siguiente API:

* [[yii\caching\Cache::get()|get()]]: recupera un elemento de datos de la memoria caché con una clave especificada.
  Un valor nulo será devuelto si el elemento de datos no ha sido encontrado en la memoria caché o si ha expirado o ha sido invalidado.
* [[yii\caching\Cache::set()|set()]]: almacena un elemento de datos identificado por una clave en la memoria caché.
* [[yii\caching\Cache::add()|add()]]: almacena un elemento de datos identificado por una clave en la memoria caché si la clave no se encuentra en la memoria caché.
* [[yii\caching\Cache::mget()|mget()]]: recupera varios elementos de datos de la memoria caché con las claves especificadas.
* [[yii\caching\Cache::mset()|mset()]]: almacena múltiples elementos de datos en la memoria caché. Cada elemento se identifica por una clave.
* [[yii\caching\Cache::madd()|madd()]]: almacena múltiples elementos de datos en la memoria caché. Cada elemento se identifica con una clave. Si una clave ya existe en la caché, el elemento será omitido.
* [[yii\caching\Cache::exists()|exists()]]: devuelve un valor que indica si la clave especificada se encuentra en la memoria caché.
* [[yii\caching\Cache::delete()|delete()]]: elimina un elemento de datos identificado por una clave de la caché.
* [[yii\caching\Cache::flush()|flush()]]: elimina todos los elementos de datos de la cache.

> Note: No Almacenes el valor boolean `false` en caché directamente porque el método [[yii\caching\Cache::get()|get()]] devuelve
el valor `false` para indicar que el dato no ha sido encontrado en la caché. Puedes poner `false` dentro de un array y cachear
este array para evitar este problema.

Algunos sistemas de almacenamiento de caché, como por ejemplo MemCache, APC, pueden recuperar múltiples valores almacenados en modo de lote (batch), lo que puede reducir considerablemente la sobrecarga que implica la recuperación de datos almacenados en la caché. Las API [[yii\caching\Cache::mget()|mget()]] y  [[yii\caching\Cache::madd()|madd()]]
se proporcionan para utilizar esta característica. En el caso de que el sistema de memoria caché no lo soportara, ésta sería simulada.

Puesto que [[yii\caching\Cache]] implementa `ArrayAccess`, un componente de caché puede ser usado como un array.
El siguiente código muestra unos ejemplos:

```php
$cache['var1'] = $value1;  // equivalente a: $cache->set('var1', $value1);
$value2 = $cache['var2'];  // equivalente a: $value2 = $cache->get('var2');
```


### Claves de Caché <span id="cache-keys"></span>

Cada elemento de datos almacenado en caché se identifica por una clave. Cuando se almacena un elemento de datos en la memoria caché, se debe especificar una clave. Más tarde, cuando se recupera el elemento de datos de la memoria caché, se debe proporcionar la clave correspondiente.

Puedes utilizar una cadena o un valor arbitrario como una clave de caché. Cuando una clave no es una cadena de texto, ésta será automáticamente serializada en una cadena.

Una estrategia común para definir una clave de caché es incluir en ella todos los factores determinantes en términos de un array. Por ejemplo, [[yii\db\Schema]] utiliza la siguiente clave para almacenar en caché la información del esquema de una tabla de base de datos:

```php
[
    __CLASS__,              // nombre de la clase del esquema
    $this->db->dsn,         // nombre del origen de datos de la conexión BD
    $this->db->username,    // usuario para la conexión BD
    $name,                  // nombre de la tabla
];
```

Como puedes ver, la clave incluye toda la información necesaria para especificar de una forma exclusiva una tabla de base de datos.

Cuando en un mismo almacenamiento en caché es utilizado por diferentes aplicaciones, se debería especificar un prefijo único para las claves de la caché por cada una de las aplicaciones para así evitar conflictos. Esto puede hacerse mediante la configuración de la propiedad [[yii\caching\Cache::keyPrefix]]. Por ejemplo, en la configuración de la aplicación podrías escribir el siguiente código:

```php
'components' => [
    'cache' => [
        'class' => 'yii\caching\ApcCache',
        'keyPrefix' => 'myapp',       // un prefijo de clave de caché único
    ],
],
```

Para garantizar la interoperabilidad, deberían utilizarse sólo caracteres alfanuméricos.


### Caducidad de Caché <span id="cache-expiration"></span>

Un elemento de datos almacenado en la memoria caché permanecerá en ella para siempre, a menos que sea removida de alguna manera debido a alguna directiva de caché (ej. el espacio de almacenamiento en caché está lleno y los datos más antiguos se eliminan). Para cambiar este comportamiento, podrías proporcionar un parámetro de caducidad al llamar [[yii\caching\Cache::set()|set()]] para guardar el elemento de datos. El parámetro nos indica por cuántos segundos el elemento se mantendrá válido en memoria caché. Cuando llames [[yii\caching\Cache::get()|get()]] para recuperar el elemento, si el tiempo de caducidad ha pasado, el método devolverá `false`, indicando que el elemento de datos no ha sido encontrado en la memoria caché. Por ejemplo,

```php
// guardar los datos en memoria caché al menos 45 segundos
$cache->set($key, $data, 45);

sleep(50);

$data = $cache->get($key);
if ($data === false) {
    // $data ha caducado o no ha sido encontrado en la memoria caché
}
```


### Dependencias de Caché <span id="cache-dependencies"></span>

Además de configurar el tiempo de caducidad, los datos almacenados en caché pueden también ser invalidados conforme a algunos cambios en la caché de dependencias. Por ejemplo, [[yii\caching\FileDependency]] representa la dependencia del tiempo de modificación del archivo. Cuando esta dependencia cambia, significa que el archivo correspondiente ha cambiado. Como resultado, cualquier contenido anticuado que sea encontrado en la caché debería ser invalidado y la llamada a [[yii\caching\Cache::get()|get()]] debería retornar falso.

Una dependencia es representada como una instancia de [[yii\caching\Dependency]] o su clase hija. Cuando llamas [[yii\caching\Cache::set()|set()]] para almacenar un elemento de datos en la caché, puedes pasar el objeto de dependencia asociado. Por ejemplo,

```php
// Crear una dependencia sobre el tiempo de modificación del archivo example.txt.
$dependency = new \yii\caching\FileDependency(['fileName' => 'example.txt']);

// Los datos expirarán en 30 segundos.
// También podría ser invalidada antes si example.txt es modificado.
$cache->set($key, $data, 30, $dependency);

// La caché comprobará si los datos han expirado.
// También comprobará si la dependencia ha cambiado.
// Devolverá `false` si se encuentran algunas de esas condiciones.
$data = $cache->get($key);
```

Aquí abajo se muestra un sumario de las dependencias disponibles:

- [[yii\caching\ChainedDependency]]: la dependencia cambia si cualquiera de las dependencias en la cadena cambia.
- [[yii\caching\DbDependency]]: la dependencia cambia si el resultado de la consulta de la sentencia SQL especificada cambia.
- [[yii\caching\ExpressionDependency]]: la dependencia cambia si el resultado de la expresión de PHP especificada cambia.
- [[yii\caching\CallbackDependency]]: la dipendenza viene modificata se il risultato della callback PHP specificata cambia.
- [[yii\caching\FileDependency]]:  la dependencia cambia si se modifica la última fecha de modificación del archivo.
- [[yii\caching\TagDependency]]: marca un elemento de datos en caché con un nombre de grupo. Puedes invalidar los elementos de datos almacenados en caché
  con el mismo nombre del grupo a la vez llamando a [[yii\caching\TagDependency::invalidate()]].


## Consultas en Caché <span id="query-caching"></span>

Las consultas en caché es una característica especial de caché construido sobre el almacenamiento de caché de datos. Se
proporciona para almacenar en caché el resultado de consultas a la base de datos.

Las consultas en caché requieren una [[yii\db\Connection|DB connection]] y un componente de aplicación caché válido. El uso básico de las consultas en memoria caché es el siguiente, asumiendo que `db` es una instancia de [[yii\db\Connection]]:

```php
$result = $db->cache(function ($db) {

    // el resultado de la consulta SQL será servida de la caché
    // si el cacheo de consultas está habilitado y el resultado de la consulta se encuentra en la caché
    return $db->createCommand('SELECT * FROM customer WHERE id=1')->queryOne();

});
```

El cacheo de consultas puede ser usado tanto para [DAO](db-dao.md) como para [ActiveRecord](db-active-record.md):

```php
$result = Customer::getDb()->cache(function ($db) {
    return Customer::find()->where(['id' => 1])->one();
});
```

> Note: Algunos DBMS (ej. [MySQL](https://dev.mysql.com/doc/refman/5.6/en/query-cache.html)) también soporta el almacenamiento en caché desde el mismo servidor de la BD. Puedes optar por utilizar cualquiera de los mecanismos de memoria caché. El almacenamiento en caché de consultas previamente descrito tiene la ventaja que de que se puede especificar dependencias de caché de una forma flexible y son potencialmente mucho más eficientes.


### Configuraciones <span id="query-caching-configs"></span>

Las consultas en caché tienen tres opciones configurables globales a través de [[yii\db\Connection]]:

* [[yii\db\Connection::enableQueryCache|enableQueryCache]]: activa o desactiva el cacheo de consultas.
  Por defecto es `true`. Tenga en cuenta que para activar el cacheo de consultas, también necesitas tener una caché válida, especificada por [[yii\db\Connection::queryCache|queryCache]].
* [[yii\db\Connection::queryCacheDuration|queryCacheDuration]]: representa el número de segundos que un resultado de la consulta permanecerá válida en la memoria caché. Puedes usar 0 para indicar que el resultado de la consulta debe permanecer en la caché para siempre. Esta propiedad es el valor usado por defecto cuando [[yii\db\Connection::cache()]] es llamada sin especificar una duración.
* [[yii\db\Connection::queryCache|queryCache]]: representa el ID del componente de aplicación de caché.
  Por defecto es `'cache'`. El almacenamiento en caché de consultas se habilita sólo si hay un componente de la aplicación de caché válida.


### Usos <span id="query-caching-usages"></span>

Puedes usar [[yii\db\Connection::cache()]] si tienes multiples consultas SQL que necesitas a aprovechar el cacheo de consultas. El uso es de la siguiente manera,

```php
$duration = 60;     // resultado de la consulta de caché durante 60 segundos.
$dependency = ...;  // dependencia opcional

$result = $db->cache(function ($db) {

    // ... realiza consultas SQL aquí ...

    return $result;

}, $duration, $dependency);
```

Cualquier consulta SQL en una función anónima será cacheada durante el tiempo indicado con la dependencia especificada.
Si el resultado de la consulta se encuentra válida en la caché, la consulta se omitirá y el resultado se servirá de la caché en su lugar. Si no especificar el parámetro `$duration`, el valor [[yii\db\Connection::queryCacheDuration|queryCacheDuration]] será usado en su lugar.

A veces dentro de `cache()`, puedes querer desactivar el cacheo de consultas para algunas consultas especificas. Puedes usar [[yii\db\Connection::noCache()]] en este caso.

```php
$result = $db->cache(function ($db) {

    // consultas SQL que usan el cacheo de consultas

    $db->noCache(function ($db) {

        // consultas SQL que no usan el cacheo de consultas

    });

    // ...

    return $result;
});
```

Si lo deseas puedes usar el cacheo de consultas para una simple consulta, puedes llamar a [[yii\db\Command::cache()]] cuando construyas el comando. Por ejemplo,

```php
// usa el cacheo de consultas y asigna la duración de la consulta de caché por 60 segundos
$customer = $db->createCommand('SELECT * FROM customer WHERE id=1')->cache(60)->queryOne();
```

También puedes usar [[yii\db\Command::noCache()]] para desactivar el cacheo de consultas de un simple comando. Por ejemplo,

```php
$result = $db->cache(function ($db) {

    // consultas SQL que usan cacheo de consultas

    // no usa cacheo de consultas para este comando
    $customer = $db->createCommand('SELECT * FROM customer WHERE id=1')->noCache()->queryOne();

    // ...

    return $result;
});
```


### Limitaciones <span id="query-caching-limitations"></span>

El almacenamiento en caché de consultas no funciona con los resultados de consulta que contienen controladores de recursos.
Por ejemplo, cuando se utiliza el tipo de columna `BLOB` en algunos DBMS, el resultado de la consulta devolverá un recurso para manejar los datos de la columna.

Algunos sistemas de almacenamiento caché tienen limitación de tamaño. Por ejemplo, memcache limita el tamaño máximo de cada entrada a 1MB. Por lo tanto, si el tamaño de un resultado de la consulta excede ese límite, el almacenamiento en caché fallará.

---

### Guide Es Caching Fragment (`docs/guide-es/caching-fragment.md`)

Caché de Fragmentos
===================

La Caché de Fragmentos se refiere al almacenamiento en caché de un fragmento, o sección, de una página Web. Por ejemplo, si
una página muestra un sumario de las ventas anuales en una tabla, podrías guardar esta tabla en memoria caché para
eliminar el tiempo necesario para generar esta tabla en cada petición (request). La caché de fragmentos está construido
sobre la [caché de datos](caching-data.md).

Para usar la caché de fragmentos, utiliza el siguiente código en tu [vista (view)](structure-views.md):


```php
if ($this->beginCache($id)) {

    // ... generar contenido aquí ...

    $this->endCache();
}
```

Es decir, encierra la lógica de la generación del contenido entre las llamadas [[yii\base\View::beginCache()|beginCache()]] y
[[yii\base\View::endCache()|endCache()]]. Si el contenido se encuentra en la memoria caché, [[yii\base\View::beginCache()|beginCache()]]
mostrará el contenido y devolverá `false`, saltandose así la lógica de generación del contenido. De lo contrario, el
código de generación se ejecutaría y al alcanzar la llamada [[yii\base\View::endCache()|endCache()]], el contenido
generado será capturado y almacenado en la memoria caché.

Como en la [caché de datos](caching-data.md), un `$id` (clave) único es necesario para identificar un contenido guardado en
caché.


## Opciones de Caché <span id="caching-options"></span>

Puedes especificar opciones adicionales para la caché de fragmentos pasando el array de opciones como segundo
parametro del método [[yii\base\View::beginCache()|beginCache()]]. Entre bastidores, este array de opciones se utiliza
para configurar el widget [[yii\widgets\FragmentCache]] que es en realidad el que implementa la funcionalidad de la caché
de fragmentos.

### Duración <span id="duration"></span>

Quizás la opción más utilizada en la caché de fragmentos es [[yii\widgets\FragmentCache::duration|duración]]. Ésta
especifica cuántos segundos el contenido puede permanecer como válido en la memoria caché. El siguiente código almacena
en la caché el fragmento de contenido para una hora a lo sumo:

```php
if ($this->beginCache($id, ['duration' => 3600])) {

    // ... generar contenido aquí ...

    $this->endCache();
}
```

Si la opción no está activada, se tomará el valor por defecto 60, lo que significa que el contenido almacenado en caché expirará en 60 segundos.


### Dependencias <span id="dependencies"></span>

Como en la [caché de datos](caching-data.md#cache-dependencies), el fragmento de contenido que está siendo almacenado en caché
también puede tener dependencias. Por ejemplo, el contenido de un artículo que se muestre depende de si el mensaje se
modifica o no.

Para especificar una dependencia, activa la opción [[yii\widgets\FragmentCache::dependency|dependencia]] (dependency),
que puede ser un objecto [[yii\caching\Dependency]] o un array de configuración para crear un objecto `Dependency`. El
siguiente código especifica que la caché de fragmento depende del cambio del valor de la columna `updated_at`:

```php
$dependency = [
    'class' => 'yii\caching\DbDependency',
    'sql' => 'SELECT MAX(updated_at) FROM post',
];

if ($this->beginCache($id, ['dependency' => $dependency])) {

    // ... generar contenido aquí ...

    $this->endCache();
}
```


### Variaciones <span id="variations"></span>

El contenido almacenado en caché puede variar de acuerdo a ciertos parámetros. Por ejemplo, para una aplicación Web que
soporte multiples idiomas, la misma pieza del código de la vista puede generar el contenido almacenado en caché
en diferentes idiomas. Por lo tanto, es posible que desees hacer variaciones del mismo contenido almacenado en caché de
acuerdo con la actual selección del idioma en la aplicación.

Para especificar variaciones en la memoria caché, configura la opción [[yii\widgets\FragmentCache::variations|variaciones]]
(variations), la cual deberá ser un array de valores escalares, cada uno de ellos representando un factor de variación.
Por ejemplo, para hacer que el contenido almacenado en la caché varíe por lenguaje, podrías usar el siguiente código:

```php
if ($this->beginCache($id, ['variations' => [Yii::$app->language]])) {

    // ... generar código aquí ...

    $this->endCache();
}
```


### Alternando el Almacenamiento en Caché <span id="toggling-caching"></span>

Puede que a veces quieras habilitar la caché de fragmentos únicamente cuando ciertas condiciones se cumplan. Por ejemplo,
para una página que muestra un formulario, tal vez quieras guardarlo en la caché cuando es inicialmente solicitado (a
través de una petición GET). Cualquier muestra posterior (a través de una petición POST) del formulario no debería ser
almacenada en caché ya que el formulario puede que contenga entradas del usuario. Para hacerlo, podrías configurar la
opción de [[yii\widgets\FragmentCache::enabled|activado]] (enabled), de la siguiente manera:

```php
if ($this->beginCache($id, ['enabled' => Yii::$app->request->isGet])) {

    // ... generar contenido aquí ...

    $this->endCache();
}
```


## Almacenamiento en Caché Anidada <span id="nested-caching"></span>

El almacenamiento en caché de fragmentos se puede anidar. Es decir, un fragmento de caché puede ser encerrado dentro de
otro fragmento que también se almacena en caché. Por ejemplo, los comentarios se almacenan en una caché de fragmento
interno, y se almacenan conjuntamente con el contenido del artículo en un fragmento de caché exterior. El siguiente
código muestra cómo dos fragmentos de caché pueden ser anidados:

```php
if ($this->beginCache($id1)) {

    // ... lógica de generación de contenido externa ...

    if ($this->beginCache($id2, $options2)) {

        // ... lógica de generación de contenido anidada ...

        $this->endCache();
    }

    // ... lógica de generación de contenido externa ...

    $this->endCache();
}
```

Existen diferentes opciones de configuración para las cachés anidadas. Por ejemplo, las cachés internas y las cachés
externas pueden usar diferentes valores de duración. Aún cuando los datos almacenados en la caché externa sean invalidados,
la caché interna puede todavía proporcionar un fragmento válido. Sin embargo, al revés no es cierto. Si la caché externa
es evaluada como válida, seguiría proporcionando la misma copia en caché incluso después de que el contenido  en la
caché interna haya sido invalidada. Por lo tanto, hay que tener mucho cuidado al configurar el tiempo de duración o las
dependencias de las cachés anidadas, de lo contrario los fragmentos internos que ya estén obsoletos se pueden seguir
manteniendo en el fragmento externo.


## Contenido Dinámico <span id="dynamic-content"></span>

Cuando se usa la caché de fragmentos, podrías encontrarte en la situación que un fragmento grande de contenido es
relavitamente estático excepto en uno u otro lugar. Por ejemplo, la cabeza de una página (header) puede que muestre el
menú principal junto al nombre del usuario actual. Otro problema es que el contenido que está siendo almacenado en caché
puede que contenga código PHP que debe ser ejecutado en cada petición (por ejemplo, el código para registrar
un paquete de recursos (asset bundle)). En ambos casos, podríamos resolver el problema con lo que llamamos la
característica de *contenido dinámico*.

Entendemos *contenido dinámico* como un fragmento de salida que no debería ser guardado en caché incluso si está
encerrado dentro de un fragmento de caché. Para hacer el contenido dinámico todo el tiempo, éste ha de ser generado ejecutando
cierto código PHP en cada petición, incluso si el contenido está siendo mostrado desde la caché.

Puedes llamar a [[yii\base\View::renderDynamic()]] dentro de un fragmento almacenado en caché para insertar código
dinámico en el lugar deseado como, por ejemplo, de la siguiente manera,

```php
if ($this->beginCache($id1)) {

    // ... lógica de generación de contenido ...

    echo $this->renderDynamic('return Yii::$app->user->identity->name;');

    // ... lógica de generación de contenido ...

    $this->endCache();
}
```

El método [[yii\base\View::renderDynamic()|renderDynamic()]] toma una pieza de código PHP como su parámetro. El valor
devuelto del código PHP se trata como contenido dinámico. El mismo código PHP será ejecutado en cada petición,
sin importar que esté dentro de un fragmento que está siendo servido desde la caché o no.

---

### Guide Es Caching Http (`docs/guide-es/caching-http.md`)

Caché HTTP
==========

Además del almacenamiento de caché en el servidor que hemos descrito en secciones anteriores, las aplicaciones Web
pueden hacer uso de la caché en el lado del cliente para así ahorrar tiempo y recursos para generar y transmitir el
mismo contenido una y otra vez.

Para usar la caché del lado del cliente, puedes configurar [[yii\filters\HttpCache]] como un filtro en el controlador
para aquellas acciones cuyo resultado deba estar almacenado en la caché en el lado del cliente. [[yii\filters\HttpCache|HttpCache]]
solo funciona en peticiones `GET` y `HEAD`. Puede manejar tres tipos de cabeceras (headers) HTTP relacionadas en este tipo de
consultas:

* [[yii\filters\HttpCache::lastModified|Last-Modified]]
* [[yii\filters\HttpCache::etagSeed|Etag]]
* [[yii\filters\HttpCache::cacheControlHeader|Cache-Control]]


## La Cabecera `Last-Modified` <span id="last-modified"></span>

La cabecera `Last-Modified` usa un sello de tiempo para indicar si la página ha sido modificada desde que el cliente la
almacena en la caché.

Puedes configurar la propiedad [[yii\filters\HttpCache::lastModified]] para activar el envío de la cabecera `Last-Modified`.
La propiedad debe ser una llamada de retorno (callable) PHP que devuelva un timestamp UNIX sobre el tiempo de modificación de
la página. El formato de la función de llamada de retorno debe ser el siguiente,

```php
/**
 * @param Action $action el objeto acción que se está controlando actualmente
 * @param array $params el valor de la propiedad "params"
 * @return int un sello de tiempo UNIX que representa el tiempo de modificación de la página
 */
function ($action, $params)
```

El siguiente es un ejemplo haciendo uso de la cabecera `Last-Modified`:

```php
public function behaviors()
{
    return [
        [
            'class' => 'yii\filters\HttpCache',
            'only' => ['index'],
            'lastModified' => function ($action, $params) {
                $q = new \yii\db\Query();
                return $q->from('post')->max('updated_at');
            },
        ],
    ];
}
```

El código anterior establece que la memoria caché HTTP debe ser habilitada únicamente por la acción `index`. Se debe
generar una cabecera HTTP `Last-Modified` basado en el último tiempo de actualización de los artículos. Cuando un
navegador visita la página `index` la primera vez, la página será generada en el servidor y enviada al navegador; Si el
navegador visita la misma página de nuevo y no ningún artículo modificado durante el período, el servidor no volverá a
regenerar la página, y el navegador usará la versión caché del lado del cliente. Como resultado, la representación del
lado del servidor y la transmisión del contenido de la página son ambos omitidos.


## La Cabecera `ETag` <span id="etag"></span>

La cabecera "Entity Tag" (o para abreviar `ETag`) usa un hash para representar el contenido de una página. Si la página
ha sido cambiada, el hash también cambiará. Al comparar el hash guardado en el lado del cliente con el hash generado en
el servidor, la caché puede determinar si la página ha cambiado y deber ser retransmitida.

Puedes configurar la propiedad [[yii\filters\HttpCache::etagSeed]] para activar el envío de la cabecera `ETag`.
La propiedad debe ser una función de retorno (callable) PHP que devuelva una semilla para la generación del hash de `ETag`.
El formato de la función de retorno es el siguiente:

```php
/**
 * @param Action $action el objeto acción que se está controlando actualmente
 * @param array $params el valor de la propiedad "params"
 * @return string una cadena usada como semilla para la generación del hash de ETag
 */
function ($action, $params)
```

El siguiente es un ejemplo de cómo usar la cabecera `ETag`:

```php
public function behaviors()
{
    return [
        [
            'class' => 'yii\filters\HttpCache',
            'only' => ['view'],
            'etagSeed' => function ($action, $params) {
                $post = $this->findModel(\Yii::$app->request->get('id'));
                return serialize([$post->title, $post->content]);
            },
        ],
    ];
}
```

El código anterior establece que la caché HTTP debe ser activada únicamente para la acción `view`. Debería generar una
cabecera HTTP `ETag` basándose en el título y contenido del artículo consultado. Cuando un navegador visita la página
`view` por primera vez, la página se generará en el servidor y será enviada al navegador; Si el navegador visita la
misma página de nuevo y no ha ocurrido un cambio en el título o contenido del artículo, el servidor no volverá a generar
la página, y el navegador usará la versión guardada en la caché del lado del cliente. Como resultado, la representación del
lado del servidor y la transmisión del contenido de la página son ambos omitidos.

ETags permiten estrategias de almacenamiento de caché más complejas y/o mucho más precisas que las cabeceras `Last-Modified`.
Por ejemplo, un ETag puede ser invalidado si el sitio Web ha cambiado de tema (theme).

La generación de un ETag que requiera muchos recursos puede echar por tierra el propósito de estar usando `HttpCache` e
introducir una sobrecarga innecesaria, ya que debe ser re-evaluada en cada solicitud (request). Trata de encontrar una
expresión sencilla para invalidar la caché si la página ha sido modificada.

> Note: En cumplimiento con [RFC 7232](https://datatracker.ietf.org/doc/html/rfc7232#section-2.4),
  `HttpCache` enviará ambas cabeceras `ETag` y `Last-Modified` si ambas están configuradas. Y si el clientes envía tanto la cabecera `If-None-Match` como la cabecera `If-Modified-Since`, solo la primera será respetada.

## La Cabecera `Cache-Control` <span id="cache-control"></span>

La cabecera `Cache-Control` especifica la directiva general de la caché para páginas. Puedes enviarla configurando la
propiedad [[yii\filters\HttpCache::cacheControlHeader]] con el valor de la cabecera. Por defecto, la siguiente cabecera
será enviada:

```
Cache-Control: public, max-age=3600
```

## Limitador de la Sesión de Caché <span id="session-cache-limiter"></span>

Cuando una página utiliza la sesión, PHP enviará automáticamente cabeceras HTTP relacionadas con la caché tal y como se
especifican en `session.cache_limiter` de la configuración INI de PHP. Estas cabeceras pueden interferir o deshabilitar
el almacenamiento de caché que desees de `HttpCache`. Para evitar este problema, por defecto `HttpCache` deshabilitará
automáticamente el envío de estas cabeceras. Si deseas modificar este comportamiento, tienes que configurar la propiedad
[[yii\filters\HttpCache::sessionCacheLimiter]]. La propiedad puede tomar un valor de cadena, incluyendo `public`, `private`,
`private_no_expire`, and `nocache`. Por favor, consulta el manual PHP acerca de [session_cache_limiter()](https://www.php.net/manual/es/function.session-cache-limiter.php)
para una mejor explicación sobre esos valores.


## Implicaciones SEO <span id="seo-implications"></span>

Los robots de motores de búsqueda tienden a respetar las cabeceras de caché. Dado que algunos `crawlers` tienen limitado
el número de páginas que pueden rastrear por dominios dentro de un cierto período de tiempo, la introducción de cabeceras
de caché pueden ayudar a la indexación del sitio Web y reducir el número de páginas que deben ser procesadas.

---

### Guide Es Caching Page (`docs/guide-es/caching-page.md`)

Caché de Páginas
================

La caché de páginas se refiere a guardar el contenido de toda una página en el almacenamiento de caché del servidor.
Posteriormente, cuando la misma página sea requerida de nuevo, su contenido será devuelto desde la caché en vez de
volver a generarlo desde cero.

El almacenamiento en caché de páginas está soportado por [[yii\filters\PageCache]], un [filtro de acción](structure-filters.md).
Puede ser utilizado de la siguiente forma en un controlador:

```php
public function behaviors()
{
    return [
        [
            'class' => 'yii\filters\PageCache',
            'only' => ['index'],
            'duration' => 60,
            'variations' => [
                \Yii::$app->language,
            ],
            'dependency' => [
                'class' => 'yii\caching\DbDependency',
                'sql' => 'SELECT COUNT(*) FROM post',
            ],
        ],
    ];
}
```

El código anterior establece que el almacenamiento de páginas en caché debe ser utilizado sólo en la acción `index`; el
contenido de la página debería almacenarse durante un máximo de 60 segundos y ser variado por el idioma actual de la
aplicación; además, el almacenamiento de la página en caché debería ser invalidado si el número total de
artículos ha cambiado.

Como puedes ver, la caché de páginas es muy similar a la [caché de fragmentos](caching-fragment.md). Ambos soportan opciones
tales como `duration`, `dependencies`, `variations`, y `enabled`. Su principal diferencia es que la caché de páginas está
implementado como un [filtro de acción](structure-filters.md) mientras que la caché de fragmentos se hace en un [widget](structure-widgets.md).

Puedes usar la [caché de fragmentos](caching-fragment.md) así como el [contenido dinámico](caching-fragment.md#dynamic-content)
junto con la caché de páginas.

---

### Guide Es Concept Aliases (`docs/guide-es/concept-aliases.md`)

Alias
=====

Loa alias son utilizados para representar rutas o URLs de manera que no tengas que escribir explícitamente rutas absolutas o URLs en tu
proyecto. Un alias debe comenzar con el signo `@` para ser diferenciado de una ruta normal de archivo y de URLs. Los alias definidos
sin el `@` del principio, serán prefijados con el signo `@`.

Yii trae disponibles varios alias predefinidos. Por ejemplo, el alias `@yii` representa la ruta de instalación del
framework Yii; `@web` representa la URL base para la aplicación Web ejecutándose.

Definir Alias <span id="defining-aliases"></span>
-------------

Para definir un alias puedes llamar a [[Yii::setAlias()]] para una determinada ruta de archivo o URL. Por ejemplo,

```php
// un alias de una ruta de archivos
Yii::setAlias('@foo', '/path/to/foo');

// una alias de un URL
Yii::setAlias('@bar', 'https://www.example.com');
```

> Note: Una ruta de archivo o URL en alias NO debe necesariamente referirse a un archivo o recurso existente.

Dado un alias, puedes derivar un nuevo alias (sin necesidad de llamar [[Yii::setAlias()]]) anexando una barra diagonal `/`
seguida por uno o varios segmentos de la ruta. Llamamos los alias definidos a través de [[Yii::setAlias()]]
*alias de raíz* (root alias), mientras que los alias derivados de ellos *alias derivados* (derived aliases). Por ejemplo,
`@foo` es un alias de raíz, mientras que `@foo/bar/file.php` es un alias derivado.

Puedes definir un alias usando otro alias (ya sea un alias de raíz o derivado):

```php
Yii::setAlias('@foobar', '@foo/bar');
```

Los alias de raíz están usualmente definidos durante la etapa [bootstrapping](runtime-bootstrapping.md) de la aplicación.
Por ejemplo, puedes llamar a [[Yii::setAlias()]] en el [script de entrada](structure-entry-scripts.md).
Por conveniencia, [Application](structure-applications.md) provee una propiedad modificable llamada `aliases` que puedes
configurar en la [configuración](concept-configurations.md) de la aplicación, como por ejemplo,

```php
return [
    // ...
    'aliases' => [
        '@foo' => '/path/to/foo',
        '@bar' => 'https://www.example.com',
    ],
];
```


Resolución de Alias <span id="resolving-aliases"></span>
-------------------

Puedes llamar [[Yii::getAlias()]] para resolver un alias de raíz en la ruta o URL que representa. El mismo método puede
además resolver un alias derivado en su correspondiente ruta de archivo o URL. Por ejemplo,

```php
echo Yii::getAlias('@foo');               // muestra: /path/to/foo
echo Yii::getAlias('@bar');               // muestra: https://www.example.com
echo Yii::getAlias('@foo/bar/file.php');  // muestra: /path/to/foo/bar/file.php
```

La ruta de archivo/URL representado por un alias derivado está determinado por la sustitución de la parte de su alias raíz
con su correspondiente ruta/Url en el alias derivado.

> Note: El método [[Yii::getAlias()]] no comprueba si la ruta/URL resultante hacer referencia a un archivo o recurso existente.


Un alias de raíz puede contener carácteres `/`. El método [[Yii::getAlias()]] es lo suficientemente inteligente para saber
qué parte de un alias es un alias de raíz y por lo tanto determinar correctamente la correspondiente ruta de archivo o URL.
Por ejemplo,

```php
Yii::setAlias('@foo', '/path/to/foo');
Yii::setAlias('@foo/bar', '/path2/bar');
Yii::getAlias('@foo/test/file.php');  // muestra: /path/to/foo/test/file.php
Yii::getAlias('@foo/bar/file.php');   // muestra: /path2/bar/file.php
```

Si `@foo/bar` no está definido como un alias de raíz, la última declaración mostraría `/path/to/foo/bar/file.php`.


Usando Alias <span id="using-aliases"></span>
------------

Los alias son utilizados en muchos lugares en Yii sin necesidad de llamar [[Yii::getAlias()]] para convertirlos
en rutas/URLs. Por ejemplo, [[yii\caching\FileCache::cachePath]] puede aceptar tanto una ruta de archivo como un alias
que represente la ruta de archivo, gracias al prefijo `@` el cual permite diferenciar una ruta de archivo
de un alias.

```php
use yii\caching\FileCache;

$cache = new FileCache([
    'cachePath' => '@runtime/cache',
]);
```

Por favor, presta atención a la documentación API para ver si una propiedad o el parámetro de un método soporta alias.


Alias Predefinidos <span id="predefined-aliases"></span>
------------------

Yii predefine un conjunto de alias para aliviar la necesidad de hacer referencia a rutas de archivo o URLs que son
utilizadas regularmente. La siguiente es la lista de alias predefinidos por Yii:

- `@yii`: el directorio donde el archivo `BaseYii.php` se encuentra (también llamado el directorio del framework).
- `@app`: la [[yii\base\Application::basePath|ruta base]] de la aplicación que se está ejecutando actualmente.
- `@runtime`: la [[yii\base\Application::runtimePath|ruta de ejecución]] de la aplicación en ejecución. Por defecto `@app/runtime`.
- `@webroot`: el directorio raíz Web de la aplicación Web se está ejecutando actualmente.
- `@web`: la URL base de la aplicación web se ejecuta actualmente. Tiene el mismo valor que [[yii\web\Request::baseUrl]].
- `@vendor`: el [[yii\base\Application::vendorPath|directorio vendor de Composer]]. Por defecto `@app/vendor`.
- `@bower`, el directorio raíz que contiene [paquetes bower](https://bower.io/). Por defecto `@vendor/bower`.
- `@npm`, el directorio raíz que contiene [paquetes npm](https://www.npmjs.com/). Por defecto `@vendor/npm`.

El alias `@yii` se define cuando incluyes el archivo `Yii.php` en tu [script de entrada](structure-entry-scripts.md),
mientras que el resto de los alias están definidos en el constructor de la aplicación cuando se aplica la
[configuración](concept-configurations.md) de la aplicación.


Alias en Extensiones <span id="extension-aliases"></span>
--------------------

Un alias se define automáticamente por cada [extensión](structure-extensions.md) que ha sido instalada a través de Composer.
El alias es nombrado tras el `namespace` de raíz de la extensión instalada tal y como está declarada en su archivo `composer.json`,
y representa el directorio raíz de la extensión. Por ejemplo, si instalas la extensión `yiisoft/yii2-jui`, tendrás
automáticamente definido el alias `@yii/jui` durante la etapa [bootstrapping](runtime-bootstrapping.md) de la aplicación:

```php
Yii::setAlias('@yii/jui', 'VendorPath/yiisoft/yii2-jui');
```

---

### Guide Es Concept Autoloading (`docs/guide-es/concept-autoloading.md`)

Autocarga de clases
===================

Yii depende del [mecanismo de autocarga de clases](https://www.php.net/manual/es/language.oop5.autoload.php) para localizar
e incluir los archivos de las clases requiridas. Proporciona un cargador de clases de alto rendimiento que cumple con el
[estandard PSR-4](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader.md).
El cargador se instala cuando incluyes el archivo `Yii.php`.

> Note: Para simplificar la descripción, en esta sección sólo hablaremos de la carga automática de clases. Sin embargo,
  ten en cuenta que el contenido que describimos aquí también se aplica a la autocarga de interfaces y rasgos (Traits).


Usando el Autocargador de Yii <span id="using-yii-autoloader"></span>
-----------------------------

Para utilizar el cargador automático de clases de Yii, deberías seguir dos reglas básicas cuando desarrolles y nombres tus
clases:

* Cada clase debe estar bajo un espacio de nombre (namespace). Por ejemplo `foo\bar\MyClass`.
* Cada clase debe estar guardada en un archivo individual cuya ruta está determinada por el siguiente algoritmo:

```php
// $className es un nombre completo de clase con las iniciales barras invertidas.
$classFile = Yii::getAlias('@' . str_replace('\\', '/', $className) . '.php');
```

Por ejemplo, si el nombre de una clase es `foo\bar\MyClass`, el [alias](concept-aliases.md) la correspondiente ruta de
archivo de la clase sería `@foo/bar/MyClass.php`. Para que este sea capaz de ser resuelto como una ruta de archivo, ya sea
`@foo` o `@foo/bar` debe ser un [alias de raíz](concept-aliases.md#defining-aliases) (root alias).

Cuando utilizas la [Plantilla de Aplicación Básica](start-installation.md), puede que pongas tus clases bajo el nivel superior
de espacio de nombres `app` para que de esta manera pueda ser automáticamente cargado por Yii sin tener la necesidad de
definir un nuevo alias. Esto es porque `@app` es un [alias predefinido](concept-aliases.md#predefined-aliases), y el
nombre de una clase tal como `app\components\MyClass` puede ser resuelto en el archivo de la clase `AppBasePath/components/MyClass.php`,
de acuerdo con el algoritmo previamente descrito.

En la [Plantilla de Aplicación Avanzada](tutorial-advanced-app.md), cada nivel tiene su propio alias. Por ejemplo, el nivel
`front-end` tiene un alias de raíz `@frontend` mientras que el nivel `back-end` tiene `@backend`. Como resultado, es posible
poner las clases `front-end` bajo el espacio de nombres `frontend` mientras que las clases `back-end` pueden hacerlo bajo
`backend`. Esto permitirá que estas clases sean automaticamente cargadas por el autocargador de Yii.


Mapa de Clases <span id="class-map"></span>
--------------

El autocargador de clases de Yii soporta el *mapa de clases*, que mapea nombres de clases to sus correpondientes rutas de
archvios. Cuando el autocargador esta cargando una clase, primero chequeará si la clase se encuentra en el mapa. Si es así,
el correspondiente archivo será incluido directamente sin más comprobación. Esto hace que la clase se cargue muy rápidamente.
De hecho, todas las clases de Yii son autocargadas de esta manera.

Puedes añadir una clase al mapa de clases `Yii::$classMap` de la siguiente forma,

```php
Yii::$classMap['foo\bar\MyClass'] = 'path/to/MyClass.php';
```

[Alias](concept-aliases.md) puede ser usado para especificar la ruta de archivos de clases. Deberías iniciar el mapeo de
clases en el proceso [bootstrapping](runtime-bootstrapping.md) de la aplicación para que de esta manera el mapa esté listo
antes de que tus clases sean usadas.


Usando otros Autocargadores <span id="using-other-autoloaders"></span>
---------------------------

Debido a que Yii incluye Composer como un gestor de dependencias y extensions, es recomendado que también instales el
autocargador de Composer. Si estás usando alguna librería externa que requiere sus autocargadores, también deberías
instalarlos.

Cuando se utiliza el cargador de clases automático de Yii conjuntamente con otros autocargadores, deberías incluir el
archivo `Yii.php` *después* de que todos los demás autocargadores se hayan instalado. Esto hará que el autocargador de
Yii sea el primero en responder a cualquier petición de carga automática de clases. Por ejemplo, el siguiente código ha
sido extraido del [script de entrada](structure-entry-scripts.md) de la [Plantilla de Aplicación Básica](start-installation.md).
La primera línea instala el autocargador de Composer, mientras que la segunda línea instala el autocargador de Yii.

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

Puedes usar el autocargador de Composer sin el autocargador de Yii. Sin embargo, al hacerlo, la eficacia de la carga de
tus clases puede que se degrade, y además deberías seguir las reglas establecidas por Composer para que tus clases pudieran
ser autocargables.

> Note: Si no deseas utilizar el autocargador de Yii, tendrás que crear tu propia versión del archivo `Yii.php` e
  incluirlo en tu [script de entrada](structure-entry-scripts.md).


Carga Automática de Clases de Extensiones <span id="autoloading-extension-classes"></span>
-----------------------------------------

El autocargador de Yii es capaz de autocargar clases de [extensiones](structure-extensions.md). El único requirimiento es
que la extensión especifique correctamente la sección de `autoload` (autocarga) en su archivo `composer.json`. Por favor,
consulta la [documentación de Composer](https://getcomposer.org/doc/04-schema.md#autoload) para más detalles acerca de la
especificación `autoload`.

En el caso de que no quieras usar el autocargador de Yii, el autocargador de Composer podría cargar las clases de extensiones
por tí.

---

### Guide Es Concept Behaviors (`docs/guide-es/concept-behaviors.md`)

Comportamientos
===============

Comportamientos son instancias de [[yii\base\Behavior]] o sus clases "hija". Comportamientos, también conocido como
[mixins](https://es.wikipedia.org/wiki/Mixin), te permiten mejorar la funcionalidad de un [[yii\base\Component|componente]]
existente sin necesidad de modificar su herencia de clases.
Cuando un comportamiento se une a un componente, "inyectará" sus métodos y propiedades dentro del componente, y podrás
acceder a esos métodos y propiedades como si hubieran estado definidos por la clase de componente. Además, un
comportamiento puede responder a [eventos](concept-events.md) disparados por el componente de modo que se pueda personalizar
o adaptar a la ejecución normal del código del componente.


Definiendo comportamientos <span id="defining-behaviors"></span>
--------------------------

Para definir un comportamiento, se debe crear una clase que exiende [[yii\base\Behavior]], o se extiende una clase hija. Por ejemplo:

```php
namespace app\components;

use yii\base\Behavior;

class MyBehavior extends Behavior
{
    public $prop1;

    private $_prop2;

    public function getProp2()
    {
        return $this->_prop2;
    }

    public function setProp2($value)
    {
        $this->_prop2 = $value;
    }

    public function foo()
    {
        // ...
    }
}
```
El código anterior define la clase de comportamiento (behavior) app\components\MyBehavior`, con dos propiedades --
`prop1` y `prop2`--y un método `foo()`. Tenga en cuenta que la propiedad `prop2`
se define a través de la getter `getProp2()` y el setter `setProp2()`. Este caso es porque [[yii\base\Behavior]] extiende [[yii\base\BaseObject]] y por lo tanto se apoya en la definición de [propiedades](concept-properties.md) via getters y setters.

Debido a que esta clase es un comportamiento, cuando está unido a un componente, el componente también tienen la propiedad `prop1` y `prop2` y el método `foo()`.

> Tip: Dentro de un comportamiento, puede acceder al componente que el comportamiento está unido a través de la propiedad [[yii\base\Behavior::owner]].


Gestión de eventos de componentes
---------------------------------

Si un comportamiento necesita responder a los acontecimientos desencadenados por el componente al que está unido, se debe reemplazar el método [[yii\base\Behavior::events()]]. Por ejemplo:

```php
namespace app\components;

use yii\db\ActiveRecord;
use yii\base\Behavior;

class MyBehavior extends Behavior
{
    // ...

    public function events()
    {
        return [
            ActiveRecord::EVENT_BEFORE_VALIDATE => 'beforeValidate',
        ];
    }

    public function beforeValidate($event)
    {
        // ...
    }
}
```

El método [[yii\base\Behavior::events()|events()]] debe devolver una lista de eventos y sus correspondientes controladores.
El ejemplo anterior declara que el evento [[yii\db\ActiveRecord::EVENT_BEFORE_VALIDATE|EVENT_BEFORE_VALIDATE]] existe y esta  exists y define su controlador, `beforeValidate()`. Al especificar un controlador de eventos, puede utilizar uno de los siguientes formatos:

* una cadena que se refiere al nombre de un método de la clase del comportamiento, como el ejemplo anterior
* un arreglo de objeto o nombre de clase, y un nombre de método como una cadena (sin paréntesis), ej., `[$object, 'methodName']`;
* una función anónima 

La firma de un controlador de eventos debe ser la siguiente, donde `$ event` refiere al parámetro de evento. Por favor, consulte la sección [Eventos](concept-events.md) para más detalles sobre los eventos.

```php
function ($event) {
}
```


Vinculando Comportamientos <span id="attaching-behaviors"></span>
--------------------------

Puedes vincular un comportamiento a un [[yii\base\Component|componente]] ya sea estática o dinámicamente. La primera forma
es la más comúnmente utilizada en la práctica.

Para unir un comportamiento estáticamente, reemplaza el método [[yii\base\Component::behaviors()|behaviors()]] dde la clase de componente a la que se une el comportamiento. El método [[yii\base\Component::behaviors()|behaviors()]]  debe devolver una lista de comportamiento [configuraciones](concept-configurations.md).
Cada configuración de comportamiento puede ser un nombre de clase de comportamiento o un arreglo de configuración:

```php
namespace app\models;

use yii\db\ActiveRecord;
use app\components\MyBehavior;

class User extends ActiveRecord
{
    public function behaviors()
    {
        return [
            // anonymous behavior, behavior class name only
            MyBehavior::class,

            // named behavior, behavior class name only
            'myBehavior2' => MyBehavior::class,

            // anonymous behavior, configuration array
            [
                'class' => MyBehavior::class,
                'prop1' => 'value1',
                'prop2' => 'value2',
            ],

            // named behavior, configuration array
            'myBehavior4' => [
                'class' => MyBehavior::class,
                'prop1' => 'value1',
                'prop2' => 'value2',
            ]
        ];
    }
}
```

Puedes asociciar un nombre a un comportamiento especificándolo en la clave de la matriz correspondiente a la configuración
del comportamiento. En este caso, el comportamiento puede ser llamado un *comportamiento nombrado* (named behavior). En
el ejemplo anterior, hay dos tipos de comportamientos nombrados: `myBehavior2` y `myBehavior4`. Si un comportamiento
no está asociado con un nombre, se le llama *comportamiento anónimo* (anonymous behavior).

Para vincular un comportamiento dinámicamente, llama al método [[yii\base\Component::attachBehavior()]] desde el componente al
que se le va a unir el comportamiento:

```php
use app\components\MyBehavior;

// vincular un objeto comportamiento "behavior"
$component->attachBehavior('myBehavior1', new MyBehavior());

// vincular una clase comportamiento
$component->attachBehavior('myBehavior2', MyBehavior::class);

// asociar una matriz de configuración
$component->attachBehavior('myBehavior3', [
    'class' => MyBehavior::class,
    'prop1' => 'value1',
    'prop2' => 'value2',
]);
```
Puede vincular múltiples comportamientos a la vez mediante el uso del método [[yii\base\Component::attachBehaviors()]]. Por ejemplo,

```php
$component->attachBehaviors([
    'myBehavior1' => new MyBehavior(), // un comportamiento nombrado
    MyBehavior::class,                 // un comportamiento anónimo
]);
```

También puedes asociar comportamientos a traves de [configuraciones](concept-configurations.md) como el siguiente:

```php
[
    'as myBehavior2' => MyBehavior::class,

    'as myBehavior3' => [
        'class' => MyBehavior::class,
        'prop1' => 'value1',
        'prop2' => 'value2',
    ],
]
```

Para más detalles, por favor visita la sección [Configuraciones](concept-configurations.md#configuration-format).


Usando comportamientos <span id="using-behaviors"></span>
----------------------

Para poder utilizar un comportamiento, primero tienes que unirlo a un [[yii\base\Component|componente]] según las instrucciones anteriores. Una vez que un comportamiento ha sido vinculado a un componente, su uso es sencillo.

Puedes usar a una variable *pública* o a una [propiedad](concept-properties.md) definida por un `getter` y/o un `setter`
del comportamiento a través del componente con el que se ha vinculado:

```php
// "prop1" es una propiedad definida en la clase comportamiento
echo $component->prop1;
$component->prop1 = $value;
```

También puedes llamar métodos *públicos* del comportamiento de una forma similar:

```php
// foo() es un método público definido dentro de la clase comportamiento
$component->foo();
```

Como puedes ver, aunque `$component` no tiene definida `prop1` y `bar()`, que se pueden utilizar como si son parte
de la definición de componentes debido al comportamiento vinculado.

Si dos comportamientos definen la misma propiedad o método y ambos están vinculados con el mismo componente, el
comportamiento que ha sido vinculado *primero* tendrá preferencia cuando se esté accediendo a la propiedad o método.

Un comportamiento puede estar asociado con un nombre cuando se une a un componente. Si este es el caso, es posible
acceder al objeto de comportamiento mediante el nombre, como se muestra a continuación,

```php
$behavior = $component->getBehavior('myBehavior');
```

También puedes acceder a todos los comportamientos vinculados al componente:

```php
$behaviors = $component->getBehaviors();
```


Desasociar Comportamientos <span id="detaching-behaviors"></span>
--------------------------

Para desasociar un comportamiento, puedes llamar el método [[yii\base\Component::detachBehavior()]] con el nombre con el
que se le asoció:

```php
$component->detachBehavior('myBehavior1');
```

También puedes desvincular *todos* los comportamientos:

```php
$component->detachBehaviors();
```


Utilizando `TimestampBehavior` <span id="using-timestamp-behavior"></span>
-----------------------------

Para terminar, vamos a echar un vistazo a [[yii\behaviors\TimestampBehavior]]. Este comportamiento soporta de forma
automática la actualización de atributos timestamp de un modelo [[yii\db\ActiveRecord|Registro Activo]]
(Active Record) en cualquier momento donde se guarda el modelo (ej., en la inserción o actualización).

Primero, vincula este comportamiento a la clase [[yii\db\ActiveRecord|Active Record]] que desees utilizar.

```php
namespace app\models\User;

use yii\db\ActiveRecord;
use yii\behaviors\TimestampBehavior;

class User extends ActiveRecord
{
    // ...

    public function behaviors()
    {
        return [
            [
                'class' => TimestampBehavior::class,
                'attributes' => [
                    ActiveRecord::EVENT_BEFORE_INSERT => ['created_at', 'updated_at'],
                    ActiveRecord::EVENT_BEFORE_UPDATE => ['updated_at'],
                ],
            ],
        ];
    }
}
```

La configuración del comportamiento anterior especifica que

* cuando el registro está siendo insertado, el comportamiento debe asignar el sello de tiempo actual a los atributos
  `created_at` y `updated_at`;
* cuando el registro está siendo actualizado, el comportamiento debe asignar el sello de tiempo actual al atributo
  `updated_at`.

Ahora si tienes un objeto `User` e intentas guardarlo, descubrirás que sus campos `created_at` y `updated_at` están
automáticamente actualizados con el sello de tiempo actual:

```php
$user = new User;
$user->email = 'test@example.com';
$user->save();
echo $user->created_at;  // muestra el sello tiempo actual (timestamp)
```

El comportamiento [[yii\behaviors\TimestampBehavior|TimestampBehavior]] también ofrece un método muy útil llamado
[[yii\behaviors\TimestampBehavior::touch()|touch()]], que asigna el sello de tiempo actual a un atributo especificado y lo guarda automáticamente en la base de datos:

```php
$user->touch('login_time');
```


Comparación con Traits <span id="comparison-with-traits"></span>
----------------------

Mientras que los comportamientos son similares a [traits](https://www.php.net/manual/es/language.oop5.traits.php) en cuanto que ambos "inyectan" sus
métodos  y propiedades a la clase primaria, son diferentes en muchos aspectos. Tal y como se describe abajo, los dos
tienen sus ventajas y desventajas. Son más como complementos el uno al otro en lugar de alternativas.


### Razones para utilizar comportamientos <span id="pros-for-behaviors"></span>

Las clases de comportamientos, como todas las clases, soportan herencias. Traits, por otro lado, pueden ser
considerados como un copia-y-pega de PHP. Ellos no soportan la herencia de clases.

Los comportamientos pueden ser asociados y desasociados a un componente dinámicamente sin necesidad de que la clase del
componente sea modificada. Para usar un trait, debes modificar la clase que la usa.

Los comportamientos son configurables mientras que los traits no.

Los comportamientos pueden personalizar la ejecución de un componente al responder a sus eventos.

Cuando hay un conflicto de nombre entre los diferentes comportamientos vinculados a un mismo componente, el conflicto es
automáticamente resuelto respetando al que ha sido asociado primero.
El conflicto de nombres en traits requiere que manualmente sean resueltos cambiando el nombre de las propiedades o métodos afectados.


### Razones para utilizar los Traits <span id="pros-for-traits"></span>

Los Traits son mucho más eficientes que los comportamientos debido a que los últimos son objetos que consumen tiempo y
memoria.

Los IDEs (Programas de desarrollo) son más amigables con traits ya que son una construcción del lenguaje nativo.

---

### Guide Es Concept Components (`docs/guide-es/concept-components.md`)

Componentes
===========

Los componentes son los principales bloques de construcción de las aplicaciones Yii. Los componentes son instancias de [[yii\base\Component]] o de una clase extendida. Las tres características principales que los componentes proporcionan
a las otras clases son:

* [Propiedades](concept-properties.md)
* [Eventos](concept-events.md)
* [Comportamientos](concept-behaviors.md)

Por separado y combinadas, estas características hacen que las clases Yii sean mucho mas personalizables y sean mucho más fáciles de usar. Por ejemplo, el incluido [[yii\jui\DatePicker|widget de selección de fecha]], un componente de la interfaz de usuario, puede ser utilizado en una [vista](structure-view.md) para generar un DatePicker interactivo:

```php
use yii\jui\DatePicker;

echo DatePicker::widget([
    'language' => 'ru',
    'name'  => 'country',
    'clientOptions' => [
        'dateFormat' => 'yy-mm-dd',
    ],
]);
```

Las propiedades del widget son fácilmente modificables porque la clase se extiende de [[yii\base\Component]].

Mientras que los componentes son muy potentes, son un poco más pesados que los objetos normales, debido al hecho de que necesitan más memoria y tiempo de CPU para poder soportar [eventos](concept-events.md) y [comportamientos](concept-behaviors.md) en particular.
Si tus componentes no necesitan estas dos características, deberías considerar extender tu componente directamente de [[yii\base\BaseObject]] en vez de [[yii\base\Component]]. De esta manera harás que tus componentes sean mucho más eficientes que objetos PHP normales, pero con el añadido soporte para [propiedades](concept-properties.md).

Cuando extiendes tu clase de [[yii\base\Component]] o [[yii\base\BaseObject]], se recomienda que sigas las siguientes convenciones:

- Si sobrescribes el constructor, especifica un parámetro `$config` como el *último* parámetro del constructor, y después pasa este parámetro al constructor padre.
- Siempre llama al constructor padre al *final* de su propio constructor.
- Si sobrescribes el método [[yii\base\BaseObject::init()]], asegúrese de llamar la implementación padre de `init` * al principio * de su método` init`.

Por ejemplo:

```php
namespace yii\components\MyClass;

use yii\base\BaseObject;

class MyClass extends BaseObject
{
    public $prop1;
    public $prop2;

    public function __construct($param1, $param2, $config = [])
    {
        // ... inicialización antes de la configuración está siendo aplicada

        parent::__construct($config);
    }

    public function init()
    {
        parent::init();

        // ... inicialización después de la configuración esta siendo aplicada
    }
}
```

Siguiendo esas directrices hará que tus componentes sean [configurables](concept-configurations.md) cuando son creados. Por ejemplo:

```php
$component = new MyClass(1, 2, ['prop1' => 3, 'prop2' => 4]);
// alternativamente
$component = \Yii::createObject([
    'class' => MyClass::class,
    'prop1' => 3,
    'prop2' => 4,
], [1, 2]);
```

> Info: Mientras que el enfoque de llamar [[Yii::createObject()]] parece mucho más complicado, es mucho más potente debido al hecho de que se implementa en la parte superior de un [contenedor de inyección de dependencia](concept-di-container.md).
  

La clase [[yii\base\BaseObject]] hace cumplir el siguiente ciclo de vida del objeto:

1. Pre-inicialización en el constructor. Puedes establecer los valores predeterminados de propiedades aquí.
2. Configuración del objeto a través de `$config`. La configuración puede sobrescribir los valores prdeterminados dentro del constructor.
3. Post-inicialización dentro de [[yii\base\BaseObject::init()|init()]]. Puedes sobrescribir este método para realizar comprobaciones de validez y normalización de las propiedades.
4. Llamadas a métodos del objeto.

Los tres primeros pasos ocurren dentro del constructor del objeto. Esto significa que una vez obtengas la instancia de un objeto, ésta ha sido inicializada para que puedas utilizarla adecuadamente.

---

### Guide Es Concept Configurations (`docs/guide-es/concept-configurations.md`)

Configuración
==============

Las configuraciones se utilizan ampliamente en Yii al crear nuevos objetos o inicializar los objetos existentes. Las configuraciones por lo general incluyen el nombre de la clase del objeto que se está creando, y una lista de los valores iniciales que deberían ser asignadas a las del [propiedades](concept-properties.md) objeto. Las configuraciones también pueden incluir una lista de manipuladores que deban imponerse a del objeto [eventos](concept-events.md) y/o una lista de [comportamientos](concept-behaviors.md) que también ha de atribuirse al objeto.

A continuación, una configuración que se utiliza para crear e inicializar una conexión a base de datos:

```php
$config = [
    'class' => 'yii\db\Connection',
    'dsn' => 'mysql:host=127.0.0.1;dbname=demo',
    'username' => 'root',
    'password' => '',
    'charset' => 'utf8',
];

$db = Yii::createObject($config);
```
El método [[Yii::createObject()]] toma una matriz de configuración como su argumento, y crea un objeto intanciando la clase llamada en la configuración. Cuando se crea una instancia del objeto, el resto de la configuración se utilizará para inicializar las propiedades del objeto, controladores de eventos y comportamientos.

Si usted ya tiene un objeto, puede usar [[Yii::configure()]] para inicializar las propiedades del objeto con una matriz de configuración:

```php
Yii::configure($object, $config);
```

Tenga en cuenta que en este caso, la matriz de configuración no debe contener un elemento `class`.

## Formato de Configuración <span id="configuration-format"></span>

El formato de una configuración se puede describir formalmente como:

```php
[
    'class' => 'ClassName',
    'propertyName' => 'propertyValue',
    'on eventName' => $eventHandler,
    'as behaviorName' => $behaviorConfig,
]
```

donde

* El elemento `class` especifica un nombre de clase completo para el objeto que se está creando.
* Los elementos `propertyName` especifica los valores iniciales de la propiedad con nombre. Las claves son los nombres de las propiedades y los valores son los valores iniciales correspondientes. Sólo los miembros de variables públicas y [propiedades](concept-properties.md) definidas por getters/setters se pueden configurar.
* Los elementos `on eventName` especifican qué manipuladores deberán adjuntarse al del objeto [eventos](concept-events.md). Observe que las claves de matriz se forman prefijando nombres de eventos con `on`. Por favor, consulte la sección [Eventos](concept-events.md) para los formatos de controlador de eventos compatibles.
* Los elementos `as behaviorName` especifican qué [comportamientos](concept-behaviors.md) deben adjuntarse al objeto. Observe que las claves de matriz se forman prefijando nombres de comportamiento con `as`; el valor, `$behaviorConfig`, representa la configuración para la creación de un comportamiento, como una configuración normal descrita aquí.

A continuación se muestra un ejemplo de una configuración con los valores de propiedad iniciales, controladores de eventos y comportamientos:

```php
[
    'class' => 'app\components\SearchEngine',
    'apiKey' => 'xxxxxxxx',
    'on search' => function ($event) {
        Yii::info("Keyword searched: " . $event->keyword);
    },
    'as indexer' => [
        'class' => 'app\components\IndexerBehavior',
        // ... property init values ...
    ],
]
```


## Usando Configuraciones <span id="using-configurations"></span>

Las configuraciones se utilizan en muchos lugares en Yii. Al comienzo de esta sección, hemos demostrado cómo crear un objeto según una configuración mediante el uso de [[Yii::createObject()]]. En este apartado, vamos a describir configuraciones de aplicaciones y configuraciones widget - dos principales usos de configuraciones.


### Configuraciones de aplicación <span id="application-configurations"></span>

Configuración para una [aplicación](structure-applications.md) es probablemente una de las configuraciones más complejas. Esto se debe a que la clase [[yii\web\Application|aplicación]] tiene un montón de propiedades y eventos configurables. Más importante aún, su propiedad [[yii\web\Application::components|componentes]] que puede recibir una gran variedad de configuraciones para crear componentes que se registran a través de la aplicación. Lo siguiente es un resumen del archivo de configuración de la aplicación para la [plantilla básica de la aplicación](start-installation.md).

```php
$config = [
    'id' => 'basic',
    'basePath' => dirname(__DIR__),
    'extensions' => require __DIR__ . '/../vendor/yiisoft/extensions.php',
    'components' => [
        'cache' => [
            'class' => 'yii\caching\FileCache',
        ],
        'mailer' => [
            'class' => 'yii\swiftmailer\Mailer',
        ],
        'log' => [
            'class' => 'yii\log\Dispatcher',
            'traceLevel' => YII_DEBUG ? 3 : 0,
            'targets' => [
                [
                    'class' => 'yii\log\FileTarget',
                ],
            ],
        ],
        'db' => [
            'class' => 'yii\db\Connection',
            'dsn' => 'mysql:host=localhost;dbname=stay2',
            'username' => 'root',
            'password' => '',
            'charset' => 'utf8',
        ],
    ],
];
```

La configuración no tiene una clave `class`. Esto es porque se utiliza como sigue en un [script de entrada](structure-entry-scripts.md), donde ya se le da el nombre de la clase,

```php
(new yii\web\Application($config))->run();
```

Para más detalles sobre la configuración de la propiedad `components` de una aplicación se puede encontrar en la sección [Aplicación](structure-applications.md) y la sección [Localizador de Servicio](concept-service-locator.md).


### Configuración Widget <span id="widget-configurations"></span>

Cuando se utiliza [widgets](structure-widgets.md), a menudo es necesario utilizar las configuraciones para personalizar las propiedades de widgets. Tanto los metodos [[yii\base\Widget::widget()]] y [[yii\base\Widget::begin()]] pueden usarse para crear un widget. Toman un arreglo de configuración, como el siguiente,

```php
use yii\widgets\Menu;

echo Menu::widget([
    'activateItems' => false,
    'items' => [
        ['label' => 'Home', 'url' => ['site/index']],
        ['label' => 'Products', 'url' => ['product/index']],
        ['label' => 'Login', 'url' => ['site/login'], 'visible' => Yii::$app->user->isGuest],
    ],
]);
```

El código anterior crea un widget `Menu` e inicializa su propiedad `activeItems` en falsa. La propiedad `items` también se configura con elementos de menú que se muestran.

Tenga en cuenta que debido a que el nombre de la clase ya está dado, la matriz de configuración no deben tener la clave `class`.


## Archivos de Configuración <span id="configuration-files"></span>

Cuando una configuración es muy compleja, una práctica común es almacenarla en uno o múltiples archivos PHP, conocidos como *archivos de configuración*. Un archivo de configuración devuelve un array de PHP que representa la configuración. Por ejemplo, es posible mantener una configuración de la aplicación en un archivo llamado `web.php`, como el siguiente,

```php
return [
    'id' => 'basic',
    'basePath' => dirname(__DIR__),
    'extensions' => require __DIR__ . '/../vendor/yiisoft/extensions.php',
    'components' => require __DIR__ . '/components.php',
];
```

Debido a que la configuración `componentes` es compleja también, se guarda en un archivo separado llamado `components.php` y "requerir" este archivo en `web.php` como se muestra arriba. El contenido de `components.php` es el siguiente,

```php
return [
    'cache' => [
        'class' => 'yii\caching\FileCache',
    ],
    'mailer' => [
        'class' => 'yii\swiftmailer\Mailer',
    ],
    'log' => [
        'class' => 'yii\log\Dispatcher',
        'traceLevel' => YII_DEBUG ? 3 : 0,
        'targets' => [
            [
                'class' => 'yii\log\FileTarget',
            ],
        ],
    ],
    'db' => [
        'class' => 'yii\db\Connection',
        'dsn' => 'mysql:host=localhost;dbname=stay2',
        'username' => 'root',
        'password' => '',
        'charset' => 'utf8',
    ],
];
```

Para obtener una configuración almacenada en un archivo de configuración, simplemente "requerir" este, como el siguiente:

```php
$config = require 'path/to/web.php';
(new yii\web\Application($config))->run();
```


## Configuraciones por Defecto <span id="default-configurations"></span>

El método [[Yii::createObject()]] es implementado en base a [contenedor de inyección de dependencia](concept-di-container.md). Le permite especificar un conjunto de los llamados *configuraciones predeterminadas* que se aplicarán a todos los casos de las clases especificadas cuando se crean utilizando [[Yii::createObject()]]. Las configuraciones por defecto se puede especificar llamando `Yii::$container->set()` en el código [bootstrapping](runtime-bootstrapping.md).

Por ejemplo, si desea personalizar [[yii\widgets\LinkPager]] para que TODO enlace de búsqueda muestre como máximo 5 botones de página (el valor por defecto es 10), puede utilizar el siguiente código para lograr este objetivo,

```php
\Yii::$container->set('yii\widgets\LinkPager', [
    'maxButtonCount' => 5,
]);
```

Sin utilizar las configuraciones predeterminadas, usted tendría que configurar `maxButtonCount` en cada lugar en el que utiliza enlace paginador.

## Constantes de Entorno <span id="environment-constants"></span>

Las configuraciones a menudo varían de acuerdo al entorno en que se ejecuta una aplicación. Por ejemplo, en el entorno de desarrollo, es posible que desee utilizar una base de datos llamada `mydb_dev`, mientras que en servidor de producción es posible que desee utilizar la base de datos `mydb_prod`. Para facilitar la conmutación de entornos, Yii proporciona una constante llamado `YII_ENV` que se puede definir en el [script de entrada](structure-entry-scripts.md) de su aplicación. Por ejemplo,

```php
defined('YII_ENV') or define('YII_ENV', 'dev');
```

Usted puede definir `YII_ENV` como uno de los valores siguientes:

- `prod`: entorno de producción. La constante `YII_ENV_PROD` evaluará como verdadero. 
Este es el valor por defecto de `YII_ENV` si no esta definida.
- `dev`: entorno de desarrollo. La constante `YII_ENV_DEV` evaluará como verdadero.
- `test`: entorno de pruebas. La constante `YII_ENV_TEST` evaluará como verdadero.

Con estas constantes de entorno, puede especificar sus configuraciones condicionales basado en el entorno actual. Por ejemplo, la configuración de la aplicación puede contener el siguiente código para permitir que el [depurador y barra de herramientas de depuración](tool-debugger.md) en el entorno de desarrollo.

```php
$config = [...];

if (YII_ENV_DEV) {
    // configuration adjustments for 'dev' environment
    $config['bootstrap'][] = 'debug';
    $config['modules']['debug'] = 'yii\debug\Module';
}

return $config;
```

---

### Guide Es Concept Di Container (`docs/guide-es/concept-di-container.md`)

Contenedor de Inyección de Dependencias
=======================================

Un contenedor de Inyección de Dependencias (ID), es un objeto que sabe como instancias y configurar objetos y sus 
objetos dependientes. El [articulo de Martin](https://martinfowler.com/articles/injection.html) contiene una buena 
explicación de porque son útiles los contenedores de ID. A continuación explicaremos como usar el contenedor de ID que 
proporciona Yii.

Inyección de Dependencias <span id="dependency-injection"></span>
-------------------------

Yii proporciona la función de contenedor de ID mediante la clase [[yii\di\Container]]. Soporta los siguientes tipos 
de ID:

* Inyección de constructores;
* Inyección de setters y propiedades;
* Inyección de [llamadas de retorno PHP](https://www.php.net/manual/es/language.types.callable.php);

### Inyección de Constructores <span id="constructor-injection"></span>

El contenedor de ID soporta inyección de constructores con la ayuda de los indicios (hint) de tipo para los parámetros del 
constructor. Los indicios de tipo le proporcionan información al contenedor para saber cuáles son las clases o 
interfaces dependientes al usarse para crear un nuevo objeto. El contenedor intentara obtener las instancias de las 
clases o interfaces dependientes y las inyectará dentro del nuevo objeto mediante el constructor. Por ejemplo,

```php
class Foo
{
    public function __construct(Bar $bar)
    {
    }
}

$foo = $container->get('Foo');
// que es equivalente a:
$bar = new Bar;
$foo = new Foo($bar);
```

### Inyección de Setters y Propiedades <span id="setter-and-property-injection"></span>

La inyección de setters y propiedades se admite a través de [configuraciones](concept-configurations.md). Cuando se 
registra una dependencia o se crea un nuevo objeto, se puede proporcionar una configuración que usará el contenedor 
para inyectar las dependencias a través de sus correspondientes setters y propiedades. Por ejemplo,

```php
use yii\base\BaseObject;

class Foo extends BaseObject
{
    public $bar;

    private $_qux;

    public function getQux()
    {
        return $this->_qux;
    }

    public function setQux(Qux $qux)
    {
        $this->_qux = $qux;
    }
}

$container->get('Foo', [], [
    'bar' => $container->get('Bar'),
    'qux' => $container->get('Qux'),
]);
```

### Inyección de Llamadas de retorno PHP <span id="php-callable-injection"></span>

En este caso, el contenedor usará una llamada de retorno PHP registrada para construir una nueva instancia de una 
clase. La llamada de retorno se responsabiliza de que dependencias debe inyectar al nuevo objeto creado. Por ejemplo,

```php
$container->set('Foo', function ($container, $params, $config) {
    return new Foo(new Bar);
});

$foo = $container->get('Foo');
```

Registro de dependencias <span id="registering-dependencies"></span>
------------------------

Se puede usar [[yii\di\Container::set()]] para registrar dependencias. El registro requiere un nombre de dependencia 
así como una definición de dependencia. Un nombre de dependencia puede ser un nombre de clase, un nombre de interfaz, 
o un nombre de alias; y una definición de dependencia puede ser un nombre de clase, un array de configuración, o una 
llamada de retorno PHP.

```
/* Detailed source-code truncated for AI context efficiency. */
```

> Tip: Si un nombre de dependencia es el mismo que la definición de dependencia, no es necesario registrarlo con 
  el contenedor de ID.

Una dependencia registrada mediante `set()` generará una instancia cada vez que se necesite la dependencia. Se puede 
usar [[yii\di\Container::setSingleton()]] para registrar una dependencia que genere una única instancia:

```php
$container->setSingleton('yii\db\Connection', [
    'dsn' => 'mysql:host=127.0.0.1;dbname=demo',
    'username' => 'root',
    'password' => '',
    'charset' => 'utf8',
]);
```

Resolución de Dependencias <span id="resolving-dependencies"></span>
--------------------------

Una ves se hayan registrado las dependencias, se puede usar el contenedor de ID para crear nuevos objetos, y el 
contenedor resolverá automáticamente las dependencias instanciándolas e inyectándolas dentro de los nuevos objetos 
creados. La resolución de dependencias es recursiva, esto significa que si una dependencia tiene otras dependencias, 
estas dependencias también se resolverán automáticamente.

Se puede usar [[yii\di\Container::get()]] para crear nuevos objetos. El método obtiene el nombre de dependencia, que 
puede ser un nombre de clase, un nombre de interfaz o un nombre de alias. El nombre de dependencia puede estar 
registrado o no mediante `set()` o `setSingleton()`. Se puede proporcionar opcionalmente un listado de los parámetros 
del constructor de clase y una [configuración](concept-configurations.md) para configurar los nuevos objetos creados. 
Por ejemplo,

```php
// "db" ha sido registrado anteriormente como nombre de alias
$db = $container->get('db');

// equivalente a: $engine = new \app\components\SearchEngine($apiKey, ['type' => 1]);
$engine = $container->get('app\components\SearchEngine', [$apiKey], ['type' => 1]);
```

Por detrás, el contenedor de ID efectúa mucho más trabajo la creación de un nuevo objeto. El contenedor primero 
inspeccionará la clase constructora para encontrar los nombres de clase o interfaces dependientes y después 
automáticamente resolverá estas dependencias recursivamente.

El siguiente código muestra un ejemplo más sofisticado. La clase `UserLister` depende del un objeto que implementa la 
interfaz `UserFinderInterface`; la clase `UserFinder` implementa la interfaz y depende del objeto `Connection`.  Todas 
estas dependencias se declaran a través de insinuaciones (hinting) de los parámetros del constructor de clase. Con el 
registro de dependencia de propiedades, el contenedor de ID puede resolver las dependencias automáticamente y crear 
una nueva instancia de `UserLister` con una simple llamada a `get('userLister')`.

```php
namespace app\models;

use yii\base\BaseObject;
use yii\db\Connection;
use yii\di\Container;

interface UserFinderInterface
{
    function findUser();
}

class UserFinder extends BaseObject implements UserFinderInterface
{
    public $db;

    public function __construct(Connection $db, $config = [])
    {
        $this->db = $db;
        parent::__construct($config);
    }

    public function findUser()
    {
    }
}

class UserLister extends BaseObject
{
    public $finder;

    public function __construct(UserFinderInterface $finder, $config = [])
    {
        $this->finder = $finder;
        parent::__construct($config);
    }
}

$container = new Container;
$container->set('yii\db\Connection', [
    'dsn' => '...',
]);
$container->set('app\models\UserFinderInterface', [
    'class' => 'app\models\UserFinder',
]);
$container->set('userLister', 'app\models\UserLister');

$lister = $container->get('userLister');

// que es equivalente a:

$db = new \yii\db\Connection(['dsn' => '...']);
$finder = new UserFinder($db);
$lister = new UserLister($finder);
```

Uso Practico <span id="practical-usage"></span>
------------

Yii crea un contenedor de ID cuando se incluye el archivo `Yii.php` en el 
[script de entrada](structure-entry-scripts.md) de la aplicación. Cuando se llama a [[Yii::createObject()]] el método 
realmente llama al contenedor del método [[yii\di\Container::get()|get()]] para crear un nuevo objeto. Como se ha 
comentado anteriormente, el contenedor de ID resolverá automáticamente las dependencias (si las hay) y las inyectará 
dentro del nuevo objeto creado. Debido a que Yii utiliza [[Yii::createObject()]] en la mayor parte del núcleo (core) 
para crear nuevo objetos, podemos personalizar los objetos globalmente para que puedan tratar con [[Yii::$container]].

Por ejemplo, se puede personalizar globalmenete el numero predeterminado de números de botones de paginación de 
[[yii\widgets\LinkPager]]:

```php
\Yii::$container->set('yii\widgets\LinkPager', ['maxButtonCount' => 5]);
```

Ahora si se usa el widget en una vista con el siguiente código, la propiedad `maxButtonCount` será inicializada con 
valor 5 en lugar de 10 que es el valor predeterminado definido en la clase.

```php
echo \yii\widgets\LinkPager::widget();
```

Se puede sobrescribir el valor establecido mediante el contenedor de ID, como a continuación:

```php
echo \yii\widgets\LinkPager::widget(['maxButtonCount' => 20]);
```

Otro ejemplo es aprovechar la ventaja de la inyección automática de constructores de contenedores de ID. Asumiendo que 
la clase controlador depende de otros objetos, tales como un servicio de reservas de hotel. Se puede declarar una 
dependencia a través de un parámetro del constructor y permitir al contenedor de ID resolverla por nosotros.

```php
namespace app\controllers;

use yii\web\Controller;
use app\components\BookingInterface;

class HotelController extends Controller
{
    protected $bookingService;

    public function __construct($id, $module, BookingInterface $bookingService, $config = [])
    {
        $this->bookingService = $bookingService;
        parent::__construct($id, $module, $config);
    }
}
```

Si se accede al controlador desde el navegador, veremos un error advirtiendo que `BookingInterface` no puede ser 
instanciada. Esto se debe a que necesitamos indicar al contenedor de ID como tratar con esta dependencia:

```php
\Yii::$container->set('app\components\BookingInterface', 'app\components\BookingService');
```

Ahora si se accede al contenedor nuevamente, se creará una instancia de `app\components\BookingService` y se inyectará 
a como tercer parámetro al constructor del controlador.

Cuando Registrar Dependencias <span id="when-to-register-dependencies"></span>
-----------------------------

El registro de dependencias debe hacerse lo antes posible debido a que las dependencias se necesitan cuando se crean 
nuevos objetos. A continuación se listan practicas recomendadas:

* Siendo desarrolladores de una aplicación, podemos registrar dependencias en el 
  [script de entrada](structure-entry-scripts.md) o en un script incluido en el script de entrada.
* Siendo desarrolladores de una [extension](structure-extensions.md) redistribuible, podemos registrar dependencias en 
  la clase de boostraping de la extensión.

Resumen <span id="summary"></span>
-------

Tanto la inyección de dependencias como el [localizador de servicios](concept-service-locator.md) son patrones de 
diseño populares que permiten construir software con acoplamiento flexible y más fácil de testear. Se recomienda 
encarecida la lectura del articulo de [Martin](https://martinfowler.com/articles/injection.html) para obtener una mejor 
comprensión de la inyección de dependencias y de la localización de servicios.

Yii implementa su propio [localizador de servicios](concept-service-locator.md) por encima del contenedor de ID. 
Cuando un localizador de servicios intenta crear una nueva instancia de objeto, se desviará la llamada al contenedor 
de ID. Este último resolverá las dependencias automáticamente como se ha descrito anteriormente.

---

### Guide Es Concept Events (`docs/guide-es/concept-events.md`)

Eventos
=======

Los eventos permiten inyectar código dentro de otro código existente en ciertos puntos de ejecución. Se pueden adjuntar
código personalizado a un evento, cuando se lance (triggered), el código se ejecutará automáticamente. Por ejemplo, un
objeto mailer puede lanzar el evento `messageSent` cuando se envía un mensaje correctamente. Si se quiere rastrear
el correcto envío del mensaje, se puede, simplemente, añadir un código de seguimiento al evento `messageSent`.

Yii introduce una clase base [[yii\base\Component]] para soportar eventos. Si una clase necesita lanzar un evento,
este debe extender a [[yii\base\Component]] o a una clase hija.

Gestor de Eventos <span id="event-handlers"></span>
-----------------

Un gestor de eventos es una
[llamada de retorno PHP (PHP callback)](https://www.php.net/manual/es/language.types.callable.php) que se ejecuta cuando se
lanza el evento al que corresponde. Se puede usar cualquier llamada de retorno de las enumeradas a continuación:

- una función de PHP global especificada como una cadena de texto (sin paréntesis), ej. `'trim'`;
- un método de objeto especificado como un array de un objeto y un nombre de método como una cadena de texto
  (sin paréntesis), ej. `[$object, 'methodNAme']`;
- un método de clase estático especificado como un array de un nombre de clase y un método como una cadena de texto
  (sin paréntesis), ej. `[$class, 'methodName']`;
- una función anónima, ej. `function ($event) { ... }`.

La firma de un gestor de eventos es:

```php
function ($event) {
    // $event es un objeto de yii\base\Event o de una clase hija
}
```

Un gestor de eventos puede obtener la siguiente información acerca de un evento ya sucedido mediante el parámetro
`$event`:

- [[yii\base\Event::name|nombre del evento]]
- [[yii\base\Event::sender|evento enviando]]: el objeto desde el que se ha ejecutado `trigger()`
- [[yii\base\Event::data|custom data]]: los datos que se proporcionan al adjuntar el gestor de eventos
  (se explicará más adelante)


Añadir Gestores de Eventos <span id="attaching-event-handlers"></span>
--------------------------

Se puede añadir un gestor a un evento llamando al método [[yii\base\Component::on()]]. Por ejemplo:

```php
$foo = new Foo;

// este gestor es una función global
$foo->on(Foo::EVENT_HELLO, 'function_name');

// este gestor es un método de objeto
$foo->on(Foo::EVENT_HELLO, [$object, 'methodName']);

// este gestor es un método de clase estática
$foo->on(Foo::EVENT_HELLO, ['app\components\Bar', 'methodName']);

// este gestor es una función anónima
$foo->on(Foo::EVENT_HELLO, function ($event) {
    // event handling logic
});
```

También se pueden adjuntar gestores de eventos mediante [configuraciones](concept-configurations.md). Se pueden
encontrar más de talles en la sección [Configuraciones](concept-configurations.md#configuration-format).

Cuando se adjunta un gestor de eventos, se pueden proporcionar datos adicionales como tercer parámetro de
[[yii\base\Component::on()]]. El gestor podrá acceder a los datos cuando se lance el evento y se ejecute el gestor.
Por ejemplo:

```php
// El siguiente código muestra "abc" cuando se lanza el evento
// ya que $event->data contiene los datos enviados en el tercer parámetro de "on"
$foo->on(Foo::EVENT_HELLO, 'function_name', 'abc');

function function_name($event) {
    echo $event->data;
}
```

Ordenación de Gestores de Eventos
---------------------------------

Se puede adjuntar uno o más gestores a un único evento. Cuando se lanza un evento, se ejecutarán los gestores adjuntos
en el orden que se hayan añadido al evento. Si un gestor necesita parar la invocación de los gestores que le siguen,
se puede establecer la propiedad [[yii\base\Event::handled]] del parámetro `$event` para que sea `true`:

```php
$foo->on(Foo::EVENT_HELLO, function ($event) {
    $event->handled = true;
});
```

De forma predeterminada, cada nuevo gestor añadido se pone a la cola de la lista de gestores del evento. Por lo tanto,
el gestor se ejecutará en el último lugar cuando se lance el evento. Para insertar un nuevo gestor al principio de la
cola de gestores para que sea ejecutado primero, se debe llamar a [[yii\base\Component::on()]], pasando al cuarto
parámetro `$append` el valor `false`:

```php
$foo->on(Foo::EVENT_HELLO, function ($event) {
    // ...
}, $data, false);
```

Lanzamiento de Eventos <span id="triggering-events"></span>
----------------------

Los eventos se lanzan llamando al método [[yii\base\Component::trigger()]]. El método requiere un *nombre de evento*,
y de forma opcional un objeto de evento que describa los parámetros que se enviarán a los gestores de eventos. Por
ejemplo:

```php
namespace app\components;

use yii\base\Component;
use yii\base\Event;

class Foo extends Component
{
    const EVENT_HELLO = 'hello';

    public function bar()
    {
        $this->trigger(self::EVENT_HELLO);
    }
}
```

Con el código anterior, cada llamada a `bar()` lanzará un evento llamado `hello`

> Tip: Se recomienda usar las constantes de clase para representar nombres de eventos. En el anterior ejemplo, la
  constante `EVENT_HELLO` representa el evento `hello`. Este enfoque proporciona tres beneficios. Primero, previene
  errores tipográficos. Segundo, puede hacer que los IDEs reconozcan los eventos en las funciones de auto-completado.
  Tercero, se puede ver que eventos soporta una clase simplemente revisando la declaración de constantes.

A veces cuando se lanza un evento se puede querer pasar información adicional al gestor de eventos. Por ejemplo, un
mailer puede querer enviar la información del mensaje para que los gestores del evento `messageSent` para que los
gestores puedan saber las particularidades del mensaje enviado. Para hacerlo, se puede proporcionar un objeto de tipo
evento como segundo parámetro al método [[yii\base\Component::trigger()]]. El objeto de tipo evento debe ser una
instancia de la clase [[yii\base\Event]] o de su clase hija. Por ejemplo:

```php
namespace app\components;

use yii\base\Component;
use yii\base\Event;

class MessageEvent extends Event
{
    public $message;
}

class Mailer extends Component
{
    const EVENT_MESSAGE_SENT = 'messageSent';

    public function send($message)
    {
        // ...enviando $message...

        $event = new MessageEvent;
        $event->message = $message;
        $this->trigger(self::EVENT_MESSAGE_SENT, $event);
    }
}
```

Cuando se lanza el método [[yii\base\Component::trigger()]], se ejecutarán todos los gestores adjuntos al evento.

Desadjuntar Gestores de Evento <span id="detaching-event-handlers"></span>
------------------------------

Para desadjuntar un gestor de un evento, se puede ejecutar el método [[yii\base\Component::off()]]. Por ejemplo:

```php
// el gestor es una función global
$foo->off(Foo::EVENT_HELLO, 'function_name');

// el gestor es un método de objeto
$foo->off(Foo::EVENT_HELLO, [$object, 'methodName']);

// el gestor es un método estático de clase
$foo->off(Foo::EVENT_HELLO, ['app\components\Bar', 'methodName']);

// el gestor es una función anónima
$foo->off(Foo::EVENT_HELLO, $anonymousFunction);
```

Tenga en cuenta que en general no se debe intentar desadjuntar las funciones anónimas a no ser que se almacene donde
se ha adjuntado al evento. En el anterior ejemplo, se asume que la función anónima se almacena como variable
`$anonymousFunction`.

Para desadjuntar TODOS los gestores de un evento, se puede llamar [[yii\base\Component::off()]] sin el segundo
parámetro:

```php
$foo->off(Foo::EVENT_HELLO);
```

Nivel de Clase (Class-Level) Gestores de Eventos <span id="class-level-event-handlers"></span>
------------------------------------------------

En las subsecciones anteriores se ha descrito como adjuntar un gestor a un evento a *nivel de instancia*. A veces, se
puede querer que un gestor responda todos los eventos de *todos* las instancias de una clase en lugar de una instancia
especifica. En lugar de adjuntar un gestor de eventos a una instancia, se puede adjuntar un gestor a *nivel de clase*
llamando al método estático [[yii\base\Event::on()]].

Por ejemplo, un objeto de tipo [Active Record](db-active-record.md) lanzará un evento
[[yii\db\BaseActiveRecord::EVENT_AFTER_INSERT|EVENT_AFTER_INSERT]] cada vez que inserte un nuevo registro en la base
de datos. Para poder registrar las inserciones efectuadas por *todos* los objetos
[Active Record](db-active-record.md), se puede usar el siguiente código:

```php
use Yii;
use yii\base\Event;
use yii\db\ActiveRecord;

Event::on(ActiveRecord::class, ActiveRecord::EVENT_AFTER_INSERT, function ($event) {
    Yii::debug(get_class($event->sender) . ' is inserted');
});
```

Se invocará al gestor de eventos cada vez que una instancia de [[yii\db\ActiveRecord|ActiveRecord]], o de uno de sus
clases hijas, lance un evento de tipo [[yii\db\BaseActiveRecord::EVENT_AFTER_INSERT|EVENT_AFTER_INSERT]]. Se puede
obtener el objeto que ha lanzado el evento mediante `$event->sender` en el gestor.

Cuando un objeto lanza un evento, primero llamará los gestores a nivel de instancia, y a continuación los gestores a
nivel de clase.

Se puede lanzar un evento de tipo *nivel de clase* llamando al método estático [[yii\base\Event::trigger()]]. Un
evento de nivel de clase no se asocia a un objeto en particular. Como resultado, esto provocará solamente la
invocación de los gestores de eventos a nivel de clase.

```php
use yii\base\Event;

Event::on(Foo::class, Foo::EVENT_HELLO, function ($event) {
    var_dump($event->sender);  // displays "null"
});

Event::trigger(Foo::class, Foo::EVENT_HELLO);
```

Tenga en cuenta que en este caso, el `$event->sender` hace referencia al nombre de la clase que lanza el evento en
lugar de a la instancia del objeto.

> Note: Debido a que los gestores a nivel de clase responderán a los eventos lanzados por cualquier instancia de la
clase, o cualquier clase hija, se debe usar con cuidado, especialmente en las clases de bajo nivel (low-level), tales
como [[yii\base\BaseObject]].

Para desadjuntar un gestor de eventos a nivel de clase, se tiene que llamar a [[yii\base\Event::off()]]. Por ejemplo:

```php
// desadjunta $handler
Event::off(Foo::class, Foo::EVENT_HELLO, $handler);

// desadjunta todos los gestores de Foo::EVENT_HELLO
Event::off(Foo::class, Foo::EVENT_HELLO);
```

Eventos Globales <span id="global-events"></span>
----------------

Yii soporta los llamados *eventos globales*, que en realidad es un truco basado en el gestor de eventos descrito
anteriormente. El evento global requiere un Singleton globalmente accesible, tal como la instancia de
[aplicación](structure-applications.md) en si misma.

Para crear un evento global, un evento remitente (event sender) llama al método `trigger()` del Singleton para lanzar
el evento, en lugar de llamar al propio método `trigger()` del remitente. De forma similar, los gestores de eventos se
adjuntan al evento del Singleton. Por ejemplo:

```php
use Yii;
use yii\base\Event;
use app\components\Foo;

Yii::$app->on('bar', function ($event) {
    echo get_class($event->sender);  // muestra "app\components\Foo"
});

Yii::$app->trigger('bar', new Event(['sender' => new Foo]));
```

Un beneficio de usar eventos globales es que no se necesita un objeto cuando se adjuntan gestores a un evento para que
sean lanzados por el objeto. En su lugar, los gestores adjuntos y el lanzamiento de eventos se efectúan en el
Singleton (ej. la instancia de la aplicación).

Sin embargo, debido a que los `namespaces` de los eventos globales son compartidos por todas partes, se les deben
asignar nombres bien pensados, como puede ser la introducción de algún `namespace`
(ej. "frontend.mail.sent", "backend.mail.sent").

---

### Guide Es Concept Properties (`docs/guide-es/concept-properties.md`)

Propiedades
===========

En PHP, las variables miembro de clases también llamadas *propiedades*, son parte de la definición de la clase, y se
usan para representar el estado de una instancia de la clase (ej. para diferenciar una instancia de clase de otra).
A la práctica, a menudo, se puede querer gestionar la lectura o escritura de las propiedades de algunos momentos. Por
ejemplo, se puede querer eliminar los espacios en blanco (trim) de una cadena de texto cada vez que esta se asigne a
una propiedad de tipo `label`. Se *podría* usar el siguiente código para realizar esta tarea:

```php
$object->label = trim($label);
```

La desventaja del código anterior es que se tendría que ejecutar `trim()` en todas las partes del código que pudieran
establecer la propiedad `label`. Si en el futuro, la propiedad `label` tiene que seguir otro funcionamiento, como por
ejemplo que la primera letra tiene que estar en mayúsculas, se tendrán que modificar todas las secciones de código que
asignen el valor a la propiedad `label`. La repetición de código conlleva a bugs, y es una practica que se tiene que
evitar en la medida de lo posible.

Para solventar este problema, Yii introduce la clase base llamada [[yii\base\BaseObject]] que da soporte a la definición
de propiedades basada en los métodos de clase *getter* y *setter*. Si una clase necesita más funcionalidad, debe
extender a la clase [[yii\base\BaseObject]] o a alguna de sus hijas.

> Info: Casi todas las clases del núcleo (core) en el framework Yii extienden a [[yii\base\BaseObject]] o a una de
  sus clases hijas. Esto significa que siempre que se encuentre un getter o un setter en una clase del núcleo, se
  puede utilizar como una propiedad.

Un método getter es un método cuyo nombre empieza por la palabra `get`: un metodo setter empieza por `set`. El nombre
añadido detrás del prefijo `get` o `set` define el nombre de la propiedad. Por ejemplo, un getter `getLabel()` y/o un
setter `setLabel()` definen la propiedad `label`, como se muestra a continuación:

```php
namespace app\components;

use yii\base\BaseObject;

class Foo extends BaseObject
{
    private $_label;

    public function getLabel()
    {
        return $this->_label;
    }

    public function setLabel($value)
    {
        $this->_label = trim($value);
    }
}
```

(Para ser claros, los métodos getter y setter crean la propiedad `label`, que en este caso hace una referencia interna
al nombre de atributo privado `_label`.)

Las propiedades definidas por los getter y los setters se pueden usar como variables de clase miembro. La principal
diferencia radica en que cuando esta propiedad se lea, se ejecutará su correspondiente método getter; cuando se asigne
un valor a la propiedad, se ejecutará el correspondiente método setter. Por ejemplo:

```php
// equivalente a $label = $object->getLabel();
$label = $object->label;

// equivalente a $object->setLabel('abc');
$object->label = 'abc';
```

Una propiedad definida por un getter sin un setter es de tipo *sólo lectura*. Si se intenta asignar un valor a esta
propiedad se producirá una excepción de tipo [[yii\base\InvalidCallException|InvalidCallException]]. Del mismo modo
que una propiedad definida con un setter pero sin getter será de tipo *sólo escritura*, cualquier intento de lectura
de esta propiedad producirá una excepción. No es común tener variables de tipo sólo escritura.

Hay varias reglas especiales y limitaciones en las propiedades definidas mediante getters y setters:

* Los nombres de estas propiedades son *case-insensitive*. Por ejemplo, `$object->label` y `$object->Label` son la
  misma. Esto se debe a que los nombres de los métodos en PHP son case-insensitive.
* Si el nombre de una propiedad de este tipo es igual al de una variable miembro de la clase, la segunda tendrá
  prioridad. Por ejemplo, si la anterior clase `Foo` tiene la variable miembro `label`, entonces la asignación
  `$object->label = 'abc'` afectará a la *variable miembro* 'label'; no se ejecutará el método setter `setLabel()`.
* Estas variables no soportan la visibilidad. No hay diferencia en definir los métodos getter o setter en una
  propiedad public, protected, o private.
* Las propiedades sólo se pueden definir por getters y setters *no estáticos*. Los métodos estáticos no se tratarán de
  la misma manera.

Volviendo de nuevo al problema descrito al principio de la guía, en lugar de ejecutar `trim()` cada vez que se asigne
un valor a `label`, ahora `trim()` sólo necesita ser invocado dentro del setter `setLabel()`. I si se tiene que añadir
un nuevo requerimiento, para que `label` empiece con una letra mayúscula, se puede modificar rápidamente el método `
setLabel()` sin tener que modificar más secciones de código. El cambio afectará a cada asignación de `label`.

---

### Guide Es Concept Service Locator (`docs/guide-es/concept-service-locator.md`)

Localizador de Servicios
========================

Un localizador de servicios es un objeto que sabe cómo proporcionar todo tipo de servicios (o componentes) que puede necesitar una aplicación. Dentro de un localizador de servicios, existe en cada componente como una única instancia, únicamente identificado por un ID. Se utiliza el ID para recuperar un componente desde el localizador de servicios.

En Yii, un localizador de servicio es simplemente una instancia de [[yii\di\ServiceLocator]], o de una clase hija.

El localizador de servicio más utilizado en Yii es el objeto *aplicación*, que se puede acceder a través de `\Yii::$app`. Los servicios que prestá son llamadas *componentes de la aplicación*, como los componentes `request`, `response`, and `urlManager`. Usted puede configurar estos componentes, o incluso cambiarlos por sus propias implementaciones fácilmente a través de la funcionalidad proporcionada por el localizador de servicios.

Además del objeto de aplicación, cada objeto módulo es también un localizador de servicios.

Para utilizar un localizador de servicios, el primer paso es registrar los componentes de la misma. Un componente se puede registrar a través de [[yii\di\ServiceLocator::set()]]. El código siguiente muestra diferentes maneras de registrarse componentes:

```php
use yii\di\ServiceLocator;
use yii\caching\FileCache;

$locator = new ServiceLocator;

// register "cache" using a class name that can be used to create a component
$locator->set('cache', 'yii\caching\ApcCache');

// register "db" using a configuration array that can be used to create a component
$locator->set('db', [
    'class' => 'yii\db\Connection',
    'dsn' => 'mysql:host=localhost;dbname=demo',
    'username' => 'root',
    'password' => '',
]);

// register "search" using an anonymous function that builds a component
$locator->set('search', function () {
    return new app\components\SolrService;
});

// register "pageCache" using a component
$locator->set('pageCache', new FileCache);
```

Una vez que el componente se ha registrado, usted puede acceder a él utilizando su ID, en una de las dos formas siguientes:

```php
$cache = $locator->get('cache');
// or alternatively
$cache = $locator->cache;
```

Como puede observarse, [[yii\di\ServiceLocator]] le permite acceder a un componente como una propiedad utilizando el ID de componente. Cuando acceda a un componente, por primera vez, [[yii\di\ServiceLocator]] utilizará la información de registro de componente para crear una nueva instancia del componente y devolverlo. Más tarde, si se accede de nuevo al componente, el localizador de servicio devolverá la misma instancia.

Usted puede utilizar [[yii\di\ServiceLocator::has()]] para comprobar si un ID de componente ya ha sido registrada. 
Si llama [[yii\di\ServiceLocator::get()]] con una identificación válida, se produce una excepción.

Debido a que los localizadores de servicios a menudo se crean con [configuraciones](concept-configurations.md), se proporciona una propiedad que puede escribir el nombre [[yii\di\ServiceLocator::setComponents()|components]]. Esto le permite configurar y registrar varios componentes a la vez. El siguiente código muestra un arreglo de configuración que se puede utilizar para configurar una aplicación, al mismo tiempo que el registro de la "db", "cache" y "buscar" componentes:

```php
return [
    // ...
    'components' => [
        'db' => [
            'class' => 'yii\db\Connection',
            'dsn' => 'mysql:host=localhost;dbname=demo',
            'username' => 'root',
            'password' => '',
        ],
        'cache' => 'yii\caching\ApcCache',
        'search' => function () {
            return new app\components\SolrService;
        },
    ],
];
```

---

### Guide Es Db Dao (`docs/guide-es/db-dao.md`)

Objetos de Acceso a Bases de Datos
==================================

Construido sobre [PDO](https://www.php.net/manual/es/book.pdo.php), Yii DAO (Objetos de Acceso a Bases de Datos) proporciona una
API orientada a objetos para el acceso a bases de datos relacionales. Es el fundamento para otros métodos de acceso a bases de datos
más avanzados, incluyendo el [constructor de consultas](db-query-builder.md) y [active record](db-active-record.md).

Al utilizar Yii DAO, principalmente vas a tratar con SQLs planos y arrays PHP. Como resultado, esta es la manera más eficiente
de acceder a las bases de datos. Sin embargo, como la sintaxis puede variar para las diferentes bases de datos, utilizando
Yii DAO también significa que tienes que tienes que tomar un esfuerzo adicional para crear una aplicación de database-agnostic.

Yii DAO soporta las siguientes bases de datos:

- [MySQL](https://www.mysql.com/)
- [MariaDB](https://mariadb.com/)
- [SQLite](https://sqlite.org/)
- [PostgreSQL](https://www.postgresql.org/): versión 8.4 o superior.
- [CUBRID](https://www.cubrid.org/): versión 9.3 o superior.
- [Oracle](https://www.oracle.com/database/)
- [MSSQL](https://www.microsoft.com/en-us/sqlserver/default.aspx): versión 2008 o superior.

## Creando Conexiones DB <span id="creating-db-connections"></span>

Para acceder a una base de datos, primero necesitas conectarte a tu bases de datos mediante la creación
de una instancia de [[yii\db\Connection]]:

```php
$db = new yii\db\Connection([
    'dsn' => 'mysql:host=localhost;dbname=example',
    'username' => 'root',
    'password' => '',
    'charset' => 'utf8',
]);
```

Debido a una conexión DB a menudo necesita ser accedido en diferentes lugares, una práctica común es
configurarlo en términos de un [componente de aplicación](structure-application-components.md) como
se muestra a continuación:

```php
return [
    // ...
    'components' => [
        // ...
        'db' => [
            'class' => 'yii\db\Connection',
            'dsn' => 'mysql:host=localhost;dbname=example',
            'username' => 'root',
            'password' => '',
            'charset' => 'utf8',
        ],
    ],
    // ...
];
```

Puedes acceder a la conexión DB mediante la expresión `Yii::$app->db`.

> Tip: Puedes configurar múltiples componentes de aplicación DB si tu aplicación necesita acceder a múltiples bases de datos.

Cuando configuras una conexión DB, deberías siempre especificar el Nombre de Origen de Datos (DSN) mediante la
propiedad [[yii\db\Connection::dsn|dsn]]. El formato del DSN varia para cada diferente base de datos. Por favor consulte el
[manual de PHP](https://www.php.net/manual/es/function.PDO-construct.php) para más detalles. Abajo están algunos ejemplos:

* MySQL, MariaDB: `mysql:host=localhost;dbname=mydatabase`
* SQLite: `sqlite:/path/to/database/file`
* PostgreSQL: `pgsql:host=localhost;port=5432;dbname=mydatabase`
* CUBRID: `cubrid:dbname=demodb;host=localhost;port=33000`
* MS SQL Server (mediante sqlsrv driver): `sqlsrv:Server=localhost;Database=mydatabase`
* MS SQL Server (mediante dblib driver): `dblib:host=localhost;dbname=mydatabase`
* MS SQL Server (mediante mssql driver): `mssql:host=localhost;dbname=mydatabase`
* Oracle: `oci:dbname=//localhost:1521/mydatabase`

Nota que si estás conectándote con una base de datos mediante ODBC, deberías configurar la propiedad [[yii\db\Connection::driverName]]
para que Yii pueda conocer el tipo de base de datos actual. Por ejemplo,

```php
'db' => [
    'class' => 'yii\db\Connection',
    'driverName' => 'mysql',
    'dsn' => 'odbc:Driver={MySQL};Server=localhost;Database=test',
    'username' => 'root',
    'password' => '',
],
```

Además de la propiedad [[yii\db\Connection::dsn|dsn]], a menudo es necesario configurar el [[yii\db\Connection::username|username]]
y [[yii\db\Connection::password|password]]. Por favor consulta [[yii\db\Connection]] para ver la lista completa de propiedades configurables.

> Info: Cuando se crea una instancia de conexión DB, la conexión actual a la base de datos no se establece hasta que
  ejecutes el primer SQL o llames explícitamente al método [[yii\db\Connection::open()|open()]].


## Ejecutando Consultas SQL <span id="executing-sql-queries"></span>

Una vez tienes instanciada una conexión a la base de datos, se pueden ejecutar consultas SQL tomando
los siguientes pasos:

1. Crea un [[yii\db\Command]] con SQL plano;
2. Vincula parámetros (opcional);
3. Llama a uno de los métodos de ejecución SQL con [[yii\db\Command]].

El siguiente ejemplo muestra varias maneras de obtener datos de una base de datos:

```php
$db = new yii\db\Connection(...);

// retorna un conjunto de filas. Cada fila es un array asociativo de columnas de nombres y valores.
// un array vacío es retornado si no hay resultados
$posts = $db->createCommand('SELECT * FROM post')
            ->queryAll();

// retorna una sola fila (la primera fila)
// `false` es retornado si no hay resultados
$post = $db->createCommand('SELECT * FROM post WHERE id=1')
           ->queryOne();

// retorna una sola columna (la primera columna)
// un array vacío es retornado si no hay resultados
$titles = $db->createCommand('SELECT title FROM post')
             ->queryColumn();

// retorna un escalar
// `false` es retornado si no hay resultados
$count = $db->createCommand('SELECT COUNT(*) FROM post')
             ->queryScalar();
```

> Note: Para preservar la precisión, los datos obtenidos de las bases de datos son todos representados como cadenas, incluso si el tipo de columna correspondiente
a la base de datos es numérico.

> Tip: Si necesitas ejecutar una consulta SQL inmediatamente después de establecer una conexión (ej., para establecer una zona horaria o un conjunto de caracteres),
> puedes hacerlo con el evento [[yii\db\Connection::EVENT_AFTER_OPEN]]. Por ejemplo,
>
```php
return [
    // ...
    'components' => [
        // ...
        'db' => [
            'class' => 'yii\db\Connection',
            // ...
            'on afterOpen' => function($event) {
                // $event->sender se refiere a la conexión DB
                $event->sender->createCommand("SET time_zone = 'UTC'")->execute();
            }
        ],
    ],
    // ...
];
```


### Parámetros Vinculados (Binding Parameters) <span id="binding-parameters"></span>

Cuando creamos un comando DB para un SQL con parámetros, nosotros deberíamos casi siempre aprovechar el uso de los parámetros vinculados
para prevenir los ataques de inyección de SQL. Por ejemplo,

```php
$post = $db->createCommand('SELECT * FROM post WHERE id=:id AND status=:status')
           ->bindValue(':id', $_GET['id'])
           ->bindValue(':status', 1)
           ->queryOne();
```

En la sentencia SQL, puedes incrustar uno o múltiples parámetros placeholders (ej. `:id` en el ejemplo anterior). Un parámetro
placeholder debería ser una cadena que empiece con dos puntos. A continuación puedes llamar a uno de los siguientes métodos para
unir los valores de los parámetros vinculados:

* [[yii\db\Command::bindValue()|bindValue()]]: une un solo parámetro
* [[yii\db\Command::bindValues()|bindValues()]]: une múltiples parámetros en una sola llamada
* [[yii\db\Command::bindParam()|bindParam()]]: similar a [[yii\db\Command::bindValue()|bindValue()]] pero también
  soporta las referencias de parámetros vinculados.

El siguiente ejemplo muestra formas alternativas de vincular parámetros:

```php
$params = [':id' => $_GET['id'], ':status' => 1];

$post = $db->createCommand('SELECT * FROM post WHERE id=:id AND status=:status')
           ->bindValues($params)
           ->queryOne();

$post = $db->createCommand('SELECT * FROM post WHERE id=:id AND status=:status', $params)
           ->queryOne();
```

La vinculación parámetros es implementada mediante [sentencias preparadas (prepared statements)](https://www.php.net/manual/es/mysqli.quickstart.prepared-statements.php).
Además de prevenir ataques de inyección de SQL, también puede mejorar el rendimiento preparando una sola vez una sentencia SQL y ejecutándola múltiples veces con diferentes
parámetros. Por ejemplo,

```php
$command = $db->createCommand('SELECT * FROM post WHERE id=:id');

$post1 = $command->bindValue(':id', 1)->queryOne();
$post2 = $command->bindValue(':id', 2)->queryOne();
```

Porque [[yii\db\Command::bindParam()|bindParam()]] soporta parámetros vinculados por referencias, el código de arriba también
puede ser escrito como lo siguiente:

```php
$command = $db->createCommand('SELECT * FROM post WHERE id=:id')
              ->bindParam(':id', $id);

$id = 1;
$post1 = $command->queryOne();

$id = 2;
$post2 = $command->queryOne();
```

Observe que vincula el placeholder a la variable `$id` antes de la ejecución, y entonces cambia el valor de esa variable
antes de cada subsiguiente ejecución (esto se hace a menudo con bucles). Ejecutando consultas de esta manera puede ser
bastante más eficiente que ejecutar una nueva consulta para cada valor diferente del parámetro.


### Ejecutando Consultas Non-SELECT <span id="non-select-queries"></span>

El método `queryXyz()` introducidos en las secciones previas todos tratan con consultas SELECT los cuales recogen los
datos de la base de datos. Para las consultas que no devuelven datos, deberías llamar a el método [[yii\db\Command::execute()]]
en su lugar. Por ejemplo,

```php
$db->createCommand('UPDATE post SET status=1 WHERE id=1')
   ->execute();
```

El método [[yii\db\Command::execute()]] retorna el número de filas afectadas por la ejecución SQL.

Para consultas INSERT, UPDATE y DELETE, en vez de escribir SQLs planos, puedes llamar a [[yii\db\Command::insert()|insert()]],
[[yii\db\Command::update()|update()]], [[yii\db\Command::delete()|delete()]], respectivamente, construyen los correspondientes
SQLs. Estos métodos entrecomillan adecuadamente las tablas y los nombres de columnas y los valores de los parámetros vinculados.
Por ejemplo,

```php
// INSERT (table name, column values)
$db->createCommand()->insert('user', [
    'name' => 'Sam',
    'age' => 30,
])->execute();

// UPDATE (table name, column values, condition)
$db->createCommand()->update('user', ['status' => 1], 'age > 30')->execute();

// DELETE (table name, condition)
$db->createCommand()->delete('user', 'status = 0')->execute();
```

Puedes también llamar a [[yii\db\Command::batchInsert()|batchInsert()]] para insertar múltiples filas de una sola vez,
que es mucho más eficiente que insertar una fila de cada vez:

```php
// table name, column names, column values
$db->createCommand()->batchInsert('user', ['name', 'age'], [
    ['Tom', 30],
    ['Jane', 20],
    ['Linda', 25],
])->execute();
```


## Entrecomillado de Tablas y Nombres de Columna <span id="quoting-table-and-column-names"></span>

Al escribir código de database-agnostic, entrecomillar correctamente los nombres de las tablas y las columnas es a menudo
un dolor de cabeza porque las diferentes bases de datos tienen diferentes reglas para entrecomillar los nombres. Para
solventar este problema, puedes usar la siguiente sintaxis de entrecomillado introducido por Yii:

* `[[column name]]`: encierra con dobles corchetes el nombre de una columna que debe ser entrecomillado;
* `{{table name}}`: encierra con dobles llaves el nombre de una tabla que debe ser entrecomillado.

Yii DAO automáticamente convertirá tales construcciones en un SQL con los correspondientes entrecomillados de los nombres de las columnas o tablas.
Por ejemplo,

```php
// ejecuta esta SQL para MySQL: SELECT COUNT(`id`) FROM `employee`
$count = $db->createCommand("SELECT COUNT([[id]]) FROM {{employee}}")
            ->queryScalar();
```


### Usando Prefijos de Tabla <span id="using-table-prefix"></span>

Si la mayoría de tus tablas de BD utilizan algún prefijo común en sus tablas, puedes usar la función de prefijo de tabla soportado
por Yii DAO.

Primero, especifica el prefijo de tabla mediante la propiedad [[yii\db\Connection::tablePrefix]]:

```php
return [
    // ...
    'components' => [
        // ...
        'db' => [
            // ...
            'tablePrefix' => 'tbl_',
        ],
    ],
];
```

Luego en tu código, siempre que lo necesites para hacer referencia a una tabla cuyo nombre tiene un prefijo, utiliza la sintaxis
`{{%table name}}`. El carácter porcentaje se sustituye con el prefijo de la tabla que has especificado en la configuración de
la conexión DB. Por ejemplo,

```php
// ejecuta esta SQL para MySQL: SELECT COUNT(`id`) FROM `tbl_employee`
$count = $db->createCommand("SELECT COUNT([[id]]) FROM {{%employee}}")
            ->queryScalar();
```


## Realización de Transacciones <span id="performing-transactions"></span>

Cuando se ejecutan múltiples consultas relacionadas en una secuencia, puede que se tengan que envolver en una
transacción para asegurar la integridad de los datos y la consistencia de tu base de datos. Si cualquiera de las consultas
falla, la base de datos debe ser revertida al estado anterior como si ninguna de estas consultas se haya ejecutado.

El siguiente código muestra una manera típica de usar transacciones:

```php
$db->transaction(function($db) {
    $db->createCommand($sql1)->execute();
    $db->createCommand($sql2)->execute();
    // ... ejecutando otras sentencias SQL
});
```

El código de arriba es equivalente a lo siguiente:

```php
$transaction = $db->beginTransaction();

try {
    $db->createCommand($sql1)->execute();
    $db->createCommand($sql2)->execute();
    // ... ejecutando otras sentencias SQL

    $transaction->commit();

} catch(\Exception $e) {

    $transaction->rollBack();

    throw $e;
}
```

Al llamar al método [[yii\db\Connection::beginTransaction()|beginTransaction()]], se inicia una nueva transacción.
La transacción se representa como un objeto [[yii\db\Transaction]] almacenado en la variable `$transaction`. Luego,
las consultas que se ejecutan están encerrados en un bloque `try...catch...`. Si todas las consultas son ejecutadas satisfactoriamente,
el método [[yii\db\Transaction::commit()|commit()]] es llamado para confirmar la transacción. De lo contrario, una excepción
se disparará y se capturará, y el método [[yii\db\Transaction::rollBack()|rollBack()]] es llamado para revertir
los cambios hechos por las consultas antes de que fallara la consulta en la transacción.


### Especificando los Niveles de Aislamiento <span id="specifying-isolation-levels"></span>

Yii también soporta la configuración de [niveles de aislamiento] para tus transacciones. Por defecto, cuando comienza una  nueva transacción,
utilizará el nivel de aislamiento definido por tu sistema de base de datos. Se puede sobrescribir el nivel de aislamiento por defecto de la
siguiente manera,

```php
$isolationLevel = \yii\db\Transaction::REPEATABLE_READ;

$db->transaction(function ($db) {
    ....
}, $isolationLevel);

// or alternatively

$transaction = $db->beginTransaction($isolationLevel);
```

Yii proporciona cuatro constantes para los niveles de aislamiento más comunes:

- [[\yii\db\Transaction::READ_UNCOMMITTED]] - el nivel más bajo, pueden ocurrir lecturas Dirty, lecturas
  Non-repeatable y Phantoms.
- [[\yii\db\Transaction::READ_COMMITTED]] - evita lecturas Dirty.
- [[\yii\db\Transaction::REPEATABLE_READ]] - evita lecturas Dirty y lecturas Non-repeatable.
- [[\yii\db\Transaction::SERIALIZABLE]] - el nivel más fuerte, evita todos los problemas nombrados anteriormente.

Además de usar las constantes de arriba para especificar los niveles de aislamiento, puedes también usar cadenas con
una sintaxis valida soportada por el DBMS que estés usando. Por ejemplo, en PostgreSQL, puedes utilizar `SERIALIZABLE READ ONLY DEFERRABLE`.

Tenga en cuenta que algunos DBMS permiten configuraciones de niveles de aislamiento solo a nivel de conexión. Las transacciones subsiguientes
recibirá el mismo nivel de aislamiento , incluso si no se especifica ninguna. Al utilizar esta característica
es posible que necesites ajustar el nivel de aislamiento para todas las transacciones de forma explícitamente para evitar conflictos
en las configuraciones.
En el momento de escribir esto, solo MSSQL y SQLite serán afectadas.

> Note: SQLite solo soporta dos niveles de aislamiento, por lo que solo se puede usar `READ UNCOMMITTED` y
`SERIALIZABLE`. El uso de otros niveles causará el lanzamiento de una excepción.

> Note: PostgreSQL no permite configurar el nivel de aislamiento antes que la transacción empiece por lo que no se
  puede especificar el nivel de aislamiento directamente cuando empieza la transacción. Se tiene que llamar a
  [[yii\db\Transaction::setIsolationLevel()]] después de que la transacción haya empezado.

[isolation levels]: https://es.wikipedia.org/wiki/Aislamiento_(ACID)#Niveles_de_aislamiento


### Transacciones Anidadas <span id="nesting-transactions"></span>

Si tu DBMS soporta Savepoint, puedes anidar múltiples transacciones como a continuación:

```php
$db->transaction(function ($db) {
    // outer transaction

    $db->transaction(function ($db) {
        // inner transaction
    });
});
```

O alternativamente,

```php
$outerTransaction = $db->beginTransaction();
try {
    $db->createCommand($sql1)->execute();

    $innerTransaction = $db->beginTransaction();
    try {
        $db->createCommand($sql2)->execute();
        $innerTransaction->commit();
    } catch (Exception $e) {
        $innerTransaction->rollBack();
    }

    $outerTransaction->commit();
} catch (Exception $e) {
    $outerTransaction->rollBack();
}
```


## Replicación y División Lectura-Escritura <span id="read-write-splitting"></span>

Muchos DBMS soportan [replicación de bases de datos](https://es.wikipedia.org/wiki/Replicaci%C3%B3n_(inform%C3%A1tica)) para tener
una mejor disponibilidad de la base de datos y un mejor tiempo de respuesta del servidor. Con la replicación de bases
de datos, los datos están replicados en los llamados *servidores maestros* (master servers) y *servidores esclavos*
(slave servers). Todas las escrituras y actualizaciones deben hacerse en el servidor maestro, mientras que las lecturas
se efectuarán en los servidores esclavos.

Para aprovechar las ventajas de la replicación de la base de datos y lograr una división de lecuta-escritura, se puede configurar
el componente [[yii\db\Connection]] como se muestra a continuación:

```php
[
    'class' => 'yii\db\Connection',

    // configuración para el maestro
    'dsn' => 'dsn for master server',
    'username' => 'master',
    'password' => '',

    // configuración para los esclavos
    'slaveConfig' => [
        'username' => 'slave',
        'password' => '',
        'attributes' => [
            // utiliza un tiempo de espera de conexión más pequeña
            PDO::ATTR_TIMEOUT => 10,
        ],
    ],

    // listado de configuraciones de esclavos
    'slaves' => [
        ['dsn' => 'dsn for slave server 1'],
        ['dsn' => 'dsn for slave server 2'],
        ['dsn' => 'dsn for slave server 3'],
        ['dsn' => 'dsn for slave server 4'],
    ],
]
```

La configuración anterior especifica una configuración con un único maestro y múltiples esclavos. Uno de los esclavos
se conectará y se usará para ejecutar consultas de lectura, mientras que el maestro se usará para realizar consultas de
escritura. De este modo la división de lectura-escritura se logra automáticamente con esta configuración, Por ejemplo,

```php
// crea una instancia de Connection usando la configuración anterior
$db = Yii::createObject($config);

// consulta contra uno de los esclavos
$rows = $db->createCommand('SELECT * FROM user LIMIT 10')->queryAll();

// consulta contra el maestro
$db->createCommand("UPDATE user SET username='demo' WHERE id=1")->execute();
```

> Info: Las consultas realizadas llamando a [[yii\db\Command::execute()]] se consideran consultas de escritura,
  mientras que todas las demás se ejecutan mediante alguno de los métodos "query" de [[yii\db\Command]] son consultas
  de lectura. Se puede obtener la conexión de esclavo activa mediante `$db->slave`.

El componente `Connection` soporta el balanceo de carga y la conmutación de errores entre esclavos. Cuando se realiza
una consulta de lectura por primera vez, el componente `Connection` elegirá un esclavo aleatorio e intentará realizar
una conexión a este. Si el esclavo se encuentra "muerto", se intentará con otro. Si no está disponible ningún esclavo, se conectará al maestro. Configurando una [[yii\db\Connection::serverStatusCache|server status cache]], se recordarán los servidores
"muertos" por lo que no se intentará volver a conectar a ellos durante
[[yii\db\Connection::serverRetryInterval|certain period of time]].

> Info: En la configuración anterior, se especifica un tiempo de espera (timeout) de conexión de 10 segundos
  para cada esclavo. Esto significa que si no se puede conectar a un esclavo en 10 segundos, este será considerado
  como "muerto". Se puede ajustar el parámetro basado en el entorno actual.

También se pueden configurar múltiples maestros con múltiples esclavos. Por ejemplo,

```php
[
    'class' => 'yii\db\Connection',

    // configuracion habitual para los maestros
    'masterConfig' => [
        'username' => 'master',
        'password' => '',
        'attributes' => [
            // utilizar un tiempo de espera de conexión más pequeña
            PDO::ATTR_TIMEOUT => 10,
        ],
    ],

    // listado de configuraciones de maestros
    'masters' => [
        ['dsn' => 'dsn for master server 1'],
        ['dsn' => 'dsn for master server 2'],
    ],

    // configuración habitual para esclavos
    'slaveConfig' => [
        'username' => 'slave',
        'password' => '',
        'attributes' => [
            // utilizar un tiempo de espera de conexión más pequeña
            PDO::ATTR_TIMEOUT => 10,
        ],
    ],

    // listado de configuración de esclavos
    'slaves' => [
        ['dsn' => 'dsn for slave server 1'],
        ['dsn' => 'dsn for slave server 2'],
        ['dsn' => 'dsn for slave server 3'],
        ['dsn' => 'dsn for slave server 4'],
    ],
]
```

La configuración anterior especifica dos maestros y cuatro esclavos. El componente `Connection` también da soporte al
balanceo de carga y la conmutación de errores entre maestros igual que hace con los esclavos. La diferencia es que
cuando no se encuentra ningún maestro disponible se lanza una excepción.

> Note: cuando se usa la propiedad [[yii\db\Connection::masters|masters]] para configurar uno o múltiples maestros, se
  ignorarán todas las otras propiedades que especifiquen una conexión de base de datos
  (ej. `dsn`, `username`, `password`), junto con el mismo objeto `Connection`.

Por defecto. las transacciones usan la conexión del maestro. Y dentro de una transacción, todas las operaciones de DB usarán
la conexión del maestro. Por ejemplo,

```php
// la transacción empieza con la conexión al maestro
$transaction = $db->beginTransaction();

try {
    // las dos consultas se ejecutan contra el maestro
    $rows = $db->createCommand('SELECT * FROM user LIMIT 10')->queryAll();
    $db->createCommand("UPDATE user SET username='demo' WHERE id=1")->execute();

    $transaction->commit();
} catch(\Exception $e) {
    $transaction->rollBack();
    throw $e;
}
```

Si se quiere empezar la transacción con una conexión a un esclavo, se debe hacer explícitamente como se muestra a
continuación:

```php
$transaction = $db->slave->beginTransaction();
```

A veces, se puede querer forzar el uso de una conexión maestra para realizar una consulta de lectura. Se puede lograr
usando el método `useMaster()`:

```php
$rows = $db->useMaster(function ($db) {
    return $db->createCommand('SELECT * FROM user LIMIT 10')->queryAll();
});
```

También se puede utilizar directamente estableciendo `$db->enableSlaves` a `false` para que se redirijan todas las
consultas a la conexión del maestro.

## Trabajando con Esquemas de Bases de Datos <span id="database-schema"></span>

Yii DAO proporciona todo un conjunto de métodos que permites manipular el esquema de tu base de datos, tal como
crear nuevas tablas, borrar una columna de una tabla, etc. Estos métodos son listados a continuación:

* [[yii\db\Command::createTable()|createTable()]]: crea una tabla
* [[yii\db\Command::renameTable()|renameTable()]]: renombra una tabla
* [[yii\db\Command::dropTable()|dropTable()]]: remueve una tabla
* [[yii\db\Command::truncateTable()|truncateTable()]]: remueve todas las filas de una tabla
* [[yii\db\Command::addColumn()|addColumn()]]: añade una columna
* [[yii\db\Command::renameColumn()|renameColumn()]]: renombra una columna
* [[yii\db\Command::dropColumn()|dropColumn()]]: remueve una columna
* [[yii\db\Command::alterColumn()|alterColumn()]]: altera una columna
* [[yii\db\Command::addPrimaryKey()|addPrimaryKey()]]: añade una clave primaria
* [[yii\db\Command::dropPrimaryKey()|dropPrimaryKey()]]: remueve una clave primaria
* [[yii\db\Command::addForeignKey()|addForeignKey()]]: añade una clave ajena
* [[yii\db\Command::dropForeignKey()|dropForeignKey()]]: remueve una clave ajena
* [[yii\db\Command::createIndex()|createIndex()]]: crea un indice
* [[yii\db\Command::dropIndex()|dropIndex()]]: remueve un indice

Estos métodos puedes ser usados como se muestra a continuación:

```php
// CREATE TABLE
$db->createCommand()->createTable('post', [
    'id' => 'pk',
    'title' => 'string',
    'text' => 'text',
]);
```

También puedes recuperar la información de definición de una tabla a través
del método [[yii\db\Connection::getTableSchema()|getTableSchema()]] de una conexión DB. Por ejemplo,

```php
$table = $db->getTableSchema('post');
```

El método retorna un objeto [[yii\db\TableSchema]] que contiene la información sobre las columnas de las tablas,
claves primarias, claves ajenas, etc. Toda esta información principalmente es utilizada por el
[constructor de consultas](db-query-builder.md) y [active record](db-active-record.md) para ayudar a
escribir código database-agnostic.

---

### Guide Es Db Migrations (`docs/guide-es/db-migrations.md`)

Migración de Base de Datos
==========================

Durante el curso de desarrollo y mantenimiento de una aplicación con base de datos, la estructura de dicha base de datos
evoluciona tanto como el código fuente. Por ejemplo, durante el desarrollo de una aplicación,
una nueva tabla podría ser necesaria; una vez que la aplicación se encuentra en producción, podría descrubrirse
que debería crearse un índice para mejorar el tiempo de ejecución de una consulta; y así sucesivamente. Debido a los cambios en la estructura de la base de datos
a menudo se requieren cambios en el código, Yii soporta la característica llamada *migración de base de datos*, la cual permite
tener un seguimiento de esos cambios en término de *migración de base de datos*, cuyo versionado es controlado
junto al del código fuente.

Los siguientes pasos muestran cómo una migración puede ser utilizada por un equipo durante el desarrollo:

1. Tim crea una nueva migración (por ej. crea una nueva table, cambia la definición de una columna, etc.).
2. Tim hace un commit con la nueva migración al sistema de control de versiones (por ej. Git, Mercurial).
3. Doug actualiza su repositorio desde el sistema de control de versiones y recibe la nueva migración.
4. Doug aplica dicha migración a su base de datos local de desarrollo, de ese modo sincronizando su base de datos
   y reflejando los cambios que hizo Tim.

Los siguientes pasos muestran cómo hacer una puesta en producción con una migración de base de datos:

1. Scott crea un tag de lanzamiento en el repositorio del proyecto que contiene algunas migraciones de base de datos.
2. Scott actualiza el código fuente en el servidor de producción con el tag de lanzamiento.
3. Scott aplica cualquier migración de base de datos acumulada a la base de datos de producción.

Yii provee un grupo de herramientas de línea de comandos que te permite:

* crear nuevas migraciones;
* aplicar migraciones;
* revertir migraciones;
* re-aplicar migraciones;
* mostrar el historial y estado de migraciones.

Todas esas herramientas son accesibles a través del comando `yii migrate`. En esta sección describiremos en detalle
cómo lograr varias tareas utilizando dichas herramientas. Puedes a su vez ver el uso de cada herramienta a través del comando
de ayuda `yii help migrate`.

> Tip: las migraciones pueden no sólo afectar un esquema de base de datos sino también ajustar datos existentes para que encajen en el nuevo esquema, crear herencia RBAC
  o también limpiar el cache.


## Creando Migraciones <span id="creating-migrations"></span>

Para crear una nueva migración, ejecuta el siguiente comando:

```
yii migrate/create <name>
```

El argumento requerido `name` da una pequeña descripción de la nueva migración. Por ejemplo, si
la migración se trata acerca de crear una nueva tabla llamada *news*, podrías utilizar el nombre `create_news_table`
y ejecutar el siguiente comando:

```
yii migrate/create create_news_table
```

> Note: Debido a que el argumento `name` será utilizado como parte del nombre de clase de la migración generada,
  sólo debería contener letras, dígitos, y/o guines bajos.

El comando anterior un nuevo archivo de clase PHP llamado `m150101_185401_create_news_table.php`
en el directorio `@app/migrations`. El archivo contendrá el siguiente código, que principalmente declara
una clase de tipo migración `m150101_185401_create_news_table` con el siguiente esqueleto de código:

```php
<?php

use yii\db\Migration;

class m150101_185401_create_news_table extends Migration
{
    public function up()
    {

    }

    public function down()
    {
        echo "m101129_185401_create_news_table cannot be reverted.\n";

        return false;
    }

    /*
    // Use safeUp/safeDown to run migration code within a transaction
    public function safeUp()
    {
    }

    public function safeDown()
    {
    }
    */
}
```

Cada migración de base de datos es definida como una clase PHP que extiende de [[yii\db\Migration]]. La nombre de clase
de la migración es generado automáticamente en el formato `m<YYMMDD_HHMMSS>_<Name>`, donde

* `<YYMMDD_HHMMSS>` se refiere a la marca de tiempo UTC en la cual el comando de migración fue ejecutado.
* `<Name>` es el mismo valor del argumento `name` provisto al ejecutar el comando.

En la clase de la migración, se espera que tu escribas código en el método `up()`, que realiza los cambios en la base de datos.
Podrías también querer introducir código en el método `down()`, que debería revertir los cambios realizados por `up()`. El método `up()` es llamado
cuando actualizas la base de datos con esta migración, mientras que el método `down()` es llamado cuando reviertes dicha migración.
El siguiente código muestra cómo podrías implementar la clase de migración para crear la tabla `news`:

```php
<?php

use yii\db\Schema;
use yii\db\Migration;

class m150101_185401_create_news_table extends Migration
{
    public function up()
    {
        $this->createTable('news', [
            'id' => Schema::TYPE_PK,
            'title' => Schema::TYPE_STRING . ' NOT NULL',
            'content' => Schema::TYPE_TEXT,
        ]);
    }

    public function down()
    {
        $this->dropTable('news');
    }
}
```

> Info: No todas las migraciones son reversibles. Por ejemplo, si el método `up()` elimina un registro en una tabla, podrías 
  no ser capáz de recuperarla en el método `down()`. A veces, podrías ser simplemente demasiado perezoso para implementar
  el método `down()`, debido a que no es muy común revertir migraciones de base de datos. En este caso, deberías devolver
  `false` en el método `down()` para indicar que dicha migración no es reversible.

La clase de migración de base de datos [[yii\db\Migration]] expone una conexión a la base de datos mediante la propiedad [[yii\db\Migration::db|db]].
Puedes utilizar esto para manipular el esquema de la base de datos utilizando métodos como se describen en
[Trabajando con Esquemas de Base de Datos](db-dao.md#database-schema).

En vez de utilizar tipos físicos, al crear tablas o columnas deberías utilizar los *tipos abstractos*
así las migraciones son independientes de algún DBMS específico. La clase [[yii\db\Schema]] define
un grupo de constantes que representan los tipos abstractos soportados. Dichas constantes son llamadas utilizando el formato
de `TYPE_<Name>`. Por ejemplo, `TYPE_PK` se refiere al tipo clave primaria auto-incremental; `TYPE_STRING`
se refiere al tipo string. Cuando se aplica una migración a una base de datos en particular, los tipos abstractos
serán traducidos a los tipos físicos correspondientes. En el caso de MySQL, `TYPE_PK` será transformado
en `int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY`, mientras `TYPE_STRING` se vuelve `varchar(255)`.

Puedes agregar restricciones adicionales al utilizar tipos abstractos. En el ejemplo anterior, ` NOT NULL` es agregado
a `Schema::TYPE_STRING` para especificar que la columna no puede ser `null`.

> Info: El mapeo entre tipos abstractos y tipos físicos es especificado en
  la propiedad [[yii\db\QueryBuilder::$typeMap|$typeMap]] en cada clase concreta `QueryBuilder`.

Desde la versión 2.0.6, puedes hacer uso del recientemente introducido generador de esquemas, el cual provee una forma más conveniente de definir las columnas.
De esta manera, la migración anterior podría ser escrita así:

```php
<?php

use yii\db\Migration;

class m150101_185401_create_news_table extends Migration
{
    public function up()
    {
        $this->createTable('news', [
            'id' => $this->primaryKey(),
            'title' => $this->string()->notNull(),
            'content' => $this->text(),
        ]);
    }

    public function down()
    {
        $this->dropTable('news');
    }
}
```

Existe una lista de todos los métodos disponibles para la definición de tipos de columna en la API de la documentación de [[yii\db\SchemaBuilderTrait]].


## Generar Migraciones <span id="generating-migrations"></span>

Desde la versión 2.0.7 la consola provee una manera muy conveniente de generar migraciones.

Si el nombre de la migración tiene una forma especial, por ejemplo `create_xxx_table` o `drop_xxx_table` entonces el archivo de la migración generada
contendrá código extra, en este caso para crear/eliminar tablas.
A continuación se describen todas estas variantes.

### Crear Tabla

```php
yii migrate/create create_post_table
```

esto genera

```php
/**
 * Handles the creation for table `post`.
 */
class m150811_220037_create_post_table extends Migration
{
    /**
     * {@inheritdoc}
     */
    public function up()
    {
        $this->createTable('post', [
            'id' => $this->primaryKey()
        ]);
    }

    /**
     * {@inheritdoc}
     */
    public function down()
    {
        $this->dropTable('post');
    }
}
```

Para crear las columnas en ese momento, las puedes especificar vía la opción `--fields`.

```php
yii migrate/create create_post_table --fields="title:string,body:text"
```

genera

```php
/**
 * Handles the creation for table `post`.
 */
class m150811_220037_create_post_table extends Migration
{
    /**
     * {@inheritdoc}
     */
    public function up()
    {
        $this->createTable('post', [
            'id' => $this->primaryKey(),
            'title' => $this->string(),
            'body' => $this->text(),
        ]);
    }

    /**
     * {@inheritdoc}
     */
    public function down()
    {
        $this->dropTable('post');
    }
}

```

Puedes especificar más parámetros para las columnas.

```php
yii migrate/create create_post_table --fields="title:string(12):notNull:unique,body:text"
```

genera

```php
/**
 * Handles the creation for table `post`.
 */
class m150811_220037_create_post_table extends Migration
{
    /**
     * {@inheritdoc}
     */
    public function up()
    {
        $this->createTable('post', [
            'id' => $this->primaryKey(),
            'title' => $this->string(12)->notNull()->unique(),
            'body' => $this->text()
        ]);
    }

    /**
     * {@inheritdoc}
     */
    public function down()
    {
        $this->dropTable('post');
    }
}
```

> Note: la clave primaria es automáticamente agragada y llamada `id` por defecto. Si quieres utilizar otro nombre puedes
> especificarlo así `--fields="name:primaryKey"`.

#### Claves Foráneas

Desde 2.0.8 el generador soporta claves foráneas utilizando la palabra clave `foreignKey`.

```php
yii migrate/create create_post_table --fields="author_id:integer:notNull:foreignKey(user),category_id:integer:defaultValue(1):foreignKey,title:string,body:text"
```

genera

```
/* Detailed source-code truncated for AI context efficiency. */
```

La posición de la palabra clave `foreignKey` en la descripción de la columna
no cambia el código generado. Esto significa:

- `author_id:integer:notNull:foreignKey(user)`
- `author_id:integer:foreignKey(user):notNull`
- `author_id:foreignKey(user):integer:notNull`

Todas generan el mismo código.

La palabra clave `foreignKey` puede tomar un parámetro entre paréntesis el cual
será el nombre de la tabla relacionada por la clave foránea generada. Si no se pasa ningún parámetro
el nombre de la tabla será deducido en base al nombre de la columna.

En el ejemplo anterior `author_id:integer:notNull:foreignKey(user)` generará
una columna llamada `author_id` con una clave foránea a la tabla `user` mientras
`category_id:integer:defaultValue(1):foreignKey` generará
`category_id` con una clave foránea a la tabla `category`.

### Eliminar Tabla

```php
yii migrate/create drop_post_table --fields="title:string(12):notNull:unique,body:text"
```

genera

```php
class m150811_220037_drop_post_table extends Migration
{
    public function up()
    {
        $this->dropTable('post');
    }

    public function down()
    {
        $this->createTable('post', [
            'id' => $this->primaryKey(),
            'title' => $this->string(12)->notNull()->unique(),
            'body' => $this->text()
        ]);
    }
}
```

### Agregar Columna

Si el nombre de la migración está en la forma `add_xxx_column_to_yyy_table` entonces el archivo generado contendrá
las declaraciones `addColumn` y `dropColumn` necesarias.

Para agregar una columna:

```php
yii migrate/create add_position_column_to_post_table --fields="position:integer"
```

genera

```php
class m150811_220037_add_position_column_to_post_table extends Migration
{
    public function up()
    {
        $this->addColumn('post', 'position', $this->integer());
    }

    public function down()
    {
        $this->dropColumn('post', 'position');
    }
}
```

### Eliminar Columna

Si el nombre de la migración está en la forma `drop_xxx_column_from_yyy_table` entonces el archivo generado contendrá
las declaraciones `addColumn` y `dropColumn` necesarias.

```php
yii migrate/create drop_position_column_from_post_table --fields="position:integer"
```

genera

```php
class m150811_220037_drop_position_column_from_post_table extends Migration
{
    public function up()
    {
        $this->dropColumn('post', 'position');
    }

    public function down()
    {
        $this->addColumn('post', 'position', $this->integer());
    }
}
```

### Agregar Tabla de Unión

Si el nombre de la migración está en la forma `create_junction_table_for_xxx_and_yyy_tables` entonces se generará el código necesario
para una tabla de unión.

```php
yii migrate/create create_junction_table_for_post_and_tag_tables --fields="created_at:dateTime"
```

genera

```
/* Detailed source-code truncated for AI context efficiency. */
```

### Migraciones Transaccionales <span id="transactional-migrations"></span>

Al ejecutar migraciones complejas de BD, es importante asegurarse que todas las migraciones funcionen o fallen como una unidad
así la base de datos puede mantener integridad y consistencia. Para alcanzar este objetivo, se recomienda que
encierres las operación de la BD de cada migración en una [transacción](db-dao.md#performing-transactions).

Una manera simple de implementar migraciones transaccionales es poniendo el código de las migraciones en los métodos `safeUp()` y `safeDown()`.
Estos métodos se diferencias con `up()` y `down()` en que son encerrados implícitamente en una transacción.
Como resultado, si alguna de las operaciones dentro de estos métodos falla, todas las operaciones previas son automáticamente revertidas.

En el siguiente ejemplo, además de crear la tabla `news` también insertamos un registro inicial dentro de la dicha tabla.

```php
<?php

use yii\db\Migration;

class m150101_185401_create_news_table extends Migration
{
    public function safeUp()
    {
        $this->createTable('news', [
            'id' => $this->primaryKey(),
            'title' => $this->string()->notNull(),
            'content' => $this->text(),
        ]);

        $this->insert('news', [
            'title' => 'test 1',
            'content' => 'content 1',
        ]);
    }

    public function safeDown()
    {
        $this->delete('news', ['id' => 1]);
        $this->dropTable('news');
    }
}
```

Ten en cuenta que usualmente cuando ejecutas múltiples operaciones en la BD en `safeUp()`, deberías revertir su orden de ejecución
en `safeDown()`. En el ejemplo anterior primero creamos la tabla y luego insertamos la finla en `safeUp()`; mientras
que en `safeDown()` primero eliminamos el registro y posteriormente eliminamos la tabla.

> Note: No todos los DBMS soportan transacciones. Y algunas consultas a la BD no pueden ser puestas en transacciones. Para algunos ejemplos,
  por favor lee acerca de [commits implícitos](https://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html). En estos casos,
  deberías igualmente implementar `up()` y `down()`.


### Métodos de Acceso a la Base de Datos <span id="db-accessing-methods"></span>

La clase base [[yii\db\Migration]] provee un grupo de métodos que te permiten acceder y manipular bases de datos.
Podrías encontrar que estos métodos son nombrados de forma similar a los [métodos DAO](db-dao.md) provistos por la clase [[yii\db\Command]].
Por ejemplo, el método [[yii\db\Migration::createTable()]] te permite crear una nueva tabla,
tal como lo hace [[yii\db\Command::createTable()]].

El beneficio de utilizar lo métodos provistos por [[yii\db\Migration]] es que no necesitas explícitamente
crear instancias de [[yii\db\Command]], y la ejecución de cada método mostrará automáticamente mensajes útiles
diciéndote qué operaciones de la base de datos se realizaron y cuánto tiempo tomaron.

Debajo hay una lista de todos los métodos de acceso a la base de datos:

* [[yii\db\Migration::execute()|execute()]]: ejecuta una declaración SQL
* [[yii\db\Migration::insert()|insert()]]: inserta un único registro
* [[yii\db\Migration::batchInsert()|batchInsert()]]: inserta múltiples registros
* [[yii\db\Migration::update()|update()]]: actualiza registros
* [[yii\db\Migration::delete()|delete()]]: elimina registros
* [[yii\db\Migration::createTable()|createTable()]]: crea una nueva tabla
* [[yii\db\Migration::renameTable()|renameTable()]]: renombra una tabla
* [[yii\db\Migration::dropTable()|dropTable()]]: elimina una tabla
* [[yii\db\Migration::truncateTable()|truncateTable()]]: elimina todos los registros de una tabla
* [[yii\db\Migration::addColumn()|addColumn()]]: agrega una columna
* [[yii\db\Migration::renameColumn()|renameColumn()]]: renombra una columna
* [[yii\db\Migration::dropColumn()|dropColumn()]]: elimina una columna
* [[yii\db\Migration::alterColumn()|alterColumn()]]: modifica una columna
* [[yii\db\Migration::addPrimaryKey()|addPrimaryKey()]]: agrega una clave primaria
* [[yii\db\Migration::dropPrimaryKey()|dropPrimaryKey()]]: elimina una clave primaria
* [[yii\db\Migration::addForeignKey()|addForeignKey()]]: agrega una clave foránea
* [[yii\db\Migration::dropForeignKey()|dropForeignKey()]]: elimina una clave foránea
* [[yii\db\Migration::createIndex()|createIndex()]]: crea un índice
* [[yii\db\Migration::dropIndex()|dropIndex()]]: elimina un índice
* [[yii\db\Migration::addCommentOnColumn()|addCommentOnColumn()]]: agrega un comentario a una columna
* [[yii\db\Migration::dropCommentFromColumn()|dropCommentFromColumn()]]: elimina un comentario de una columna
* [[yii\db\Migration::addCommentOnTable()|addCommentOnTable()]]: agrega un comentario a una tabla
* [[yii\db\Migration::dropCommentFromTable()|dropCommentFromTable()]]: elimina un comentario de una tabla

> Info: [[yii\db\Migration]] no provee un método de consulta a la base de datos. Esto es porque normalmente no necesitas
  mostrar mensajes detallados al traer datos de una base de datos. También se debe a que puedes utilizar el poderoso
  [Query Builder](db-query-builder.md) para generar y ejecutar consultas complejas.

> Note: Al manipular datos utilizando una migración podrías encontrar que utilizando tus clases [Active Record](db-active-record.md)
> para esto podría ser útil ya que algo de la lógica ya está implementada ahí. Ten en cuenta de todos modos, que en contraste con
> el código escrito en las migraciones, cuya naturaleza es permanecer constante por siempre, la lógica de la aplicación está sujeta a cambios.
> Entonces al utilizar Active Record en migraciones, los cambios en la lógica en la capa Active Record podrían accidentalmente romper
> migraciones existentes. Por esta razón, el código de las migraciones debería permanecer independiente de determinada lógica de la aplicación
> tal como clases Active Record.


## Aplicar Migraciones <span id="applying-migrations"></span>

To upgrade a database to its latest structure, you should apply all available new migrations using the following command:
Para actualizar una base de datos a su última estructura, deberías aplicar todas las nuevas migraciones utilizando el siguiente comando:

```
yii migrate
```

Este comando listará todas las migraciones que no han sido aplicadas hasta el momento. Si confirmas que quieres aplicar
dichas migraciones, se correrá el método `up()` o `safeUp()` en cada clase de migración nueva, una tras otra,
en el orden de su valor de marca temporal. Si alguna de las migraciones falla, el comando terminará su ejecución sin aplicar
el resto de las migraciones.

> Tip: En caso de no disponer de la línea de comandos en el servidor, podrías intentar utilizar
> la extensión [web shell](https://github.com/samdark/yii2-webshell).

Por cada migración aplicada correctamente, el comando insertará un registro en la base de datos, en la tabla llamada
`migration` para registrar la correcta aplicación de la migración. Esto permitirá a la herramienta de migración identificar
cuáles migraciones han sido aplicadas y cuáles no.

> Info: La herramienta de migración creará automáticamente la tabla  `migration` en la base de datos especificada
  en la opción [[yii\console\controllers\MigrateController::db|db]] del comando. Por defecto, la base de datos
  es especificada en el [componente de aplicación](structure-application-components.md) `db`.

A veces, podrías sólo querer aplicar una o algunas pocas migraciones, en vez de todas las migraciones disponibles.
Puedes hacer esto el número de migraciones que quieres aplicar al ejecutar el comando.
Por ejemplo, el siguiente comando intentará aplicar las tres siguientes migraciones disponibles:

```
yii migrate 3
```

Puedes además explícitamente especificar una migración en particular a la cual la base de datos debería migrar
utilizando el comando `migrate/to` de acuerdo a uno de los siguientes formatos:

```
yii migrate/to 150101_185401                      # utiliza la marca temporal para especificar la migración
yii migrate/to "2015-01-01 18:54:01"              # utiliza un string que puede ser analizado por strtotime()
yii migrate/to m150101_185401_create_news_table   # utiliza el nombre completo
yii migrate/to 1392853618                         # utiliza el tiempo UNIX
```

Si hubiera migraciones previas a la especificada sin aplicar, estas serán aplicadas antes de que la migración especificada
sea aplicada.

Si la migración especificada ha sido aplicada previamente, cualquier migración aplicada posteriormente será revertida.


## Revertir Migraciones <span id="reverting-migrations"></span>

Para revertir (deshacer) una o varias migraciones ya aplicadas, puedes ejecutar el siguiente comando:

```
yii migrate/down     # revierte la más reciente migración aplicada
yii migrate/down 3   # revierte las 3 últimas migraciones aplicadas
```

> Note: No todas las migraciones son reversibles. Intentar revertir tales migraciones producirá un error y detendrá
  completamente el proceso de reversión.


## Rehacer Migraciones <span id="redoing-migrations"></span>

Rehacer (re-ejecutar) migraciones significa primero revertir las migraciones especificadas y luego aplicarlas nuevamente. Esto puede hacerse
de esta manera:

```
yii migrate/redo        # rehace la más reciente migración aplicada
yii migrate/redo 3      # rehace las 3 últimas migraciones aplicadas
```

> Note: Si una migración no es reversible, no tendrás posibilidades de rehacerla.


## Listar Migraciones <span id="listing-migrations"></span>

Para listar cuáles migraciones han sido aplicadas y cuáles no, puedes utilizar los siguientes comandos:

```
yii migrate/history     # muestra las últimas 10 migraciones aplicadas
yii migrate/history 5   # muestra las últimas 5 migraciones aplicadas
yii migrate/history all # muestra todas las migraciones aplicadas

yii migrate/new         # muestra las primeras 10 nuevas migraciones
yii migrate/new 5       # muestra las primeras 5 nuevas migraciones
yii migrate/new all     # muestra todas las nuevas migraciones
```


## Modificar el Historial de Migraciones <span id="modifying-migration-history"></span>

En vez de aplicar o revertir migraciones, a veces simplemente quieres marcar que tu base de datos
ha sido actualizada a una migración en particular. Esto sucede normalmente cuando cambias manualmente la base de datos
a un estado particular y no quieres que la/s migración/es de ese cambio sean re-aplicadas posteriormente. Puedes alcanzar este objetivo
con el siguiente comando:

```
yii migrate/mark 150101_185401                      # utiliza la marca temporal para especificar la migración
yii migrate/mark "2015-01-01 18:54:01"              # utiliza un string que puede ser analizado por strtotime()
yii migrate/mark m150101_185401_create_news_table   # utiliza el nombre completo
yii migrate/mark 1392853618                         # utiliza el tiempo UNIX
```

El comando modificará la tabla `migration` agregando o eliminado ciertos registros para indicar que en la base de datos
han sido aplicadas las migraciones hasta la especificada. Ninguna migración será aplicada ni revertida por este comando.


## Personalizar Migraciones <span id="customizing-migrations"></span>

Hay varias maneras de personalizar el comando de migración.


### Utilizar Opciones de la Línea de Comandos <span id="using-command-line-options"></span>

El comando de migración trae algunas opciones de línea de comandos que pueden ser utilizadas para personalizar su comportamiento:

* `interactive`: boolean (por defecto `true`), especificar si se debe ejecutar la migración en modo interactivo.
  Cuando se indica `true`, se le pedirá confirmación al usuario antes de ejecutar ciertas acciones.
  Puedes querer definirlo como `false` si el comando está siendo utilizado como un proceso de fondo.

* `migrationPath`: string (por defecto `@app/migrations`), especifica el directorio que contiene todos los archivos
  de clase de las migraciones. Este puede ser especificado tanto como una ruta a un directorio un [alias](concept-aliases.md) de ruta.
  Ten en cuenta que el directorio debe existir, o el comando disparará un error.

* `migrationTable`: string (por defecto `migration`), especifica el nombre de la tabla de la base de datos que almacena
  información del historial de migraciones. Dicha tabla será creada por el comando en caso de que no exista.
  Puedes también crearla manualmente utilizando la estructura `version varchar(255) primary key, apply_time integer`.

* `db`: string (por defecto `db`), especifica el ID del [componente de aplicación](structure-application-components.md) de la base de datos.
  Esto representa la base de datos que será migrada en este comando.

* `templateFile`: string (por defecto `@yii/views/migration.php`), especifica la ruta al template
  utilizado para generar el esqueleto de los archivos de clases de migración. Puede ser especificado tanto como una ruta a un archivo
  como una [alias](concept-aliases.md) de una ruta. El template es un archivo PHP en el cual puedes utilizar una variable predefinida
  llamada `$className` para obtener el nombre de clase de la migración.

* `generatorTemplateFiles`: array (por defecto `[
        'create_table' => '@yii/views/createTableMigration.php',
        'drop_table' => '@yii/views/dropTableMigration.php',
        'add_column' => '@yii/views/addColumnMigration.php',
        'drop_column' => '@yii/views/dropColumnMigration.php',
        'create_junction' => '@yii/views/createTableMigration.php'
  ]`), especifica los templates utilizados para generar las migraciones. Ver "[Generar Migraciones](#generating-migrations)"
  para más detalles.

* `fields`: array de strings de definiciones de columna utilizado por el código de migración. Por defecto `[]`. El formato de cada
  definición es `COLUMN_NAME:COLUMN_TYPE:COLUMN_DECORATOR`. Por ejemplo, `--fields=name:string(12):notNull` produce
  una columna string de tamaño 12 que es not `null`.

El siguiente ejemplo muestra cómo se pueden utilizar estas opciones.

Por ejemplo, si queremos migrar un módulo `forum` cuyos arhivos de migración
están ubicados dentro del directorio `migrations` del módulo, podemos utilizar el siguientedocs/guide-es/db-migrations.md
comando:

```
# realiza las migraciones de un módulo forum sin interacción del usuario
yii migrate --migrationPath=@app/modules/forum/migrations --interactive=0
```


### Configurar el Comando Globalmente <span id="configuring-command-globally"></span>

En vez de introducir los valores de las opciones cada vez que ejecutas un comandod e migración, podrías configurarlos
de una vez por todas en la configuración de la aplicación como se muestra a continuación:

```php
return [
    'controllerMap' => [
        'migrate' => [
            'class' => 'yii\console\controllers\MigrateController',
            'migrationTable' => 'backend_migration',
        ],
    ],
];
```

Con esta configuración, cada vez que ejecutes un comando de migración, la tabla `backend_migration`
será utilizada para registrar el historial de migraciones. No necesitarás volver a especificarla con la opción `migrationTable`
de la línea de comandos.


## Migrar Múltiples Bases de Datos <span id="migrating-multiple-databases"></span>

Por defecto, las migraciones son aplicadas en la misma base de datos especificada en el [componente de aplicación](structure-application-components.md) `db`.
Si quieres que sean aplicadas en una base de datos diferente, puedes especificar la opción `db` como se muestra a continuación,

```
yii migrate --db=db2
```

El comando anterior aplicará las migraciones en la base de datos `db2`.

A veces puede suceder que quieras aplicar *algunas* de las migraciones a una base de datos, mientras algunas otras
a una base de datos distinta. Para lograr esto, al implementar una clase de migración debes especificar explícitamente el ID del componente DB
que la migración debe utilizar, como a continuación:

```php
<?php

use yii\db\Migration;

class m150101_185401_create_news_table extends Migration
{
    public function init()
    {
        $this->db = 'db2';
        parent::init();
    }
}
```

La migración anterior se aplicará a `db2`, incluso si especificas una base de datos diferente en la opción `db` de la
línea de comandos. Ten en cuenta que el historial aún será registrado in la base de datos especificada en la opción `db` de la línea de comandos.

Si tienes múltiples migraciones que utilizan la misma base de datos, es recomandable que crees una clase base de migración 
con el código `init()` mostrado. Entonces cada clase de migración puede extender de esa clase base.

> Tip: Aparte de definir la propiedad [[yii\db\Migration::db|db]], puedes también operar en diferentes bases de datos
  creando nuevas conexiones de base de datos en tus clases de migración. También puedes utilizar [métodos DAO](db-dao.md)
  con esas conexiones para manipular diferentes bases de datos.

Another strategy that you can take to migrate multiple databases is to keep migrations for different databases in
different migration paths. Then you can migrate these databases in separate commands like the following:
Otra estrategia que puedes seguir para migrar múltiples bases de datos es mantener las migraciones para diferentes bases de datos en
distintas rutas de migración. Entonces podrías migrar esas bases de datos en comandos separados como a continuación:

```
yii migrate --migrationPath=@app/migrations/db1 --db=db1
yii migrate --migrationPath=@app/migrations/db2 --db=db2
...
```

El primer comando aplicará las migraciones que se encuentran en `@app/migrations/db1` en la base de datos `db1`, el segundo comando
aplicará las migraciones que se encuentran en `@app/migrations/db2` en `db2`, y así sucesivamente.

---

### Guide Es Db Query Builder (`docs/guide-es/db-query-builder.md`)

Constructor de Consultas
========================

> Note: Esta sección está en desarrollo.

Yii proporciona una capa de acceso básico a bases de datos como se describe en la sección
[Objetos de Acceso a Bases de Datos](db-dao.md). La capa de acceso a bases de datos proporciona un método de bajo
nivel (low-level) para interaccionar con la base de datos. Aunque a veces puede ser útil la escritura de sentencias
SQLs puras, en otras situaciones puede ser pesado y propenso a errores. Otra manera de tratar con bases de datos puede
ser el uso de Constructores de Consultas (Query Builder). El Constructor de Consultas proporciona un medio orientado a
objetos para generar las consultas que se ejecutarán.

Un uso típico de Constructor de Consultas puede ser el siguiente:

```php
$rows = (new \yii\db\Query())
    ->select('id, name')
    ->from('user')
    ->limit(10)
    ->all();

// que es equivalente al siguiente código:

$query = (new \yii\db\Query())
    ->select('id, name')
    ->from('user')
    ->limit(10);

//  Crear un comando. Se puede obtener la consulta SQL actual utilizando $command->sql
$command = $query->createCommand();

// Ejecutar el comando:
$rows = $command->queryAll();
```

Métodos de Consulta
-------------------

Como se puede observar, primero se debe tratar con [[yii\db\Query]]. En realidad, `Query` sólo se encarga de
representar diversa información de la consulta. La lógica para generar la consulta se efectúa mediante
[[yii\db\QueryBuilder]] cuando se llama al método `createCommand()`, y la ejecución de la consulta la efectúa
[[yii\db\Command]].

Se ha establecido, por convenio, que [[yii\db\Query]] proporcione un conjunto de métodos de consulta comunes que
construirán la consulta, la ejecutarán, y devolverán el resultado. Por ejemplo:

- [[yii\db\Query::all()|all()]]: construye la consulta, la ejecuta y devuelve todos los resultados en formato de array.
- [[yii\db\Query::one()|one()]]: devuelve la primera fila del resultado.
- [[yii\db\Query::column()|column()]]: devuelve la primera columna del resultado.
- [[yii\db\Query::scalar()|scalar()]]: devuelve la primera columna en la primera fila del resultado.
- [[yii\db\Query::exists()|exists()]]: devuelve un valor indicando si la el resultado devuelve algo.
- [[yii\db\Query::count()|count()]]: devuelve el resultado de la consulta `COUNT`. Otros métodos similares incluidos
  son `sum($q)`, `average($q)`, `max($q)`, `min($q)`, que soportan las llamadas funciones de agregación. El parámetro
  `$q` es obligatorio en estos métodos y puede ser el nombre de la columna o expresión.

Construcción de Consultas
-------------------------

A continuación se explicará como construir una sentencia SQL que incluya varias clausulas. Para simplificarlo, usamos
`$query` para representar el objeto [[yii\db\Query]]:

### `SELECT`

Para formar una consulta `SELECT` básica, se necesita especificar que columnas y de que tablas se seleccionarán:

```php
$query->select('id, name')
    ->from('user');
```

Las opciones de select se pueden especificar como una cadena de texto (string) separada por comas o como un array. La
sintaxis del array es especialmente útil cuando se forma la selección dinámicamente.

```php
$query->select(['id', 'name'])
    ->from('user');
```

> Info: Se debe usar siempre el formato array si la clausula `SELECT` contiene expresiones SQL. Esto se debe a
  que una expresión SQL como `CONCAT(first_name, last_name) AS full_name` puede contener comas. Si se junta con otra
  cadena de texto de otra columna, puede ser que la expresión se divida en varias partes por comas, esto puede
  conllevar a errores.

Cuando se especifican columnas, se pueden incluir los prefijos de las tablas o alias de columnas, ej.  `user.id`,
`user.id AS user_id`. Si se usa un array para especificar las columnas, también se pueden usar las claves del array
para especificar los alias de columna, ej. `['user_id' => 'user.id', 'user_name' => 'user.name']`.

A partir de la versión 2.0.1, también se pueden seleccionar subconsultas como columnas. Por ejemplo:

```php
$subQuery = (new Query)->select('COUNT(*)')->from('user');
$query = (new Query)->select(['id', 'count' => $subQuery])->from('post');
// $query representa la siguiente sentencia SQL:
// SELECT `id`, (SELECT COUNT(*) FROM `user`) AS `count` FROM `post`
```

Para seleccionar filas distintas, se puede llamar a `distinct()`, como se muestra a continuación:

```php
$query->select('user_id')->distinct()->from('post');
```

### `FROM`

Para especificar de que tabla(s) se quieren seleccionar los datos, se llama a `from()`:

```php
$query->select('*')->from('user');
```

Se pueden especificar múltiples tablas usando una cadena de texto separado por comas o un array. Los nombres de tablas
pueden contener prefijos de esquema (ej. `'public.user'`) y/o alias de tablas (ej. `'user u'). El método
entrecomillara automáticamente los nombres de tablas a menos que contengan algún paréntesis (que significa que se
proporciona la tabla como una subconsulta o una expresión de BD). Por ejemplo:

```php
$query->select('u.*, p.*')->from(['user u', 'post p']);
```

Cuando se especifican las tablas como un array, también se pueden usar las claves de los arrays como alias de tablas
(si una tabla no necesita alias, no se usa una clave en formato texto). Por ejemplo:

```php
$query->select('u.*, p.*')->from(['u' => 'user', 'p' => 'post']);
```

Se puede especificar una subconsulta usando un objeto `Query`. En este caso, la clave del array correspondiente se
usará como alias para la subconsulta.

```php
$subQuery = (new Query())->select('id')->from('user')->where('status=1');
$query->select('*')->from(['u' => $subQuery]);
```

### `WHERE`

Habitualmente se seleccionan los datos basándose en ciertos criterios. El Constructor de Consultas tiene algunos
métodos útiles para especificarlos, el más poderoso de estos es `where`, y se puede usar de múltiples formas.

La manera más simple para aplicar una condición es usar una cadena de texto:

```php
$query->where('status=:status', [':status' => $status]);
```

Cuando se usan cadenas de texto, hay que asegurarse que se unen los parámetros de la consulta, no crear una consulta
mediante concatenación de cadenas de texto. El enfoque anterior es seguro, el que se muestra a continuación, no lo es:

```php
$query->where("status=$status"); // Peligroso!
```

En lugar de enlazar los valores de estado inmediatamente, se puede hacer usando `params` o `addParams`:

```php
$query->where('status=:status');
$query->addParams([':status' => $status]);
```

Se pueden establecer múltiples condiciones en `where` usando el *formato hash*.

```php
$query->where([
    'status' => 10,
    'type' => 2,
    'id' => [4, 8, 15, 16, 23, 42],
]);
```

El código generará la el siguiente SQL:

```sql
WHERE (`status` = 10) AND (`type` = 2) AND (`id` IN (4, 8, 15, 16, 23, 42))
```

El valor NULO es un valor especial en las bases de datos, y el Constructor de Consultas lo gestiona inteligentemente.
Este código:

```php
$query->where(['status' => null]);
```

da como resultado la siguiente cláusula WHERE:

```sql
WHERE (`status` IS NULL)
```

También se pueden crear subconsultas con objetos de tipo `Query` como en el siguiente ejemplo:

```php
$userQuery = (new Query)->select('id')->from('user');
$query->where(['id' => $userQuery]);
```

que generará el siguiente código SQL:

```sql
WHERE `id` IN (SELECT `id` FROM `user`)
```

Otra manera de usar el método es el formato de operando que es `[operator, operand1, operand2, ...]`.

El operando puede ser uno de los siguientes (ver también [[yii\db\QueryInterface::where()]]):

- `and`: los operandos deben concatenerase usando `AND`. por ejemplo, `['and', 'id=1', 'id=2']` generará
  `id=1 AND id=2`. Si el operando es un array, se convertirá en una cadena de texto usando las reglas aquí descritas.
  Por ejemplo, `['and', 'type=1', ['or', 'id=1', 'id=2']]` generará `type=1 AND (id=1 OR id=2)`. El método no
  ejecutará ningún filtrado ni entrecomillado.

- `or`: similar al operando `and` exceptuando que los operando son concatenados usando `OR`.

- `between`: el operando 1 debe ser el nombre de columna, y los operandos 2 y 3 deben ser los valores iniciales y
  finales del rango en el que se encuentra la columna. Por ejemplo, `['between', 'id', 1, 10]` generará
  `id BETWEEN 1 AND 10`.

- `not between`: similar a `between` exceptuando que  `BETWEEN` se reemplaza por `NOT BETWEEN` en la condición
  generada.

- `in`: el operando 1 debe ser una columna o una expresión de BD. El operando 2 puede ser un array o un objeto de tipo
  `Query`. Generará una condición `IN`. Si el operando 2 es un array, representará el rango de valores que puede
  albergar la columna o la expresión de BD; Si el operando 2 es un objeto de tipo `Query`, se generará una subconsulta
  y se usará como rango de la columna o de la expresión de BD. Por ejemplo, `['in', 'id', [1, 2, 3]]` generará
  `id IN (1, 2, 3)`. El método entrecomillará adecuadamente el nombre de columna y filtrará los valores del rango. El
  operando `in` también soporta columnas compuestas. En este caso, el operando 1 debe se un array de columnas,
  mientras que el operando 2 debe ser un array de arrays o un objeto de tipo `Query` que represente el rango de las
  columnas.

- `not in`: similar que el operando `in` exceptuando que `IN` se reemplaza por `NOT IN` en la condición generada.

- `like`: el operando 1 debe ser una columna o una expresión de BD, y el operando 2 debe ser una cadena de texto o un
  array que represente los valores a los que tienen que asemejarse la columna o la expresión de BD.Por ejemplo,
  `['like', 'name', 'tester']` generará `name LIKE '%tester%'`. Cuando se da el valor rango como un array, se
  generarán múltiples predicados `LIKE` y se concatenaran usando `AND`. Por ejemplo,
  `['like', 'name', ['test', 'sample']]` generará `name LIKE '%test%' AND name LIKE '%sample%'`. También se puede
  proporcionar un tercer operando opcional para especificar como deben filtrarse los caracteres especiales en los
  valores. El operando debe se un array que mapeen los caracteres especiales a sus caracteres filtrados asociados. Si
  no se proporciona este operando, se aplicará el mapeo de filtrado predeterminado. Se puede usar `false` o un array
  vacío para indicar que los valores ya están filtrados y no se necesita aplicar ningún filtro. Hay que tener en
  cuenta que cuando se usa un el mapeo de filtrado (o no se especifica el tercer operando), los valores se encerraran
  automáticamente entre un par de caracteres de porcentaje.

> Note: Cuando se usa PostgreSQL también se puede usar
[`ilike`](https://www.postgresql.org/docs/8.3/static/functions-matching.html#FUNCTIONS-LIKE) en lugar de `like` para
filtrar resultados insensibles a mayúsculas (case-insensitive).

- `or like`: similar al operando `like` exceptuando que se usa `OR` para concatenar los predicados `LIKE` cuando haya
  un segundo operando en un array.

- `not like`: similar al operando `like` exceptuando que se usa `LIKE` en lugar de `NOT LIKE` en las condiciones
  generadas.

- `or not like`: similar al operando `not like` exceptuando que se usa `OR` para concatenar los predicados `NOT LIKE`.

- `exists`: requiere un operando que debe ser una instancia de [[yii\db\Query]] que represente la subconsulta. Esto
  generará una expresión `EXISTS (sub-query)`.

- `not exists`: similar al operando `exists` y genera una expresión `NOT EXISTS (sub-query)`.

Adicionalmente se puede especificar cualquier cosa como operando:

```php
$query->select('id')
    ->from('user')
    ->where(['>=', 'id', 10]);
```

Cuyo resultado será:

```sql
SELECT id FROM user WHERE id >= 10;
```

Si se construyen partes de una condición dinámicamente, es muy convenientes usar `andWhere()` y `orWhere()`:

```php
$status = 10;
$search = 'yii';

$query->where(['status' => $status]);
if (!empty($search)) {
    $query->andWhere(['like', 'title', $search]);
}
```

En el caso que `$search` no este vacío, se generará el siguiente código SQL:

```sql
WHERE (`status` = 10) AND (`title` LIKE '%yii%')
```

#### Construcción de Condiciones de Filtro

Cuando se generan condiciones de filtro basadas en datos recibidos de usuarios (inputs), a menudo se quieren gestionar
de forma especial las "datos vacíos" para ignorarlos en los filtros. Por ejemplo, teniendo un formulario HTML que
obtiene el nombre de usuario y la dirección de correo electrónico. Si el usuario solo rellena el campo de nombre de
usuario, se puede querer generar una consulta para saber si el nombre de usuario recibido es valido. Se puede usar
`filterWhere()` para conseguirlo:

```php
// $username y $email son campos de formulario rellenados por usuarios
$query->filterWhere([
    'username' => $username,
    'email' => $email,
]);
```

El método `filterWhere()` es muy similar al método `where()`. La principal diferencia es que el `filterWhere()`
eliminará los valores vacíos de las condiciones proporcionadas. Por lo tanto si `$email` es "vació", la consulta
resultante será `...WHERE username=:username`; y si tanto `$username` como `$email` son "vacías", la consulta no
tendrá `WHERE`.

Decimos que un valor es *vacío* si es nulo, una cadena de texto vacía, una cadena de texto que consista en espacios en
blanco o un array vacío.

También se pueden usar `andFilterWhere()` y `orFilterWhere()` para añadir más condiciones de filtro.

### `ORDER BY`

Se pueden usar `orderBy` y `addOrderBy` para ordenar resultados:

```php
$query->orderBy([
    'id' => SORT_ASC,
    'name' => SORT_DESC,
]);
```

Aquí estamos ordenando por `id` ascendente y después por `name` descendente.

### `GROUP BY` and `HAVING`

Para añadir `GROUP BY` al SQL generado se puede usar el siguiente código:

```php
$query->groupBy('id, status');
```

Si se quieren añadir otro campo después de usar `groupBy`:

```php
$query->addGroupBy(['created_at', 'updated_at']);
```

Para añadir la condición `HAVING` se pueden usar los métodos `having` y `andHaving` y `orHaving`. Los parámetros para
ellos son similares a los del grupo de métodos `where`:

```php
$query->having(['status' => $status]);
```

### `LIMIT` and `OFFSET`

Para limitar el resultado a 10 filas se puede usar `limit`:

```php
$query->limit(10);
```

Para saltarse las 100 primeras filas, se puede usar:

```php
$query->offset(100);
```

### `JOIN`

Las clausulas `JOIN` se generan en el Constructor de Consultas usando el método join aplicable:

- `innerJoin()`
- `leftJoin()`
- `rightJoin()`

Este left join selecciona los datos desde dos tablas relacionadas en una consulta:

```php
$query->select(['user.name AS author', 'post.title as title'])
    ->from('user')
    ->leftJoin('post', 'post.user_id = user.id');
```

En el código, el primer parámetro del método `leftjoin` especifica la tabla a la que aplicar el join. El segundo
parámetro, define la condición del join.

Si la aplicación de bases de datos soporta otros tipos de joins, se pueden usar mediante el método `join` genérico:

```php
$query->join('FULL OUTER JOIN', 'post', 'post.user_id = user.id');
```

El primer argumento es el tipo de join a realizar. El segundo es la tabla a la que aplicar el join, y el tercero es la condición:

Como en `FROM`, también se pueden efectuar joins con subconsultas. Para hacerlo, se debe especificar la subconsulta
como un array que tiene que contener un elemento. El valor del array tiene que ser un objeto de tipo `Query` que
represente la subconsulta, mientras que la clave del array es el alias de la subconsulta. Por ejemplo:

```php
$query->leftJoin(['u' => $subQuery], 'u.id=author_id');
```

### `UNION`

En SQL `UNION` agrega resultados de una consulta a otra consulta. Las columnas devueltas por ambas consultas deben
coincidir. En Yii para construirla, primero se pueden formar dos objetos de tipo query y después usar el método
`union`:

```php
$query = new Query();
$query->select("id, category_id as type, name")->from('post')->limit(10);

$anotherQuery = new Query();
$anotherQuery->select('id, type, name')->from('user')->limit(10);

$query->union($anotherQuery);
```

Consulta por Lotes
---------------

Cuando se trabaja con grandes cantidades de datos, los métodos como [[yii\db\Query::all()]] no son adecuados ya que
requieren la carga de todos los datos en memoria. Para mantener los requerimientos de memoria reducidos, Yii
proporciona soporte a las llamadas consultas por lotes (batch query). Una consulta por lotes usa un cursor de datos y
recupera los datos en bloques.

Las consultas por lotes se pueden usar del siguiente modo:

```php
use yii\db\Query;

$query = (new Query())
    ->from('user')
    ->orderBy('id');

foreach ($query->batch() as $users) {
    // $users is an array of 100 or fewer rows from the user table
}

// o si se quieren iterar las filas una a una
foreach ($query->each() as $user) {
    // $user representa uno fila de datos de la tabla user
}
```

Los métodos [[yii\db\Query::batch()]] y [[yii\db\Query::each()]] devuelven un objeto [[yii\db\BatchQueryResult]] que
implementa una interfaz `Iterator` y así se puede usar en el constructor `foreach`. Durante la primera iteración, se
efectúa una consulta SQL a la base de datos. Desde entonces, los datos se recuperan por lotes en las iteraciones. El
tamaño predeterminado de los lotes es 100, que significa que se recuperan 100 filas de datos en cada lote. Se puede
modificar el tamaño de los lotes pasando pasando un primer parámetro a los métodos `batch()` o `each()`.

En comparación con [[yii\db\Query::all()]], las consultas por lotes sólo cargan 100 filas de datos en memoria cada
vez. Si el procesan los datos y después se descartan inmediatamente, las consultas por lotes, pueden ayudar a mantener
el uso de memora bajo un limite.

Si se especifica que el resultado de la consulta tiene que ser indexado por alguna columna mediante
[[yii\db\Query::indexBy()]], las consultas por lotes seguirán manteniendo el indice adecuado. Por ejemplo,

```php
use yii\db\Query;

$query = (new Query())
    ->from('user')
    ->indexBy('username');

foreach ($query->batch() as $users) {
    // $users esta indexado en la columna "username"
}

foreach ($query->each() as $username => $user) {
}
```

---

### Guide Es Glossary (`docs/guide-es/glossary.md`)

# A

## alias

Alias es un string utilizado por Yii para referirse a una clase o directorio tal como `@app/vendor`.

## aplicación

La aplicación es el objeto central durante la solicitud HTTP. Contiene un número de componentes con los que toma información de la solicitud y la envía al controlador apropiado para posterior procesamiento.

El objeto de la aplicación es instanciado como un singleton por el script de entrada. El singleton de la aplicación puede ser accedido desde cualquier lugar a través de `\Yii::$app`.

## assets

Asset se refiere a un archivo de recurso. Típicamente contiene JavaScript o CSS pero puede ser cualquier otra cosa que sea accesible vía HTTP.

## atributo

Un atributo es una propiedad de un modelo (una variable miembro de clase o una propiedad mágica definida vía `__get()`/`__set()`) que almacena **datos de negocio**.

# B

## bundle

Bundle, conocido como paquete en Yii 1.1, se refiere a un número de recursos y un archivo de configuración que describe dependencias y lista recursos.

# C

## configuración

Configuración puede referirse tanto al proceso de establecer propiedades de un objeto como a un archivo de configuración que almacena la definición de propiedades para un objeto o clase de objetos.

# E

## extensión

Extensión es un grupo de clases, paquete de recursos y configuraciones que agrega más características a la aplicación.

# I

## instalación

Instalación es el proceso de preparar algo para trabajar, desde seguir un archivo léame hasta ejecutar un script preparado especialmente para tal fin. En el caso de Yii, define permisos y chequea los requerimientos para el funcionamiento del software.

# M

## módulo

Módulo es una sub-aplicación que contiene elementos MVC en sí mismo, como modelos, vistas, controladores, etc. y puede ser utilizado dentro de la aplicación principal. Típicamente remitiendo las solicitudes al módulo en vez de manejándolo desde controladores.

# N

## namespace

Namespace (espacio de nombres) se refiere a una [característica de PHP](https://www.php.net/manual/es/language.namespaces.php) activamente utilizada en Yii 2.

# P

## paquete

[Ver bundle](#bundle).

# V

## vendor

Vendor (proveedor) es una organización o un desarrollador individual que provee código en forma de extensiones, módulos o librerías.

---

### Guide Es Helper Array (`docs/guide-es/helper-array.md`)

ArrayHelper
===========

Adicionalmente al [rico conjunto de funciones para arrays de PHP](https://www.php.net/manual/es/book.array.php), el array helper de Yii proporciona
métodos estáticos adicionales permitiendo trabajar con arrays de manera más eficiente.


## Devolviendo Valores <span id="getting-values"></span>

Recuperar valores de un array, un objeto o una estructura compleja usando PHP estándar es bastante
repetitivo. Tienes que comprobar primero si una clave existe con `isset`, después devolver el valor si existe, si no,
devolver un valor por defecto:

```php
class User
{
    public $name = 'Alex';
}

$array = [
    'foo' => [
        'bar' => new User(),
    ]
];

$value = isset($array['foo']['bar']->name) ? $array['foo']['bar']->name : null;
```

Yii proviene de un método muy conveniente para hacerlo:

```php
$value = ArrayHelper::getValue($array, 'foo.bar.name');
```

El primer argumento del método es de donde vamos a obtener el valor. El segundo argumento especifica como devolver el dato. Puede ser
de la siguiente manera:

- Nombre de la clave del array o de la propiedad del objeto para recuperar el valor.
- Conjunto de puntos separados por las claves del array o los nombres de las propiedades del objeto. Esto se ha usado en el ejemplo anterior.
- Un callback que devuelve un valor.

El callback se debería usar de la siguiente manera:

```php
$fullName = ArrayHelper::getValue($user, function ($user, $defaultValue) {
    return $user->firstName . ' ' . $user->lastName;
});
```

El tercer argumento opcional es el valor por defecto el cual es `null` si no se especifica. Podría ser utilizado de la siguiente manera:

```php
$username = ArrayHelper::getValue($comment, 'user.username', 'Unknown');
```

En caso de que quieras coger un valor y luego removerlo inmediatamente del array puedes usar el método `remove`:

```php
$array = ['type' => 'A', 'options' => [1, 2]];
$type = ArrayHelper::remove($array, 'type');
```

Después de ejecutar el código el `$array` contendrá `['options' => [1, 2]]` y `$type` debe ser `A`. Tenga en cuenta que a diferencia del método
`getValue`, `remove` solo soporta nombres clave simples.


## Comprobando la Existencia de Claves <span id="checking-existence-of-keys"></span>

`ArrayHelper::keyExists` funciona de la misma manera que [array_key_exists](https://www.php.net/manual/es/function.array-key-exists.php)
excepto que también soporta case-insensitive para la comparación de claves. Por ejemplo,

```php
$data1 = [
    'userName' => 'Alex',
];

$data2 = [
    'username' => 'Carsten',
];

if (!ArrayHelper::keyExists('username', $data1, false) || !ArrayHelper::keyExists('username', $data2, false)) {
    echo "Please provide username.";
}
```

## Recuperando Columnas <span id="retrieving-columns"></span>

A menudo necesitas obtener unos valores de una columna de las filas de datos u objetos de un array. Un ejemplo común es obtener una lista de IDs.

```php
$data = [
    ['id' => '123', 'data' => 'abc'],
    ['id' => '345', 'data' => 'def'],
];
$ids = ArrayHelper::getColumn($array, 'id');
```

El resultado será `['123', '345']`.

Si se requieren transformaciones adicionales o la manera de obtener el valor es complejo, se podría especificar como segundo argumento
una función anónima :

```php
$result = ArrayHelper::getColumn($array, function ($element) {
    return $element['id'];
});
```


## Re-indexar Arrays <span id="reindexing-arrays"></span>

Con el fin de indexar un array según una clave especificada, se puede usar el método `index`. La entrada debería ser
un array multidimensional o un array de objetos. `$key` puede ser tanto una clave del sub-array, un nombre de una propiedad
del objeto, o una función anónima que debe devolver el valor que será utilizado como clave.

El atributo `$groups` es un array de claves, que será utilizado para agrupar el array de entrada en uno o más sub-arrays
basado en la clave especificada.

Si el atributo `$key` o su valor por el elemento en particular es `null` y `$groups` no está definido, dicho elemento del array
será descartado. De otro modo, si `$groups` es especificado, el elemento del array será agregado al array resultante
sin una clave.

Por ejemplo:

```php
$array = [
    ['id' => '123', 'data' => 'abc', 'device' => 'laptop'],
    ['id' => '345', 'data' => 'def', 'device' => 'tablet'],
    ['id' => '345', 'data' => 'hgi', 'device' => 'smartphone'],
];
$result = ArrayHelper::index($array, 'id');');
```

El resultado será un array asociativo, donde la clave es el valor del atributo `id`

```php
[
    '123' => ['id' => '123', 'data' => 'abc', 'device' => 'laptop'],
    '345' => ['id' => '345', 'data' => 'hgi', 'device' => 'smartphone']
    // El segundo elemento del array original es sobrescrito por el último elemento debido a que tiene el mismo id
]
```

Pasando una función anónima en `$key`, da el mismo resultado.

```php
$result = ArrayHelper::index($array, function ($element) {
    return $element['id'];
});
```

Pasando `id` como tercer argumento, agrupará `$array` mediante `id`:

```php
$result = ArrayHelper::index($array, null, 'id');
```

El resultado será un array multidimensional agrupado por `id` en su primer nivel y no indexado en su segundo nivel:

```php
[
    '123' => [
        ['id' => '123', 'data' => 'abc', 'device' => 'laptop']
    ],
    '345' => [ // todos los elementos con este índice están presentes en el array resultante
        ['id' => '345', 'data' => 'def', 'device' => 'tablet'],
        ['id' => '345', 'data' => 'hgi', 'device' => 'smartphone'],
    ]
]
```

Una función anónima puede ser usada también en el array agrupador:

```php
$result = ArrayHelper::index($array, 'data', [function ($element) {
    return $element['id'];
}, 'device']);
```

El resultado será un array multidimensional agrupado por `id` en su primer nivel, por `device` en su segundo nivel e
indexado por `data` en su tercer nivel:

```php
[
    '123' => [
        'laptop' => [
            'abc' => ['id' => '123', 'data' => 'abc', 'device' => 'laptop']
        ]
    ],
    '345' => [
        'tablet' => [
            'def' => ['id' => '345', 'data' => 'def', 'device' => 'tablet']
        ],
        'smartphone' => [
            'hgi' => ['id' => '345', 'data' => 'hgi', 'device' => 'smartphone']
        ]
    ]
]
```

## Construyendo Mapas (Maps) <span id="building-maps"></span>

Con el fin de construir un mapa (pareja clave-valor) de un array multidimensional o un array de objetos puedes usar el método `map`.
Los parámetros `$from` y `$to`  especifican los nombres de las claves o los nombres de las propiedades que serán configuradas en el mapa. Opcionalmente, se puede
agrupar en el mapa de acuerdo al campo de agrupamiento `$group`. Por ejemplo,

```php
$array = [
    ['id' => '123', 'name' => 'aaa', 'class' => 'x'],
    ['id' => '124', 'name' => 'bbb', 'class' => 'x'],
    ['id' => '345', 'name' => 'ccc', 'class' => 'y'],
);

$result = ArrayHelper::map($array, 'id', 'name');
// el resultado es:
// [
//     '123' => 'aaa',
//     '124' => 'bbb',
//     '345' => 'ccc',
// ]

$result = ArrayHelper::map($array, 'id', 'name', 'class');
// el resultado es:
// [
//     'x' => [
//         '123' => 'aaa',
//         '124' => 'bbb',
//     ],
//     'y' => [
//         '345' => 'ccc',
//     ],
// ]
```


## Ordenamiento Multidimensional <span id="multidimensional-sorting"></span>

El método `multisort` ayuda a ordenar un array de objetos o arrays anidados por una o varias claves. Por ejemplo,

```php
$data = [
    ['age' => 30, 'name' => 'Alexander'],
    ['age' => 30, 'name' => 'Brian'],
    ['age' => 19, 'name' => 'Barney'],
];
ArrayHelper::multisort($data, ['age', 'name'], [SORT_ASC, SORT_DESC]);
```

Después del ordenado obtendremos lo siguiente en `$data`:

```php
[
    ['age' => 19, 'name' => 'Barney'],
    ['age' => 30, 'name' => 'Brian'],
    ['age' => 30, 'name' => 'Alexander'],
];
```

El segundo argumento que especifica las claves para ordenar puede ser una cadena si se trata de una clave, un array en caso de que tenga múltiples claves
o una función anónima como la siguiente

```php
ArrayHelper::multisort($data, function($item) {
    return isset($item['age']) ? ['age', 'name'] : 'name';
});
```

El tercer argumento es la dirección. En caso de ordenar por una clave podría ser `SORT_ASC` o
`SORT_DESC`. Si ordenas por múltiples valores puedes ordenar cada valor diferentemente proporcionando un array de
direcciones de ordenación.

El último argumento es un PHP sort flag que toma los mismos valores que los pasados a
PHP [sort()](https://www.php.net/manual/es/function.sort.php).


## Detectando Tipos de Array <span id="detecting-array-types"></span>

Es muy útil saber si un array es indexado o asociativo. He aquí un ejemplo:

```php
// sin claves especificadas
$indexed = ['Qiang', 'Paul'];
echo ArrayHelper::isIndexed($indexed);

// todas las claves son strings
$associative = ['framework' => 'Yii', 'version' => '2.0'];
echo ArrayHelper::isAssociative($associative);
```


## Codificación y Decodificación de Valores HTML <span id="html-encoding-values"></span>

Con el fin de codificar o decodificar caracteres especiales en un array de strings con entidades HTML puedes usar lo siguiente:

```php
$encoded = ArrayHelper::htmlEncode($data);
$decoded = ArrayHelper::htmlDecode($data);
```

Solo los valores se codifican por defecto. Pasando como segundo argumento `false` puedes codificar un array de claves también.
La codificación utilizará el charset de la aplicación y podría ser cambiado pasandole un tercer argumento.


## Fusionando Arrays <span id="merging-arrays"></span>

```php
  /**
    * Fusiona recursivamente dos o más arrays en uno.
    * Si cada array tiene un elemento con el mismo valor string de clave, el último
    * sobrescribirá el anterior (difiere de array_merge_recursive).
    * Se llegará a una fusión recursiva si ambos arrays tienen un elemento tipo array
    * y comparten la misma clave.
    * Para elementos cuyas claves son enteros, los elementos del array final
    * serán agregados al array anterior.
    * @param array $a array al que se va a fusionar
    * @param array $b array desde el cual fusionar. Puedes especificar
    * arrays adicionales mediante el tercer argumento, cuarto argumento, etc.
    * @return array el array fusionado (los arrays originales no sufren cambios)
    */
    public static function merge($a, $b)
```


## Convirtiendo Objetos a Arrays <span id="converting-objects-to-arrays"></span>

A menudo necesitas convertir un objeto o un array de objetos a un array. El caso más común es convertir los modelos de active record
con el fin de servir los arrays de datos vía API REST o utilizarlos de otra manera. El siguiente código se podría utilizar para hacerlo:

```php
$posts = Post::find()->limit(10)->all();
$data = ArrayHelper::toArray($posts, [
    'app\models\Post' => [
        'id',
        'title',
        // el nombre de la clave del resultado del array => nombre de la propiedad
        'createTime' => 'created_at',
        // el nombre de la clave del resultado del array => función anónima
        'length' => function ($post) {
            return strlen($post->content);
        },
    ],
]);
```

El primer argumento contiene el dato que queremos convertir. En nuestro caso queremos convertir un modelo AR `Post`.

El segundo argumento es el mapeo de conversión por clase. Estamos configurando un mapeo para el modelo `Post`.
Cada array de mapeo contiene un conjunto de mapeos. Cada mapeo podría ser:

- Un campo nombre para incluir como está.
- Un par clave-valor del array deseado con un nombre clave y el nombre de la columna del modelo que tomará el valor.
- Un par clave-valor del array deseado con un nombre clave y una función anónima que retorne el valor.

El resultado de la conversión anterior será:


```php
[
    'id' => 123,
    'title' => 'test',
    'createTime' => '2013-01-01 12:00AM',
    'length' => 301,
]
```

Es posible proporcionar una manera predeterminada de convertir un objeto a un array para una clase especifica
mediante la implementación de la interfaz [[yii\base\Arrayable|Arrayable]] en esa clase.

## Haciendo pruebas con Arrays <span id="testing-arrays"></span>

A menudo necesitarás comprobar está en un array o un grupo de elementos es un sub-grupo de otro.
A pesar de que PHP ofrece `in_array()`, este no soporta sub-grupos u objetos de tipo `\Traversable`.

Para ayudar en este tipo de pruebas, [[yii\helpers\ArrayHelper]] provee [[yii\helpers\ArrayHelper::isIn()|isIn()]]
y [[yii\helpers\ArrayHelper::isSubset()|isSubset()]] con la misma firma del método
[in_array()](https://www.php.net/manual/es/function.in-array.php).

```php
// true
ArrayHelper::isIn('a', ['a']);
// true
ArrayHelper::isIn('a', new(ArrayObject['a']));

// true 
ArrayHelper::isSubset(new(ArrayObject['a', 'c']), new(ArrayObject['a', 'b', 'c'])

```

---

--- METRICS ---
- Files Extracted: 110
- Estimated Token Budget: ~126771 tokens
- Canonical Reference: https://codewiki.google/github.com/yiisoft/yii2
