Trabalhando com Bancos de Dados ¶
Esta seção descreverá como criar uma nova página que exibe informações de países obtidos de uma tabela de banco de dados chamada pais
. Para isso, você
configurará uma conexão com o banco de dados, criará uma classe de
Active Record, definirá uma action e criará uma view.
Ao longo deste tutorial, você aprenderá como:
- configurar uma conexão de BD
- definir uma classe Active Record
- consultar dados usando a classe de Active Record
- exibir dados em uma view de forma paginada
Perceba que para terminar essa seção, você deve ter conhecimento e experiência básicos em bancos de dados. Em particular, você deve saber como criar um banco de dados e como executar instruções SQL usando uma ferramenta cliente de bancos de dados.
Preparando o Banco de Dados ¶
Para começar, crie um banco de dados chamado yii2basico
, de onde você
obterá os dados em sua aplicação. Você pode criar um banco de dados SQLite, MySQL,
PostgreSQL, MSSQL ou Oracle, já que o Yii tem suporte embutido a vários gerenciadores de bancos de dados. Por questões de simplicidade, será assumido o uso do MySQL
na descrição a seguir.
Info: O MariaDB costumava ser um substituto transparente do MySQL. Isto já não é mais totalmente verdade. Caso você queira usar recursos avançados como suporte a
JSON
no MariaDB, por favor, consulte a extensão do MariaDB listada mais à frente.
Em seguida, crie uma tabela chamada pais
no banco de dados e insira alguns
dados de exemplo. Você pode rodar as seguintes declarações SQL para fazer isso:
CREATE TABLE `pais` (
`codigo` CHAR(2) NOT NULL PRIMARY KEY,
`nome` CHAR(52) NOT NULL,
`populacao` INT(11) NOT NULL DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `pais` VALUES ('AU','Austrália',24016400);
INSERT INTO `pais` VALUES ('BR','Brasil',205722000);
INSERT INTO `pais` VALUES ('CA','Canadá',35985751);
INSERT INTO `pais` VALUES ('CN','China',1375210000);
INSERT INTO `pais` VALUES ('DE','Alemanha',81459000);
INSERT INTO `pais` VALUES ('FR','França',64513242);
INSERT INTO `pais` VALUES ('GB','Reino Unido',65097000);
INSERT INTO `pais` VALUES ('IN','Índia',1285400000);
INSERT INTO `pais` VALUES ('RU','Rússia',146519759);
INSERT INTO `pais` VALUES ('US','Estados Unidos',322976000);
Neste ponto, você tem um banco de dados chamado yii2basico
e dentro dele uma
tabela pais
com três colunas, contendo dez linhas de dados.
Configurando uma Conexão de BD ¶
Antes de prosseguir, certifique-se de que você possui instalados tanto a
extensão PDO do PHP quanto o driver
PDO para o gerenciador de banco de dados que você está usando (por exemplo, pdo_mysql
para o MySQL).
Este é um requisito básico se a sua aplicação usa um banco de dados relacional.
Tendo esses instalados, abra o arquivo config/db.php
e mude os parâmetros conforme seu banco de dados.
Por padrão, o arquivo contém o seguinte:
<?php
return [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=yii2basico',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
];
O arquivo config/db.php
é uma típica ferramenta de configuração baseada em arquivo. Este arquivo de configuração em particular especifica
os parâmetros necessários para criar e inicializar uma instância yii\db\Connection
por meio da qual você pode fazer consultas SQL ao banco de dados subjacente.
A conexão configurada acima pode ser acessada no código da aplicação através da expressão Yii::$app->db
.
Info: O arquivo
config/db.php
será absorvido (incluso) pela configuração principal da aplicaçãoconfig/web.php
, que especifica como a instância da aplicação deve ser inicializada. Para mais informações, por favor, consulte a seção Configurações.
Se você precisa trabalhar com bancos de dados para os quais não há suporte nativo no Yii, consulte as seguintes extensões:
Criando um Active Record ¶
Para representar e buscar os dados da tabela pais
, crie uma classe que deriva de Active Record chamada Pais
e salve-a
no arquivo models/Pais.php
.
<?php
namespace app\models;
use yii\db\ActiveRecord;
class Pais extends ActiveRecord
{
}
A classe Pais
estende de yii\db\ActiveRecord. Você não precisa escrever
nenhum código nela! Só com o código acima, o Yii descobrirá o nome da tabela
associada a partir do nome da classe.
Info: Se não houver nenhuma correspondência direta do nome da classe com o nome da tabela, você pode sobrescrever o método yii\db\ActiveRecord::tableName() para especificar explicitamente o nome da tabela associada.
Usando a classe Pais
, você pode manipular facilmente os dados na tabela
pais
, conforme é demonstrado nos fragmentos de código a seguir:
use app\models\Pais;
// obtém todas as linhas da tabela pais e as ordena pela coluna "nome"
$paises = Pais::find()->orderBy('nome')->all();
// obtém a linha cuja chave primária é "BR"
$pais = Pais::findOne('BR');
// exibe "Brasil"
echo $pais->nome;
// altera o nome do país para "Brazil" e o salva no banco de dados
$pais->nome = 'Brazil';
$pais->save();
Info: O Active Record é uma maneira poderosa de acessar e manipular dados do banco de dados de uma forma orientada a objetos. Você pode encontrar informações mais detalhadas na seção [Active Record](db-active-record.md. Alternativamente, você também pode interagir com o banco de dados usando um método de acesso a dados em baixo nível chamado Objeto de Acesso a Dados (Data Access Objects).
Criando uma Action ¶
Para disponibiliar os dados de países aos usuários finais, você precisa criar uma nova
action. Em vez de colocar a nova action no controller site
como você fez nas seções anteriores, faz mais sentido criar um novo controller
especificamente para todas as actions relacionadas aos dados de países. Chame
este novo controller de PaisController
, e crie uma action index
nele,
conforme o exemplo a seguir:
<?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();
$paginacao = new Pagination([
'defaultPageSize' => 5,
'totalCount' => $query->count(),
]);
$paises = $query->orderBy('nome')
->offset($paginacao->offset)
->limit($paginacao->limit)
->all();
return $this->render('index', [
'paises' => $paises,
'paginacao' => $paginacao,
]);
}
}
Salve o código acima no arquivo controllers/PaisController.php
.
A action index
chama Pais::find()
. Este método do Active Record constrói
uma consulta ao BD e retorna todos os dados da tabela pais
. Para limitar o
número de países retornados a cada requisição, a consulta é paginada com a ajuda
de um objeto yii\data\Pagination. O objeto Pagination
serve para dois propósitos:
- Define as cláusulas
offset
elimit
da declaração SQL representada pela query (consulta) de modo que apenas retorne uma única página de dados por vez (no exemplo, no máximo 5 linhas por página). - É usado na view para exibir um paginador que consiste de uma lista de botões de páginas, conforme será explicado na próxima subseção.
No final do código, a action index
renderiza uma view chamada index
e envia a ela os dados dos países e as informações de paginação.
Criando uma View ¶
Dentro do diretório views
, primeiro crie um subdiretório chamado pais
.
Esta pasta será usada para guardar todas as views renderizadas pelo controller
PaisController
. Dentro do diretório views/pais
, crie um arquivo index.php
contendo o seguinte:
<?php
use yii\helpers\Html;
use yii\widgets\LinkPager;
?>
<h1>Países</h1>
<ul>
<?php foreach ($paises as $pais): ?>
<li>
<?= Html::encode("{$pais->nome} ({$pais->codigo})") ?>:
<?= $pais->populacao ?>
</li>
<?php endforeach; ?>
</ul>
<?= LinkPager::widget(['pagination' => $paginacao]) ?>
A view tem duas seções relativas à exibição dos dados dos países. Na primeira parte,
os dados de países fornecidos são percorridos e renderizados como uma lista HTML.
Na segunda parte, um widget yii\widgets\LinkPager é renderizado usando as
informações de paginação passadas pela action. O widget LinkPager
exibe uma
lista de botões de páginas. Clicar em qualquer um deles vai atualizar os dados dos países conforme a página correspondente.
Conferindo ¶
Para ver se todo os códigos acima funcionam, use o seu navegador para acessar a seguinte URL:
http://hostname/index.php?r=pais/index
Primeiramente, você verá uma lista exibindo cinco países. Abaixo dos países, você verá um paginador com quatro botões. Se você clicar no botão "2", você verá a página exibir outros cinco países do banco de dados: a segunda página de registros. Observe mais cuidadosamente e você perceberá que a URL no browser mudou para
http://hostname/index.php?r=pais/index&page=2
Por trás das cortinas, Pagination está fornecendo toda a funcionalidade necessária para paginar um conjunto de dados:
- Inicialmente, Pagination representa a primeira página,
que reflete a consulta SELECT de países com a cláusula
LIMIT 5 OFFSET 0
. Como resultado, os primeiros cinco países serão buscados e exibidos. - O widget LinkPager renderiza os botões das páginas
usando as URLs criadas pelo Pagination.
As URLs conterão um parâmetro
page
, que representa os diferentes números de páginas. - Se você clicar no botão de página "2", uma nova requisição para a rota
pais/index
será disparada e tratada. Pagination lê o parâmetropage
da URL e define o número da página atual como sendo 2. A nova consulta de países então terá a cláusulaLIMIT 5 OFFSET 5
e retornará os próximos cinco países para a exibição.
Resumo ¶
Nesta seção, você aprendeu como trabalhar com um banco de dados. Você também aprendeu como buscar e exibir dados em páginas com a ajuda do yii\data\Pagination e do yii\widgets\LinkPager.
Na próxima seção, você aprenderá como usar a poderosa ferramenta de geração de códigos, chamada Gii, para ajudá-lo a implementar rapidamente algumas funcionalidades comumente necessárias, tais como as operações CRUD (Criar-Ler-Atualizar-Excluir) para trabalhar com os dados de uma tabela do banco de dados. Na verdade, todo o código que você acabou de escrever pode ser gerado automaticamente no Yii usando a ferramenta Gii.