Trabajar con Bases de Datos =========================== En esta sección, explicaremos cómo crear una nueva página para mostrar datos de países traídos de una tabla de la base de datos llamada `country`. Para lograr este objetivo, configurarás una conexión a la base de datos, crearás una clase [Active Record](db-active-record.md), una [acción](structure-controllers.md) y una [vista](structure-views.md). A lo largo de este tutorial, aprenderás a * configurar una conexión a la base de datos; * definir una clase Active Record; * realizar consultas a la base de datos utilizando la clase Active Record; * mostrar datos en una vista con paginación incluida. Ten en cuenta que para finalizar esta sección, deberás tener al menos conocimientos básicos y experiencia con bases de datos. En particular, deberás ser capaz de crear una base de datos y saber ejecutar consultas SQL usando alguna herramienta de cliente de base de datos. Preparar una Base de Datos -------------------------- Para empezar, crea una base de datos llamada `yii2basic` de la cual tomarás los datos en la aplicación. Puedes elegir entre una base de datos SQLite, MySQL, PostgreSQL, MSSQL u Oracle, dado que Yii incluye soporte para varios motores. Por simplicidad, usaremos MySQL en la siguiente descripción. A continuación, crea una tabla llamada `country` e inserta algunos datos de ejemplo. Puedes utilizar las siguientes declaraciones SQL. ```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); ``` Al final, tendrás una base de datos llamada `yii2basic`, y dentro de esta, una tabla llamada `country` con diez registros en ella. Configurar una conexión a la Base de Datos ------------------------------------------ Asegúrate de tener instalado la extensión de PHP [PDO](http://www.php.net/manual/es/book.pdo.php) y el driver de PDO para el motor que estés utilizando (ej. `pdo_mysql` para MySQL). Este es un requisito básico si tu aplicación va a utilizar bases de datos relacionales. Abre el archivo `config/db.php` y ajusta el contenido dependiendo de la configuración a tu base de datos. Por defecto, el archivo contiene el siguiente contenido: ```php 'yii\db\Connection', 'dsn' => 'mysql:host=localhost;dbname=yii2basic', 'username' => 'root', 'password' => '', 'charset' => 'utf8', ]; ``` El archivo `config/db.php` representa la típica [configuración](concept-configurations.md) basada en archivos. Este archivo de configuración en particular especifica los parámetros necesarios para crear e inicializar una instancia de [[yii\db\Connection]] a través de la cual puedes realizar consultas SQL contra la base de datos subyacente. La conexión a la base de datos realizada anteriormente puede ser accedida mediante `Yii::$app->db`. > Info: El archivo `config/db.php` será incluido en el archivo principal de configuración `config/web.php`, el cual especifica cómo la instancia de la [aplicación](structure-applications.md) debe ser inicializada. Para más información, consulta la sección [Configuraciones](concept-configurations.md). Si necesitas trabajar con bases de datos cuyo soporte no está incluído en Yii, revisa las siguientes extensiones: - [Informix](https://github.com/edgardmessias/yii2-informix) - [IBM DB2](https://github.com/edgardmessias/yii2-ibm-db2) - [Firebird](https://github.com/edgardmessias/yii2-firebird) Crear un Active Record ---------------------- Para representar y extraer datos de la tabla `country`, crea una clase [Active Record](db-active-record.md) llamada `Country` y guárdala en el archivo `models/Country.php`. ```php Info: Si no se puede realizar un emparejamiento entre el nombre de la clase y la tabla, puedes sobrescribir el método [[yii\db\ActiveRecord::tableName()]] para especificar explícitamente el nombre de la tabla asiciada. Utilizando la clase `Country`, puedes manipular los datos de la tabla `country` fácilmente, como se muestra en los siguiente ejemplos: ```php use app\models\Country; // obtiene todos los registros de la tabla country ordenándolos por "name" $countries = Country::find()->orderBy('name')->all(); // obtiene el registro cuya clave primaria es "US" $country = Country::findOne('US'); // muestra "United States" echo $country->name; // cambia el nombre del país a "U.S.A." y lo guarda en la base de datos $country->name = 'U.S.A.'; $country->save(); ``` > Info: Active Record es una potente forma de acceder y manipular datos de una base de datos de una manera orientada a objetos. Puedes encontrar información más detallada acerca de [Active Record](db-active-record.md). Además de Active Record, puedes utilizar un método de acceso de bajo nivel llamado [Data Access Objects](db-dao.md). Crear una Acción ---------------- Para mostrar el país a los usuarios, necesitas crear una acción. En vez de hacerlo en el controlador `site` como lo hiciste en las secciones previas, tiene más sentido crear un nuevo controlador que englobe todas las acciones de manipulación de datos de la tabla country. Llama a este nuevo controlador `CountryController` y define una acción `index` en él, como se muestra a continuación: ```php 5, 'totalCount' => $query->count(), ]); $countries = $query->orderBy('name') ->offset($pagination->offset) ->limit($pagination->limit) ->all(); return $this->render('index', [ 'countries' => $countries, 'pagination' => $pagination, ]); } } ``` Guarda el código anterior en el archivo `controllers/CountryController.php`. La acción `index` llama a `Country::find()` para generar una consulta a la base de datos y traer todos los datos de la tabla `country`. Para limitar la cantidad de registros traídos en cada petición, la consulta es paginada con la ayuda de un objeto [[yii\data\Pagination]]. El objeto `Pagination` sirve para dos propósitos: * Define las cláusulas `offset` y `limit` de la consulta SQL para así sólo devolver una sola página de datos (5 registros por página como máximo). * Es utilizado en la vista para mostrar un paginador que consiste en una lista de botones que representan a cada página, tal como será explicado en la siguiente sub-sección. Al final, la acción `index` renderiza una vista llamada `index` y le pasa los datos de países así como la información de paginación relacionada. Crear una Vista --------------- Bajo el directorio `views`, crea primero un sub-directorio llamado `country`. Este será usado para contener todas las vistas renderizadas por el controlador `country`. Dentro del directorio `views/country`, crea un archivo llamado `index.php` con el siguiente contenido: ```php