Illustration of a bird flying.

Formas de conectar seu banco de dados com PHP


[vc_row][vc_column][vc_column_text][UPDATE 25/12/2017]

Este post foi escrito antes do lançamento oficial do PHP 7, que depreciou as funções mysql_*. Em breve atualizarei o mesmo com os exemplos utilizando as funções mysqli_*.

 

Este post é o primeiro de uma sequência infinita de posts gerados após um encontro de desenvolvedores. Em Setembro de 2015 foi realizado um fisbowl no VII FTSL no campus da UTFPR. Este encontro gerou uma discussão sadia, muitos dos presentes participaram dos debates, dezenas de temas foram sugeridos, alguns rejeitados no momento do sorteio e outros discutidos, alguns inclusive com direito à diversos rounds. Pois bem, creio que para os assuntos discutidos, a maioria da dúvidas possam ter sido sanadas naquele dia mesmo, no entanto ficaram uns tantos assuntos bem interessantes que com toda certeza merecem uma explanação em forma de posts. Claro que ressalto que longe de mim querer ser o detentor da verdade, no entanto, com toda certeza ao meu alcance passar a minha visão sobre determinados assuntos, como é a base deste meu blog mesmo. Comentários à vontade. Pois bem, o primeiro tema é sobre formas de conectar seu banco de dados com o PHP. Neste post demonstrarei alguns exemplos práticos que com toda certeza auxiliarão os desenvolvedores PHP, principalmente os iniciantes, que é o foco deste post, boa leitura!

 

O PHP é uma linguagem de programação dinâmica, não apenas em sua tipagem (que é tipagem DINÂMICA e não FRACA), mas sim em sua forma possibilitar com que os desenvolvedores construam suas aplicações, você pode usar e abusar da orientação à objetos para algo mais controlado, que merece um cuidado a longo prazo, bem como pode criar algo extremamente rápido de forma estrutural para um projeto simples e objetivo. Não existe essa de paradigma X é melhor que Y, tudo depende do que você precisa criar. Pois bem, com a conexão do banco de dados é a mesma coisa, se você tem algo pontual a entregar e tem a certeza de que aquilo finalizou, utilize as funções nativas do PHP para isto, não há mal nenhum! No entanto se você está criando algo que estima ter uma longa vida, seja no funcionamento bem como em constantes manutenções, sugiro você ter um pouco mais de trabalho para que possa ao longo de anos poder evoluir sua aplicação com poucas ou nenhuma dor de cabeça.

Ok, mas até aqui tudo parece apenas ser mais um conselho, você deve estar querendo algo palpável certo? Pois bem, vamos botar a mão na massa. Prepare seu ambiente, pega um cafezinho, esteja com a mente relaxada. Esta leitura está estimada em cerca de 25 minutos e após isto você conhecerá:

  • Manipulação de banco de dados Mysql com as funções nativas do PHP
  • Manipulação com o PDO
  • Manipulação com o Doctrine ORM

 

Vamos lá?![/vc_column_text][vc_column_text]

Criando um banco de dados simples

Neste primeiro passo, crie inicialmente um banco de dados conforme o esquema abaixo. Este banco servirá somente para embasar o funcionamento, justamente por isso de todos os campos e parâmetros utilizados até mesmo no PHP estarem em Português, para simplificar a leitura.

Imagino que a maioria dos desenvolvedores possui o mysql instalado de alguma forma, seja nativo do Sistema Operacional como pelos *AMPs (LAMP, XAMPP, MAMP e outros). Se sim, apenas cole o conteúdo abaixo no seu editor SQL e o execute.

 

-- -----------------------------------------------------
-- Schema blog
-- -----------------------------------------------------
CREATE SCHEMA IF NOT EXISTS `blog` DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
USE `blog` ;

-- -----------------------------------------------------
-- Table `blog`.`posts`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `blog`.`posts` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `titulo` VARCHAR(255) NULL,
  `conteudo` TEXT NULL,
  PRIMARY KEY (`id`))
ENGINE = MyISAM;

 

Feito isto, vamos começar a colocar a mão na massa (mesmo).

 

Tudo no index.php, pra começar

Começaremos de imediato com a conexão mais simples possível de se fazer com o PHP, com suas funções nativas. Crie uma pasta de teste e dentro dela um arquivo index.php, pode criar com a ferramenta que achar mais adequada, utilizarei o SublimeText 2. Após isto, abra o seu terminal (shell), entre na pasta recém criada e inicie o server embutido do PHP através do comando: php -S localhost:8080.

No arquivo index, conecte seu banco de dados mysql:

<?php
# index.php
// Exibindo todos os erros e warnings para facilitar a identificação de erros
ini_set('display_errors', true);
error_reporting(E_ALL);

$host = 'localhost';
$user = 'root';
$pass = 'root';
$database = 'blog';

mysql_connect($host, $user, $pass) or die('Não foi possível conectar');

mysql_select_db($database) or die('Não foi possível conectar com o banco de dados');

echo 'Banco de dados conectado com sucesso';

 

Ao abrir seu browser no endereço https://localhost:8080 o banco deve estar conectado, ignore os erros, por enquanto.

02-index-mysql-connectOk mas e o erro que mostra? Esta tela laranja que é exibida (que para você pode não estar formatado assim por causa do xdebug) informa que a função nativa de conexão com o mysql foi marcada como obsoleta e em versões mais novas (como o caso do PHP 7) não mais será possível utitilizar desta forma, mas calma, você ainda poderá utilizar por um bom tempo, visto que as hospedagens no Brasil levam anos para atualizar as versões do PHP.

 

Realizando a primeira consulta

Para não estender muito este post, eu populei a tabela posts, faça o mesmo, adicione quantos registros quiser e em seguida realize a consulta exibida abaixo.

<?php
# index.php
// ...
$result = mysql_query('SELECT * FROM posts');

if (mysql_affected_rows() && !mysql_error()) {
    echo 'Exibindo ' . mysql_affected_rows() . ' registros localizados <br /><br />';
    while($item = mysql_fetch_assoc($result)) {
        echo 'Post: ' . $item['titulo'] . ' Conteúdo: ' . $item['conteudo'] . '<br />';
    }
}

 

O resultado será algo como abaixo: Novamente, ignore o erro.

04-exibindo-registros-mysql

Tudo funcionando corretamente. Que tal agora baixarmos o nível de log de erros apenas para termos uma tela mais bonitinha? Isto é válido visto que até este ponto você já está ciente de que as funções nativas do PHP serão removidas na versão 7, que será lançado em breve mas ainda levará muito tempo para os hosts a aderirem.

No seu index.php, onde tá error_reporting(E_ALL) mude para error_reporting(E_ERROR), ainda é possível remover as 2 linhas de log de erros, faça assim se preferir. Dê um refresh em seu browser e pronto, agora temos todas as informações necessárias sem a tela de erros.

05-sem-erros

Agora pensemos em um cenário em que você tenha centenas de consultas semelhantes à que foi mostrada, mais ainda, mais centenas de inserts, deletes e updates… Todos com as funções nativas do PHP, neste caso, para o Mysql, mysql_*. Imaginou tudo como eu descrevi? Agora pense que sua aplicação cresceu e por exigências de um DBA ou mesmo por parte de uma empresa o banco de dados tenha de mudar… Problemas à vista não é mesmo? Apenas pense, são dezenas, centenas, milhares de linhas de código que você terá de alterar para que sua aplicação suporte um novo banco de dados. Como resolver? Existem duas saídas elegantes para esta situação. A primeira é pela utilização de PDO (PHP Data Objects) e a segunda pela utilização de um ORM (Object Relational Mapper), apresentarei ambas nas próximas linhas.

 

PDO

Apenas por curiosidade, sabe quando surgiu o PDO? Não?! Na versão 5 do PHP, em 2004! Assutador não é mesmo, fazem mais de 11 anos e até hoje tem programador PHP que não o conhece. Pois bem, o PDO facilita muito a manutenção de diversos bancos de dados (Sqlite, Mysql, Oracle, SQL Server…) além de dar uma camada de segurança por utilizar diversos recursos de filtros e manipulação como prepared statements. Abaixo, a mesma conexão que já realizamos no index.php foi portada para o PDO, perceba a diferença.

06-pdo

Como perceptível na linha 12, se precisarmos alterar o banco de dados do Mysql para o Postgres por exemplo, basta informar nesta linha os novos parâmetros e, se o restante da sua aplicação estiver bem estruturada, nenhuma ou muito pouca alteração deverá ser feita. Concorda que é muito mais prático?! Sem contar na segurança, veja abaixo a diferença entre um insert no banco com função nativa e com o PDO.

Perceba que na linha 37 apenas estou “dizendo” ao Mysql: confia em mim, estou filtrando/validando os dados, pode inserir. Mas neste ponto se a minha validação falhou, o estrago pode ser irreparável. Já nas linhas 41 e 42, mesmo após ter filtrado os dados (linhas 34 e 35) eu ainda “falo”: Olha PDO, eu filtrei, mas filtra de volta, faz o seu melhor! E pronto, o próprio PDO lhe fornece uma camada extra de segurança, isso é ótimo!

 

ORM

O ORM é de longe o que eu mais indico, ele é seguro, robusto e de quebra faz você tratar seus registros do banco de dados como objetos em sua aplicação. Um ORM (Object Relational Mapper) transforma toda tabela em uma entidade (encare como uma Model) facilitando a manipulação do banco de dados. A principal vantagem do ORM é que você se preocupa com sua aplicação, detalhes do banco de dados, deixa com ele! Os ORMs estão presentes em forma de bibliotecas independentes (normalmente gerenciadas pelo Composer) e em muitos frameworks, alguns inclusive tem seu próprio ORM com é o caso do CakePHP e do Laravel. Aqui mostrarei o de longe mais utilizado no mundo PHP, o Doctrine. Não vou entrar em detalhes da instalação e configuração do Doctrine aqui mas deixarei referências para que você consiga trabalhar com ele no fim deste post.

Abaixo exemplifico a mesma consulta já mostrada com as funções nativas do PHP e com PDO.

08-doctrine-find

 

Fácil né?! O EntityManager faz parte do Doctrine, a partir do momento que temos um repositório, podemos buscar um ou mais registros, atualizar dados, salvar tais dados… Agora veja como ficaria um insert no banco de dados utilizando o Doctrine ORM:

09-doctrine-persis-flush

Como é perceptível, eu não tenho conhecimento de detalhes do banco de dados, quem faz isso por mim é o Doctrine, eu apenas manipulo objetos, seto seus respectivos dados e digo ao Doctrine que ele deve salvar as alterações que fiz. Além de mais elegante é muito mais seguro que manipular o banco de dados diretamente, uso o Doctrine sempre que possível, para projetos maiores, não é nem uma vontade mas sim uma exigência.

Agora você deve ter ficado curioso com relação ao objeto Post certo? De onde vem, como é, como o Doctrine o reconhece… pois bem, vou apenas mostrar como ele seria nesta mesma abordagem deste post.

<?php

namespace SuaAplicacaoEntity;

use DoctrineORMMapping as ORM;

/**
 * Aqui é informado que este objeto representa uma tabela no banco de dados
 * 
 * @ORMTable(name="posts")
 * @ORMEntity
 */
class Post 
{
    /**
     * O ID é um campo com valores inteiros e setado como chave primária
     *
     * @ORMId
     * @ORMColumn(type="integer")
     * @ORMGeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * Informando que a tabela possui um campo chamado titulo com sua respectiva 
     * capacidade e que não pode ser nulo
     * 
     * @ORMColumn(type="string", length=255, nullable=false)
     */
    private $titulo;

    /**
     * Informando que a tabela possui um campo chamado conteúdo, 
     * do tipo texto e que não pode ser nulo
     *
     * @ORMColumn(type="text", nullable=false)
     */
    private $conteudo;

    // Getters and setters

    public function getId()
    {
        return $this->id;
    }

    public function getTitulo()
    {
        return $this->titulo;
    }

    public function getConteudo()
    {
        return $this->conteudo;
    }

    public function setTitulo($titulo)
    {
        $this->titulo = $titulo;
        return $this;
    }

    public function setConteudo($conteudo)
    {
        $this->conteudo = $conteudo;
        return $this;
    }

}

 

Simples não é mesmo? E mais uma vez reforçando, você não precisa saber de detalhes do banco de dados, mas sim de como utilizar os objetos mapeados.

 

Vantagens e desvantagens

Como você deve saber, as 3 abordagens mostradas aqui possuem suas vantagens e desvantagens. Abaixo listo as que considero principais.

 

Funções nativas (vantagens)

  • Muito fácil de utilizar
  • Mais rápido para quem está iniciando
  • Conexão nativa, mais rápida que os demais (para pequenas consultas)
  • Manda bem em pequenos/rápidos projetos

 

PDO (vantagens)

  • Seguro
  • Conecta com praticamente qualquer banco de dados
  • Fácil reaproveitamento de código
  • Possui diversos tratamentos e filtros para os mais diversos fins

 

ORM (vantagens)

  • Seguro
  • Abstrai a camada de banco de dados, desta forma você trabalha com objetos ao invés de queries
  • Deixa o código muito mais organizado

 

Funções nativas (desvantagens)

  • Tende a ser inseguro, o programador deve estar muito certo do que está fazendo
  • Antiquado, cairá em breve do PHP
  • Praticamente impossível reaproveitar código de forma inteligente

 

PDO (desvantagens)

  • Difícil para iniciantes

 

ORM (desvantagens)

  • Difícil para iniciantes
  • Requer bom conhecimento de orientação a objetos
  • Requer configurações que no começo são complexas
  • Não remove toda a necessidade de escrever queries manuais, para situações específicas será necessário escrever queries, para isto utilizando Query Builder ou DQL (Doctrine Query Language)

 

E agora?

Bem, até aqui você viu que existem pelo menos 3 formas de manipular o banco de dados com PHP, a forma com funções nativas, com PDO e com ORM. Também viu que o ORM é uma pedida excelente justamente por abstrair as coisas. Pois bem, com excessão das funcões nativas, você ainda tem muito estudo pela frente. O intuito deste post foi apenas apresentar as formas mais comuns de se manipular banco de dados no PHP, agora é contigo. Lógico que sugiro estudar tanto o uso do PDO quanto de um ORM, lhe trarão muitos benefícios.

Abaixo os links para as documentações oficiais:

 

PDO: https://php.net/manual/pt_BR/book.pdo.php

Doctrine ORM: https://www.doctrine-project.org/projects/orm.html

 

Como mencionei anteriormente neste post, caso queira saber de forma rápida como trabalhar com o Doctrine, sugiro a leitura deste meu artigo no Tableless. O artigo é sobre TDD mas em determinado ponto do mesmo é mostrado passo a passo como instalar, configurar e usar o Doctrine.

Também é claro que quero recomendar de olhos fechados o livro do fera Elton Minetto, Doctrine na prática. Ganhei este livro no final de 2013 num mini curso de Doctrine com o Minetto na PHP Conference, li e reli várias vezes. Diferente da documentação técnica, o livro segue uma abordagem prática com a criação de uma aplicação real, então dá pra ver como tudo funciona enquanto a leitura desenrola. Vale muito a pena o investimento![/vc_column_text][/vc_column][/vc_row]

, ,