Conectando e consultando um banco de dados com o PHP7

Formas de conexão

Atualmente é possível efetuar a conexão do PHP 7 com o banco de dados de duas formas:

Usando a extensão MySQLi - a qual acessa apenas bancos MySQL.
Usando PDO (PHP Data Objects) - O qual é utilizado para acessar bancos diversos, em torno de 12 sistemas de bancos de dados diferentes. Para maiores informações acesse o site oficial.

Obs: Algumas funções antigas como: mysql_connect, mysql_query, etc... Foram descontinuadas.


Qual das duas formas de conexão é a melhor?

Na verdade, as duas formas realizam muito bem a conexão com o banco de dados.

A questão é... o que é mais prático e posteriormente poderá facilitar mudanças?

Neste caso o mais recomendado é utilizarmos PDO, pois caso seja necessário a mudança de um sistema de banco de dados para outro, com o PDO tudo isso seria muito simples, não seria necessário nenhuma mudança extrema no código, apenas algumas alterações no momento da conexão com o banco. 

Caso deseje utilizar mais de um banco na aplicação, também é recomendado o uso do PDO.

Agora se a questão é performance, e você estiver utilizando aplicação apenas com bancos MySQL, recomendamos o uso da extensão mysqli.


Instalação

MySQLi - É um driver nativo a partir do PHP 5.3.0. Para mais informações acesse o site oficial clicando aqui
PDO - Para detalhes de instalação acesse o site oficial clicando aqui

Preparação para execução dos exemplos:

Abaixo serão apresentados alguns exemplos de conexão com o banco, caso você tenha interesse em testá-los em seu computador, é necessário a criação de um banco de dados MySql. Para isso execute os comandos abaixo através do seu gerenciador de banco de dados MySQL, pode ser no PhPMyAdmin ou MySQL Workbench, entre outros.

CREATE DATABASE db_cadastrousuarios;

USE db_cadastrousuarios;

CREATE TABLE tb_usuarios (
    idusuario int NOT NULL AUTO_INCREMENT,
    nome varchar(64) NOT NULL,
    idade int NOT NULL,
    cidade varchar(64) NOT NULL,
    email varchar(64) NOT NULL,
    PRIMARY KEY (idusuario)
);

INSERT INTO tb_usuarios (nome, idade, cidade, email) VALUES ("Joana Silva", 30, "São Paulo","um_email_qualquer");
INSERT INTO tb_usuarios (nome, idade, cidade, email) VALUES ("Marlene de Souza", 33, "São Paulo", "um_email_qualquer");
INSERT INTO tb_usuarios (nome, idade, cidade, email) VALUES ("Marcos Silva", 18, "Itapira", "um_email_qualquer");
INSERT INTO tb_usuarios (nome, idade, cidade, email) VALUES ("João Carlos Mello", 39, "Socorro",  "um_email_qualquer");

Com o banco de dados criado e uma tabela com registros, segue abaixo os exemplos de conexão.


Exemplos de conexão com o banco usando MySQLi:

<?php
	
$host = 'localhost'; //host
$usuario = 'root'; //usuário
$senha = ''; //senha
$database = 'db_cadastrousuarios'; //banco de dados

// Criando a conexão
$conn = new mysqli($host, $usuario, $senha, $database);

//ajusta o charset de comunicação entre a aplicação e o banco de dados
mysqli_set_charset($conn, 'utf8');

// Verificando a conexao
if ($conn->connect_error) {
    die("Conexão falhou: " . $conn->connect_error);
} 
echo "Conectado com sucesso.</br></br>";

$result = $conn->query("SELECT * FROM tb_usuarios ORDER BY idusuario"); 

if ($result->num_rows > 0) {				    
				    
    while($row = $result->fetch_assoc()) {
        
        echo "<strong>ID:</strong> ". $row['idusuario']."</br>".
			 "<strong>Nome:</strong> ". $row['nome']."</br>".
			 "<strong>Idade:</strong> ". $row['idade']."</br>".
			 "<strong>Cidade:</strong> ". $row['cidade']."</br>".
			 "<strong>Email:</strong> ". $row['email']."</br>".
			 "------------------------------------------------------------ </br></br>";
 	}
 } else {
 	echo "A consulta não retornou resultados.";
 }
 
$conn->close();

?>

 

Comentando o código acima:

Linha 3 a 6: Informamos os dados de acesso ao banco de dados;

Linha 9 a 18: Realizamos a conexão com o banco usando a classe mysqli e a testamos;

Linha 20 a 35: Executamos uma consulta no banco e exibimos o resultado.

Linha 37: Encerramos a conexão;

 

Conexão através do MySqli e consulta utilizando Prepared Statements(Declarações Preparadas) e Bound Parameters(Parâmetros Vinculados)

Abaixo vamos verificar basicamente uma consulta parecida, mas utilizando Prepared Statements (Declarações Preparadas) e Bound Parameters (Parâmetros Vinculados). Tudo isso funciona da seguinte forma:

Preparamos um modelo de declaração SQL que é enviado ao banco de dados. Os valores a serem usados na consulta não são especificados, são apenas rotulados, no caso abaixo com o caractere " ? ".

Ex: "UPDATE tb_usuarios SET nome = ?, idade = ?, cidade = ?, email = ? WHERE idusuario = ?"
O banco de dados posteriormente avalia, compila e executa a otimização da consulta no modelo de declaração SQL armazenando o resultado sem executar.

Por fim, a aplicação, ou seja, o código PHP, une a declaração preparada com os parâmetros e executa a instrução. E isso pode ser executado inúmeras vezes com valores diferentes apontando para os valores rotulados como "?".

 

<?php

$host = 'localhost'; //host
$usuario = 'root'; //usuário
$senha = ''; //senha
$database = 'db_cadastrousuarios'; //banco de dados

// Criando a conexão
$conn = new mysqli($host, $usuario, $senha, $database);

mysqli_set_charset($conn, 'utf8');

// Verificando a conexao
if ($conn->connect_error) {
    die("Conexão falhou: " . $conn->connect_error);
} 
echo "Conectado com sucesso.</br></br>";

//stmt - prepared statements - comando preparado
$stmt = $conn->prepare("SELECT * FROM tb_usuarios WHERE cidade = ?");

$stmt->bind_param("s", $_POST['cidade']);

$_POST['cidade'] = "São Paulo";
$stmt->execute();
$results = $stmt->get_result();
imprimirResultados($results);


//A consulta pode ser repetida várias vezes com valores diferentes
$_POST['cidade'] = "Osasco";
$stmt->execute();
$results = $stmt->get_result();
imprimirResultados($results);


function imprimirResultados($results){
	foreach ($results as $row) {
		foreach ($row as $key => $value) {
			echo "<strong>".$key.": </strong>".$value."<br/>";
		}
		echo "---------------------------------------------------------------<br/>";
	}
}

$stmt->close();
$conn->close();

?>

Comentando o código acima:

Linha 20: É onde usamos Prepared Statements - Preparamos um modelo de declaração SQL que é enviado ao banco de dados usando parâmetros vinculados " ? ".

Linha 22: É onde passamos os valores que substituem os " ? " dentro da declaração no momento da consulta, é necessário informarmos também o tipo de dado do parâmetro o qual será passado. A função bind_param("s", $_POST['cidade']) faz a ligação dos parâmetros a consulta e o argumento "s" informa o tipo de dado do parâmetro. Nesse caso estamos informando que $_POST['cidade'] é uma string.

O argumento pode ser um dos quatro tipos:

i - inteiro

d - duplo

s - string

b - BLOB

Lembrando que é necessário seguir a ordem com que os parâmetros "?" foram inseridos na query, caso seja utilizado mais de um parâmetro na consulta.

Linha 25: Momento em que solicitamos a execução da consulta.

Linha 26: É onde recebemos o retorno da consulta.

Linha 27: Passamos o resultado da consulta para a função imprimirResultados() efetuar a exibição na tela.

Linha 46: Encerramos a declaração preparada.

Linha 47: Encerramos a conexão com o banco. 


Quais são as vantagens ao utilizarmos Prepared Statements e Bound Parameters?

A principal é que são muito úteis contra SQL Injections, pois os valores dos parâmetros, são transmitidos posteriormente usando um protocolo diferente, não precisam ser escapados. E se o modelo de declaração original não for de entrada externa a injeção SQL pode não ocorrer.

Também ajudam o banco a reduzir o tempo de verificação, pois a preparação da consulta é feita apenas uma vez, mesmo que a instrução seja realizada várias vezes com valores diferentes.

Os Bound Parameters (Parâmetros Vinculados), minimizam a largura de banda do servidor, pois os parâmetros são enviados apenas uma vez, e não a toda consulta. 


Exemplos de conexão com o banco usando PDO:

<?php

try 
{
	//PDO faz a conexão com o bd independente de qual banco será utilizado.
	$conn = new PDO("mysql:dbname=db_cadastrousuarios;host=localhost", "root","", 
		array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));	

	//Imprime cada linha de retorno da consulta
	foreach($conn->query("SELECT idusuario, nome, idade, cidade, email FROM tb_usuarios ORDER BY idusuario") as $row) {
			
		 echo "<strong>ID:</strong> ". $row['idusuario']."</br>".
			 "<strong>Nome:</strong> ". $row['nome']."</br>".
			 "<strong>Idade:</strong> ". $row['idade']."</br>".
			 "<strong>Cidade:</strong> ". $row['cidade']."</br>".
			 "<strong>Email:</strong> ". $row['email']."</br>".
			 "------------------------------------------------------------ </br></br>";
	}	

	//Fecha a conexão
	$conn = null; 

} catch (PDOException $e) { 
    print "Error!: " . $e->getMessage() . "<br/>";
    die();
}

Comentando o código acima:

Linha 6: Realiza a conexão com o banco utilizando PDO. Note que no trecho $conn = new PDO("mysql:dbname=db_cadastrousuarios; - estamos definindo qual banco será utilizado - MySQL e o nome da base de dados.

Ex: Caso este banco db_cadastrousuarios exista no SQL Server, bastaria modificar para: $conn = new PDO ("sqlsrv: Database= db_cadastrousuarios; server=CASA-PC; ConnectionPooling=0", "root","");, vamos imaginar que este banco exista no PostgreSQL, então a conexão ficaria: $conn = new PDO ("pgsql: host=192.168.137.1; port=5432; dbname= db_cadastrousuarios', "root", "" ");

Linha 7: Ao utilizarmos na conexão array( PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8" ) - ajustamos o charset.

Linha 10 a 18: Efetuamos a consulta e usamos um foreach para efetuarmos a exibição de cada linha retornada.

Linha 21: Fechamos a conexão.

 

Conexão através do PDO e consulta utilizando Prepared Statements(Declarações Preparadas) e Bound Parameters(Parâmetros Vinculados)

Segue abaixo outro exemplo utilizando declarações preparadas e parâmetros vinculados. Note que ao utilizar PDO os parâmetros da consulta estão vinculados com outros rótulos específicos. 

<?php 

try 
{	
	$conn = new PDO("mysql:dbname=db_cadastrousuarios;host=localhost", "root","", 
		array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));	

	$stmt = $conn->prepare("INSERT INTO tb_usuarios (nome, idade, cidade, email) VALUES (:nome, :idade, :cidade, :email)");

	$stmt->bindParam(":nome", $nome);
	$stmt->bindParam(":idade", $idade);
	$stmt->bindParam(":cidade", $cidade);
	$stmt->bindParam(":email", $email);

	//Inserindo uma linha
	$nome = "Carlos Almeida";
	$idade = 54;
	$cidade = "Sorocaba";
	$email = "um_email_qualquer"; 
	$stmt->execute();

	//Inserindo outra linha
	$nome = "Joséfa Souza de Mello";
	$idade = 44;
	$cidade = "Itapira";
	$email = "um_email_qualquer"; 
	$stmt->execute();

	echo "Linhas inseridas com sucesso.";


} catch (PDOException $e) { 
    print "Error!: " . $e->getMessage() . "<br/>";
    die();
}

$conn = null; 

 ?>

Comentando o código acima:

Linha 5 e 6: Faz a conexão com o banco utilizando PDO.

Linha 8: É onde usamos Prepared Statements - Preparamos um modelo de declaração SQL que é enviado ao banco de dados usando parâmetros vinculados com rótulos ":nome, :idade, :cidade, :email".

Linha 10 a 13: Vinculamos os parâmetros a declaração preparada, utilizando a função bindParam(),  no PDO não é necessário seguir nenhuma ordem e informar o tipo de dado do parâmetro.

Linha 16 a 19: Informamos os valores a incluídos através dos parâmetros vinculados.

Linha 20: Executamos o Insert no banco.

Linha 22 a 27: Informamos novos valores a serem incluídos através dos parâmetros vinculados e executamos um novo Insert no banco;

Linha 29: Informamos sucesso na operação.

Linha 32 a 35: Exibe mensagem de erro, caso seja capturada alguma exceção "falha" dentro do try{}.

Linha 37: Fechamos a conexão.

 


Conclusão

Neste artigo vimos as diversas formas de conexão e consultas de uma aplicação ao banco de dados no PHP7, fica agora por sua conta a aplicação dos conhecimentos em seus projetos.

Download dos arquivos de exemplo: ExemplosConexao.rar.


Fontes: 

http://php.net/ 

https://www.w3schools.com/