viernes, 26 de diciembre de 2014

Trabajando con bases de datos

Es muy seguro que en nuestros trabajos necesitemos conectarnos a una base de datos. En ésta sección veremos como:

  • Configurar una conexión a base de datos
  • Definir una clase Active Record (Registro Activo)
  • Realizar consultas usando la clase Active Record
  • Desplegar datos en una página a través de una vista

Preparando la base de datos

Yii nos permite trabajar con diferentes base de datos como SQLite, MySQL, PostgreSQL, MSSQL u Oracle.

Para nuestro ejemplo utilizaremos MySQL en el que crearemos una base de datos yii2basic y una tabla pais con algunos registros.

CREATE TABLE IF NOT EXISTS `pais` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `nombre` varchar(50) NOT NULL,
  `codigo` varchar(3) NOT NULL,
  `poblacion` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

INSERT INTO `pais`(`nombre`, `codigo`, `poblacion`) VALUES ('Colombia','CO', 47846160);
INSERT INTO `pais`(`nombre`, `codigo`, `poblacion`) VALUES ('Venezuela','VE', 31648930);
INSERT INTO `pais`(`nombre`, `codigo`, `poblacion`) VALUES ('Argentina','AR', 42192500);
INSERT INTO `pais`(`nombre`, `codigo`, `poblacion`) VALUES ('Ecuador','EC', 16013143);
INSERT INTO `pais`(`nombre`, `codigo`, `poblacion`) VALUES ('Uruguay','UY', 3286314);
INSERT INTO `pais`(`nombre`, `codigo`, `poblacion`) VALUES ('Paraguay','PY', 6672633);
INSERT INTO `pais`(`nombre`, `codigo`, `poblacion`) VALUES ('Bolivia','BO', 10027254);
INSERT INTO `pais`(`nombre`, `codigo`, `poblacion`) VALUES ('Chile','CL', 17819054);



Configurar una conexión a base de datos

Por una lado, debemos habilitar las extensiones correspondientes a nuestra base de datos en la configuración de PHP. Para nuestro caso es php_mysqlphp_pdo_mysql.

Por otro lado, abrimos el archivo \config\db.php y cambiamos los parámetros de acuerdo a nuestra base de datos. En nuestro caso:

return [
    'class' => 'yii\db\Connection',
    'dsn' => 'mysql:host=localhost;dbname=yii2basic',
    'username' => 'root',
    'password' => '',
    'charset' => 'utf8',
];

Para acceder a esta configuración en el código de nuestra aplicación lo podemos hacer con la expresión Yii::$app->db.

Creando el Active Record (Registro Activo)

Para representar y extraer los datos de la tabla pais, creamos una clase pais derivada de Active Record. El archivo en el cual guardamos es \models\Pais.php con el siguiente contenido:

<?php

namespace app\models;

use yii\db\ActiveRecord;

class Pais extends ActiveRecord
{
}

Este es todo el código que debemos escribir. No es necesario especificar el nombre de la tabla, ya que el nombre de la clase se asocia al nombre de la tabla.

Es posible sobreescribir el método yii\db\ActiveRecord::tableName()  para especificar de manera explícita el nombre de la tabla. El código sería algo similar a:

class Pais extends ActiveRecord
{
    public static function tableName()
    {
        return 'tbl_paises';
    }
}

Creando la Acción

Crearemos un controlador propio para nuestra tabla, y la acción index como la acción por defecto o que se ejecutará si no se especifica de manera explícitamente en la url. Creamos el archivo \controllers\PaisController.php con el siguiente contenido:

<?php

namespace app\controllers;

use yii\web\Controller;
use yii\data\Pagination;
use app\models\Pais;

class PaisController extends Controller
{
    public function actionIndex()
    {
        $query = Pais::find();

        $pagination = new Pagination([
            'defaultPageSize' => 5,
            'totalCount' => $query->count(),
        ]);

        $paises = $query->orderBy('nombre')
            ->offset($pagination->offset)
            ->limit($pagination->limit)
            ->all();

        return $this->render('index', [
            'paises' => $paises,
            'pagination' => $pagination,
        ]);
    }
}

Analicemos un poco el código.

Tenemos la llamada a Country::find() la cual recupera todos los datos de nuestra tabla. El límite de datos recuperados se realiza con ayuda del objeto yii\data\Pagination. El objeto Pagination tiene dos propósitos:
  1. Ajustar las cláusulas offset y limit de la consulta sql y recuperar un conjunto específico de datos. En nuestro ejemplo, páginas de 5 registros cada una.
  2. Desplegar de manera consistente los botones de paginación en nuestra vista.
Al final, se retorna la vista index con los datos de los países y la información de la paginación.

Creando la vista

Bajo el directorio views, crearemos un subdirectorio de nombre pais. En este subdirectorio se guardarán todas las vistas utilizadas en nuestro controlador. Creamos el archivo \views\pais\index.php con el siguiente código:

<?php
use yii\helpers\Html;
use yii\widgets\LinkPager;
?>
<h1>Países</h1>
<ul>
<?php foreach ($paises as $pais): ?>
    <li>
        <?= Html::encode("{$pais->nombre} ({$pais->codigo})") ?>:
        <?= $pais->poblacion ?>
    </li>
<?php endforeach; ?>
</ul>

<?= LinkPager::widget(['pagination' => $pagination]) ?>

La vista tiene dos secciones. La primera, que toma los datos de los países y los presenta como una lista HTML con viñetas (unordered); y la segunda, el widget yii\widgets\LinkPager para mostrar los botones de paginación.

Probando

Para probar el resultado de nuestro trabajo podemos en nuestro navegador web escribir la url:
http://hostname/index.php?r=pais/index

El resultado será similar al siguiente:



Sugerencias


  • Al crear nuestra base de datos, es bueno definir una conexión (cotejamiento) del tipo utf8.
  • Nuestros archivos deben ser grabados como UTF-8 sin BOM.



También te puede interesar:
DAO - Database Access Objects (Objetos de acceso a base de datos)
Generador de Consultas (Query Builder)
Active Record (Registro Activo)

1 comentario:

  1. Thanks for sharing, nice post! Post really provice useful information!

    Giaonhan247 chuyên dịch vụ mua hàng mỹ từ dịch vụ order hàng mỹ hay nhận mua nước hoa pháp từ website nổi tiếng hàng đầu nước Mỹ mua hàng ebay ship về VN uy tín, giá rẻ.

    ResponderBorrar

Nota: sólo los miembros de este blog pueden publicar comentarios.