Categories
Programação

Executando Queries com PDO

Para executar uma query SQL vamos usar o método query() da classe PDO, que irá nos rertornar um objeto da classe PDOStatement.

Então vamos lá, executar a query e guardar o resultado em $statement:

$statement = $pdo->query("SELECT city.Name, city.CountryCode, city.District, city.Population FROM world.city");

var_dump($statement);

E aqui está a saída do var_dump() com um objeto da classe PDOStatement:

object(PDOStatement)#2 (1) { ["queryString"]=> string(82) "SELECT city.Name, city.CountryCode, city.District, city.Population FROM world.city" }

Continuando… Já temos um objeto do tipo PDOStatement, e o que fazermos como ele?

Vamos conhecer agora alguns métodos pertencentes a sua classe PDOStatement, começando pelo fetch() que busca a primeira linha retornarda da nossa query:

$one_row = $statement->fetch();
var_dump($one_row);

Como saída na tela, temos um array:

array(4) { ["Name"]=> string(5) "Kabul" ["CountryCode"]=> string(3) "AFG" ["District"]=> string(5) "Kabol" ["Population"]=> int(1780000) }

Vamos agora converter esse array para um objeto JSON, e deixar essa saída pronta para ser recuperada por qualquer outra parte do sistema, como o front-end. Para isso basta substituir nosso var_dump() por um json_encode():

$one_row = $statement->fetch();
echo json_encode($one_row);

E aqui está a informação pronta para se consumida:

{
    Name: "Kabul", 
    CountryCode: "AFG",
    District: "Kabol", 
    Population: 1780000
}

Aqui já temos algo útil para uso, mas… Calma aí. Até agora viemos trabalhando com POO, usando classes, métodos e objetos… E então recebemos esses dados em um array antes de passá-los adiante. Por que?

O que ocorre é que o retorno padrão do metódo fetch() é um array. Isso não chega a ser um problema se você quiser logo depois imprimir as informações em formato JSON, uma vez que a função json_encode() recebe justamente um array.

Mas e se quisermos receber do fetch() um objeto ao invés de um array? É fácil:

$one_row = $statement->fetch(true);
var_dump($one_row);

Dessa vez passamos no método fetch() um parâmetro booleano com “true”. Isso vai nos garantir que o retorno seja um objeto. Vamos de novo a saída…

object(PDORow)#3 (5) { 
    ["queryString"]=> string(82) "SELECT city.Name, city.CountryCode, city.District, city.Population FROM world.city" 
    ["Name"]=> string(5) "Kabul" 
    ["CountryCode"]=> string(3) "AFG" 
    ["District"]=> string(5) "Kabol" 
    ["Population"]=> int(1780000) 
}

Legal, agora temos um objeto PDORow, com cinco atributos, sendo o primeiro “queryString” a query SQL que foi executada, e os demais cada uma das colunas que vieram da query. Vamos imprimir cada coluna, e ver código completo até aqui, incluindo o que foi feito nos posts anteriores:

$dsn = "mysql:host=localhost;dbname=world;port=3306;charset=utf8mb4";
    
$username = 'my_username';
$password = 'my_password';
        
$options = [
    PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    PDO::ATTR_EMULATE_PREPARES   => false,
];
        
try {
     $pdo = new PDO($dsn, $username, $password, $options);
} catch (\PDOException $e) {
     throw new \PDOException($e->getMessage(), (int)$e->getCode());
}

$statement = $pdo->query("SELECT city.Name, city.CountryCode, city.District, city.Population FROM world.city");

$one_row = $statement->fetch(true);

echo $one_row->Name;
echo $one_row->CountryCode;
echo $one_row->District;
echo $one_row->Population;

Como saída temos agora:

Kabul AFG Kabol 1780000

Poderíamos até concatenar no final de cada echo ali em cima uma tag <br> para quebrar linhas e organizar melhor a informação impressa, mas isso começaria a sujar nosso código de backend, que deve somente buscar a informação no banco de dados.

Vamos então devolver a informação em formato JSON:

$one_row = $statement->fetch(true);
$one_object_json = array(
    $one_row->Name, 
    $one_row->CountryCode, 
    $one_row->District, 
    $one_row->Population
);
echo json_encode($one_object_json);

Se você leu o código com atenção, percebeu que eu coloquei cada um dos atributos: Name, CountryCode, District e Population dentro de um novo array, através da função array(), isso é devido ao fato da função json_encode() realmente precisar de um array como parâmetro de entrada.

Aqui está a saída:

[
    "Kabul",
    "AFG",
    "Kabol",
    1780000
]

Como visto, quando se trata de passar os dados obtidos para frente como JSON, não há vantagem em retornar um objeto no método fetch(). Mas então, como trabalhar com um objeto ao invés de um array e conseguir um retorno em JSON de forma fácil em PDO?

Vamos resolver isso no próximo post, com a criação de uma pequena mas poderosa classe! “A classe esquecida do PDO”.

Categories
Programação

O Poder do PDO

Não saber o poder do PHP Data Objects pode estar te levando a reinventar a roda todo dia!

Neste artigo vamos ver exemplos práticos de como utilizar PDO para facilitar sua vida, além de falar de boas e más praticas ao utilizá-lo.

Por que PDO?

Mas então, por que PDO afinal?

Resposta rápida:

Os reais benefícios do PDO são:

  • Segurança – Proteção contra SQL injections.
  • Usabilidade – Há muitos métodos prontos para automatizar operações totineiras.
  • Reutilização – O mesmo código PHP serve para acessar diferentes bancos de dados, de SQLite a Oracle, passando pelos populares SQLServer, PostgreSQL e claro MySQL.

Tudo sobre os benefícios do PDO:

PDO é uma camada de abstração de acesso ao banco de dados, que oferece uma interface unificada para acessar 12 bancos de dados diferentes, são eles:

  • PostgreSQL
  • SQLite
  • MySQL
  • Oracle
  • ODBC
  • MS SQLServer & Azure
  • Firebird
  • Informix
  • IBM DB2
  • Sybase
  • Cubrid
  • 4D

O PDO abstrai não apenas uma interface de conexão com banco de dados, mas também operações básicas que, de outra forma, teriam que ser repetidas centenas de vezes em cada aplicação, o que te levaria para bem longe de uma das premissas para ser um bom programador: Don’t Repeat Yourself (DRY)!

Ao contrário do mysql e do mysqli, que são ambos drivers de baixo nível servindo apenas como ponte entre o banco de dados MySQL e uma camada de abstração de nível superior, o PDO já é uma abstração pronta totalmente utilizável.

Bem, mas agora que já sabemos um pouco sobre os benefícios de se utilizar o PDO, não percamos mais tempo e vamos direto a ação! Começar a pôr a mão na massa!

Em seguida: Conectando a um banco de dados com PDO

Categories
Programação

Conectando a um Banco de Dados com PDO

O PDO tem um método de conexão sofisticado porém simples de usar, chamado Data Source Name (DSN). Tudo o que você fazer para utilizá-lo é inserir os valores para configuração nos seus locais adequados.

Para entendermos melhor o que precisamos para criar uma instância PDO vamos ver seu método construtor abaixo:

public function __construct(
    $dsn,
    $username = null,
    $passwd = null,
    $options = null
)

Perceba que ele recebe quatro parâmetros, sendo apenas o primero “dsn” obrigatório. Vamos ver cada um deles…

DSN: Como valores do tipo string, em $dsn vão: o driver do banco de dados, host, nome do banco (schema), porta, definição de charset, bem como o unix_socket quando for o caso.

$dsn = "mysql:host=localhost;dbname=test;port=3306;charset=utf8mb4";

Usuário e senha: Também como strings, passe $username e $password para conexão ao banco.

$username = "my_user";
$password = "my_password";

Options: Por último podemos passar aqui uma infinidade de outros parâmetros, dentro do último parâmetro $options, que se trata de um array.

$options = [
    PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    PDO::ATTR_EMULATE_PREPARES   => false,
];

Pronto, agora já temos tudo o que precisamos para fazer nossa conexão… O código completo ficaria assim:

$dsn = "mysql:host=localhost;dbname=test;port=3306;charset=utf8mb4";

$username = 'my_username';
$password = 'my_password';

$options = [
    PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    PDO::ATTR_EMULATE_PREPARES   => false,
];

try {
     $pdo = new PDO($dsn, $username, $password, $options);
} catch (\PDOException $e) {
     throw new \PDOException($e->getMessage(), (int)$e->getCode());
}

Com nossas quatro variáveis ​​mencionadas acima corretamente definidas, teremos o objeto $pdo criado, como uma nova instância da classe PDO.

Para nos certificar que tudo ocorreu bem, podemos ver as informações desse novo objeto adicionando ao final do nosso código a função de manipulação de variáveis var_dump():

var_dump($pdo);

Como resultado teremos impresso na tela:

object(PDO)#1 (0) { }

Tudo certo! Vamos continuar…

Ah, sim, uma dica para quem por algum motivo ainda está usando PHP abaixo da versão 5.3.6… Atualize para a 7.0! No mínimo! Essa semana! Por favor…

Não é que eu queira, eu preciso…

Mas sério, se em versões muito antigas do PHP, você tiver problemas para definir o tipo de charset no MySQL usando o DSN, você pode fazer isso através de uma query SQL:

$pdo->exec("set names utf8");

Em seguida: Executando queries com PDO