Access
 sql >> Base de Dados >  >> RDS >> Access

Por que você deve usar PHPs PDO para acesso ao banco de dados


Muitos programadores PHP aprenderam como acessar bancos de dados usando as extensões MySQL ou MySQLi. A partir do PHP 5.1, existe uma maneira melhor. O PHP Data Objects (PDO) fornece métodos para instruções preparadas e trabalho com objetos que o tornarão muito mais produtivo!

Geradores e estruturas de CRUD


O código do banco de dados é repetitivo, mas muito importante para acertar. É aí que entram os geradores e frameworks PHP CRUD:eles economizam tempo gerando automaticamente todo esse código repetitivo para que você possa se concentrar em outras partes do aplicativo.

Na CodeCanyon, você encontrará geradores e frameworks CRUD que o ajudarão a entregar produtos de excelente qualidade no prazo. (CRUD é um acrônimo para criar, ler, atualizar e excluir – as manipulações básicas para um banco de dados.)
  • PHP9 Geradores e frameworks PHP CRUD úteis disponíveis no CodeCanyonFranc Lucas
  • PHPCrie rapidamente uma interface PHP CRUD com a ferramenta PDO Advanced CRUD GeneratorSajal Soni

Introdução ao DOP

PDO—PHP Data Objects—são uma camada de acesso ao banco de dados que fornece um método uniforme de acesso a vários bancos de dados.

Ele não leva em conta a sintaxe específica do banco de dados, mas pode permitir que o processo de troca de bancos de dados e plataformas seja bastante simples, simplesmente trocando a string de conexão em muitos casos.

Este tutorial não pretende ser um tutorial completo sobre SQL. Ele foi escrito principalmente para pessoas que usam o mysql ou mysqli extensão para ajudá-los a dar o salto para o PDO mais portátil e poderoso.

Quando se trata de operações de banco de dados em PHP, o PDO oferece muitas vantagens sobre a sintaxe bruta. Vamos listar rapidamente alguns:
  • camada de abstração
  • sintaxe orientada a objetos
  • suporte para declarações preparadas
  • melhor tratamento de exceções
  • APIs seguras e reutilizáveis
  • suporte para todos os bancos de dados populares

Suporte de banco de dados


A extensão pode suportar qualquer banco de dados para o qual um driver PDO foi escrito. No momento da redação deste artigo, os seguintes drivers de banco de dados estão disponíveis:
  • PDO_DBLIB (FreeTDS/Microsoft SQL Server/Sybase)
  • PDO_FIREBIRD (Firebird/Interbase 6)
  • PDO_IBM (IBM DB2)
  • PDO_INFORMIX (Servidor dinâmico IBM Informix)
  • PDO_MYSQL (MySQL 3.x/4.x/5.x)
  • PDO_OCI (Interface de chamada do Oracle)
  • PDO_ODBC (ODBC v3 (IBM DB2, unixODBC e win32 ODBC))
  • PDO_PGSQL (PostgreSQL)
  • PDO_SQLITE (SQLite 3 e SQLite 2)
  • PDO_4D (D)

Todos esses drivers não estão necessariamente disponíveis em seu sistema; aqui está uma maneira rápida de descobrir quais drivers você tem:
print_r(PDO::getAvailableDrivers());

Conectando


Bancos de dados diferentes podem ter métodos de conexão ligeiramente diferentes. Abaixo, você pode ver o método para se conectar a alguns dos bancos de dados mais populares. Você notará que os três primeiros são idênticos, exceto o tipo de banco de dados - e o SQLite tem sua própria sintaxe.
experimente { # MS SQL Server e Sybase com PDO_DBLIB $DBH =new PDO("mssql:host =$host;dbname=$dbname", $usuário, $pass); $DBH =new PDO("sybase:host=$host;dbname=$dbname", $user, $pass); # MySQL com PDO_MYSQL $DBH =new PDO("mysql:host=$host;dbname=$dbname", $user, $pass); # Banco de Dados SQLite $DBH =new PDO("sqlite:my/database/path/database.db");}catch(PDOException $e) { echo $e->getMessage();}

Por favor, tome nota do bloco try/catch. Você deve sempre envolver suas operações PDO em um try/catch e usar o mecanismo de exceção – mais sobre isso em breve. Normalmente, você fará apenas uma única conexão — há várias listadas para mostrar a sintaxe. $DBH significa 'manipulador de banco de dados' e será usado ao longo deste tutorial.

Você pode fechar qualquer conexão definindo o identificador como nulo.
# fecha a conexão$DBH =null;

Você pode obter mais informações sobre opções específicas de banco de dados e/ou strings de conexão para outros bancos de dados em PHP.net.

Exceções e PDO


O PDO pode usar exceções para lidar com erros, o que significa que tudo o que você faz com o PDO deve ser encapsulado em um bloco try/catch. Você pode forçar o PDO em um dos três modos de erro definindo o atributo de modo de erro em seu identificador de banco de dados recém-criado. Aqui está a sintaxe:
$DBH->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT );$DBH->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING );$DBH->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );

Não importa o modo de erro que você definir, um erro de conexão sempre produzirá uma exceção, e a criação de uma conexão deve estar sempre contida em um bloco try/catch.

PDO::ERRMODE_SILENT


Este é o modo de erro padrão. Se você deixá-lo nesse modo, terá que verificar se há erros da maneira que provavelmente está acostumado se tiver usado o mysql ou mysqli extensões. Os outros dois métodos são mais adequados para programação DRY.

PDO::ERRMODE_WARNING


Este modo emitirá um aviso padrão do PHP e permitirá que o programa continue a execução. É útil para depuração.

PDO::ERRMODE_EXCEPTION


Este é o modo que você deseja na maioria das situações. Ele dispara uma exceção, permitindo que você lide com erros e oculte dados que possam ajudar alguém a explorar seu sistema. Aqui está um exemplo de como aproveitar as exceções:
# conectar ao banco de dadostry { $DBH =new PDO("mysql:host=$host;dbname=$dbname", $user, $pass); $DBH->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION ); #UH-OH! Digite DELECT em vez de SELECT! $DBH->prepare('DELECT name FROM people');}catch(PDOException $e) { echo "Desculpe, Dave. Receio não poder fazer isso."; file_put_contents('PDOErrors.txt', $e->getMessage(), FILE_APPEND);}

Há um erro intencional na instrução select; isso causará uma exceção. A exceção envia os detalhes do erro para um arquivo de log e exibe uma mensagem amigável (ou não tão amigável) para o usuário.

Inserir e atualizar


Inserir novos dados (ou atualizar dados existentes) é uma das operações de banco de dados mais comuns. Usando PHP PDO, este é normalmente um processo de duas etapas. Tudo coberto nesta seção se aplica igualmente a UPDATEINSERT operações.

Aqui está um exemplo do tipo mais básico de inserção:
# STH significa "Identificador de Instrução"$STH =$DBH->prepare("INSERT INTO people ( first_name ) values ​​( 'Cathy' )");$STH->execute();

Você também pode realizar a mesma operação usando o comando exec() método, com uma chamada a menos. Na maioria das situações, você usará o método mais longo para poder aproveitar as instruções preparadas. Mesmo que você vá usá-lo apenas uma vez, o uso de instruções preparadas ajudará a protegê-lo contra ataques de injeção de SQL.

Declarações Preparadas

O uso de instruções preparadas ajudará a protegê-lo contra injeção de SQL.

Uma instrução preparada é uma instrução SQL pré-compilada que pode ser executada várias vezes enviando apenas os dados para o servidor. Ele tem a vantagem adicional de tornar automaticamente os dados usados ​​nos espaços reservados protegidos contra ataques de injeção de SQL.

Você usa uma instrução preparada incluindo espaços reservados em seu SQL. Aqui estão três exemplos:um sem placeholders, um com placeholders sem nome e um com placeholders nomeados.
# sem espaços reservados - pronto para SQL Injection!$STH =$DBH->prepare("INSERT INTO people (name, addr, city) values ​​($name, $addr, $city)"); # espaços reservados sem nome$STH =$DBH->prepare("INSERT INTO people (name, addr, city) values ​​(?, ?, ?)"); # espaços reservados nomeados$STH =$DBH->prepare("INSERT INTO folks (name, addr, city) values ​​(:name, :addr, :city)");

Você quer evitar o primeiro método; está aqui para comparação. A escolha de usar espaços reservados nomeados ou não nomeados afetará a forma como você define os dados para essas instruções.

Espaços reservados sem nome

# atribui variáveis ​​para cada placeholder, indexado 1-3$STH->bindParam(1, $name);$STH->bindParam(2, $addr);$STH->bindParam(3, $city); # insere uma linha$name ="Daniel"$addr ="1 Wicked Way";$city ="Arlington Heights";$STH->execute(); # insere outra linha com valores diferentes$name ="Steve"$addr ="5 Circle Drive";$city ="Schaumburg";$STH->execute();

Há duas etapas aqui. Primeiro, atribuímos variáveis ​​aos vários espaços reservados (linhas 2–4). Em seguida, atribuímos valores a esses espaços reservados e executamos a instrução. Para enviar outro conjunto de dados, basta alterar os valores dessas variáveis ​​e executar a instrução novamente.

Isso parece um pouco complicado para instruções com muitos parâmetros? Isso é. No entanto, se seus dados estiverem armazenados em uma matriz, há um atalho fácil:
# os dados que queremos inserir$data =array('Cathy', '9 Dark and Twisty Road', 'Cardiff'); $STH =$DBH->prepare("INSERT INTO people (name, addr, city) values ​​(?, ?, ?)");$STH->execute($data);

Isso é fácil!

Os dados na matriz se aplicam aos espaços reservados em ordem. $data[0] vai para o primeiro marcador, $data[1] o segundo, etc. No entanto, se os índices de seu array não estiverem em ordem, isso não funcionará corretamente e você precisará reindexar o array.

Espaços reservados nomeados


Você provavelmente poderia adivinhar a sintaxe, mas aqui está um exemplo:
# o primeiro argumento é o nome do espaço reservado nomeado - observe que os espaços reservados# sempre começam com dois pontos.$STH->bindParam(':name', $name);

Você pode usar um atalho aqui também, mas funciona com arrays associativos. Aqui está um exemplo:
# os dados que queremos inserir$data =array( 'name' => 'Cathy', 'addr' => '9 Dark and Twisty', 'city' => 'Cardiff' ); # o atalho!$STH =$DBH->prepare("INSERT INTO people (name, addr, city) value (:name, :addr, :city)");$STH->execute($data); 
As chaves de sua matriz não precisam começar com dois pontos, mas, caso contrário, precisam corresponder aos espaços reservados nomeados. Se você tem um array de arrays, você pode iterar sobre eles e simplesmente chamar o método execute com cada matriz de dados.

Outro recurso interessante de espaços reservados nomeados é a capacidade de inserir objetos diretamente em seu banco de dados, supondo que as propriedades correspondam aos campos nomeados. Aqui está um objeto de exemplo e como você executaria sua inserção:
# uma simples objectclass person { public $name; public $addr; público $cidade; function __construct($n,$a,$c) { $this->nome =$n; $this->addr =$a; $esta->cidade =$c; } # etc ...} $cathy =new person('Cathy','9 Dark and Twisty','Cardiff'); # aqui está a parte divertida:$STH =$DBH->prepare("INSERT INTO people (name, addr, city) value (:name, :addr, :city)");$STH->execute((array)$ cathy);

Lançando o objeto para um array no execute significa que as propriedades são tratadas como chaves de matriz.

Selecionando dados


Os dados são obtidos por meio de ->fetch() , um método de seu identificador de instrução. Antes de chamar fetch, é melhor dizer ao PDO como você gostaria que os dados fossem buscados. Você tem as seguintes opções:
  • PDO::FETCH_ASSOC : retorna uma matriz indexada pelo nome da coluna.
  • PDO::FETCH_BOTH (padrão): retorna uma matriz indexada pelo nome e pelo número da coluna.
  • PDO::FETCH_BOUND : atribui os valores de suas colunas às variáveis ​​definidas com o ->bindColumn() método.
  • PDO::FETCH_CLASS : atribui os valores de suas colunas às propriedades da classe nomeada. Ele criará as propriedades se as propriedades correspondentes não existirem.
  • PDO::FETCH_INTO : atualiza uma instância existente da classe nomeada.
  • PDO::FETCH_LAZY :combina PDO::FETCH_BOTH /PDO::FETCH_OBJ , criando os nomes das variáveis ​​do objeto à medida que são usados.
  • PDO::FETCH_NUM : retorna uma matriz indexada pelo número da coluna.
  • PDO::FETCH_OBJ : retorna um objeto anônimo com nomes de propriedades que correspondem aos nomes das colunas.

Na verdade, existem três que abrangem a maioria das situações: FETCH_ASSOCFETCH_CLASSFETCH_OBJ . Para definir o método de busca, a seguinte sintaxe é usada:
$STH->setFetchMode(PDO::FETCH_ASSOC);

Você também pode definir o tipo de busca diretamente em ->fetch() chamada de método.

FETCH_ASSOC


Esse tipo de busca cria uma matriz associativa, indexada pelo nome da coluna. Isso deve ser bastante familiar para qualquer um que tenha usado as extensões mysql/mysqli. Aqui está um exemplo de seleção de dados com este método:
# usando o método de atalho ->query() aqui já que não há valores de variável# na instrução select.$STH =$DBH->query('SELECT name, addr, city from folks'); # configurando o modo de busca$STH->setFetchMode(PDO::FETCH_ASSOC); while($row =$STH->fetch()) { echo $row['name'] . "\n"; echo $row['addr'] . "\n"; echo $row['city'] . "\n";}

O loop while continuará a percorrer o conjunto de resultados uma linha de cada vez até ser concluído.

FETCH_OBJ


Este tipo de busca cria um objeto da classe std para cada linha de dados buscados. Aqui está um exemplo:
# criando a instrução$STH =$DBH->query('SELECT nome, endereço, cidade do pessoal'); # configurando o modo de busca$STH->setFetchMode(PDO::FETCH_OBJ); # mostrando os resultadoswhile($row =$STH->fetch()) { echo $row->name . "\n"; echo $row->addr . "\n"; echo $linha->cidade. "\n";}

FETCH_CLASS


As propriedades do seu objeto são definidas ANTES do construtor ser chamado. Isso é importante.

Este método de busca permite buscar dados diretamente em uma classe de sua escolha. Quando você usa FETCH_CLASS , as propriedades do seu objeto são definidas BEFORE o construtor é chamado. Leia isso de novo — é importante. Se as propriedades correspondentes aos nomes das colunas não existirem, essas propriedades serão criadas (como públicas) para você.

Isso significa que, se seus dados precisarem de alguma transformação depois de saírem do banco de dados, isso poderá ser feito automaticamente pelo seu objeto à medida que cada objeto é criado.

Como exemplo, imagine uma situação em que o endereço precisa ser parcialmente obscurecido para cada registro. Poderíamos fazer isso operando nessa propriedade no construtor. Aqui está um exemplo:
class secret_person { public $name; public $addr; público $cidade; public $outros_dados; function __construct($other ='') { $this->address =preg_replace('/[a-z]/', 'x', $this->address); $this->other_data =$other; }}

À medida que os dados são buscados nessa classe, o endereço tem todas as letras minúsculas a-z letras substituídas pela letra x . Agora, usar a classe e fazer com que essa transformação de dados ocorra é completamente transparente:
$STH =$DBH->query('SELECT name, addr, city from people');$STH->setFetchMode(PDO::FETCH_CLASS, 'secret_person'); while($obj =$STH->fetch()) { echo $obj->addr;}

Se o endereço fosse '5 Rosebud', você veria '5 Rxxxxxx' como sua saída. Claro, pode haver situações em que você deseja que o construtor seja chamado antes que os dados sejam atribuídos. O PDO também cobre isso.
$STH->setFetchMode(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, 'secret_person');

Agora, ao repetir o exemplo anterior com este modo de busca (PDO::FETCH_PROPS_LATE ), o endereço não ser obscurecido, uma vez que o construtor foi chamado e as propriedades foram atribuídas.

Finalmente, se você realmente precisar, você pode passar argumentos para o construtor ao buscar dados em objetos com PDO:
$STH->setFetchMode(PDO::FETCH_CLASS, 'secret_person', array('stuff'));

Se você precisar passar dados diferentes para o construtor para cada objeto, você pode definir o modo de busca dentro do fetch método:
$i =0;while($rowObj =$STH->fetch(PDO::FETCH_CLASS, 'secret_person', array($i))) { // faz coisas $i++}

Alguns outros métodos úteis


Embora isso não tenha a intenção de cobrir tudo no PDO (é uma extensão enorme!), existem mais alguns métodos que você deseja conhecer para fazer coisas básicas com o PDO.
$DBH->lastInsertId();

->lastInsertId() O método é sempre chamado no identificador do banco de dados, não no identificador da instrução, e retornará o id incrementado automaticamente da última linha inserida por essa conexão.
$DBH->exec('DELETE FROM people WHERE 1');$DBH->exec("SET time_zone ='-8:00'");

->exec() é usado para operações que não podem retornar dados além das linhas afetadas. O acima são dois exemplos de uso do método exec.
$seguro =$DBH->quote($inseguro);

->quote() O método cita strings para que sejam seguras para uso em consultas. Este é o seu substituto se você não estiver usando instruções preparadas.
$rows_affected =$STH->rowCount();

->rowCount() retorna um inteiro indicando o número de linhas afetadas por uma operação. Em pelo menos uma versão conhecida do PDO, o método não estava funcionando com instruções select. No entanto, ele funciona corretamente na versão PHP 5.1.6 e superior.

Se você estiver tendo esse problema e não puder atualizar o PHP, poderá obter o número de linhas com o seguinte:
$sql ="SELECT COUNT(*) FROM people";if ($STH =$DBH->query($sql)) { # verifica a contagem de linhas if ($STH->fetchColumn()> 0) { # emite um select real aqui, porque há dados! } else { echo "Nenhuma linha correspondeu à consulta."; }}

Geradores PHP CRUD do CodeCanyon


Você pode economizar horas encontrando um gerador PHP CRUD do CodeCanyon e usando-o em seus projetos. Aqui estão cinco dos downloads mais populares que você pode começar a usar agora.

1. Aplicação multifuncional Laravel:Sximo 6


O construtor Sximo 6 é baseado nos frameworks mais populares do mercado. Ele também recebeu uma nova atualização para 2021, tornando-o o mais fácil de usar e rico em recursos possível. Alguns desses recursos incluem:
  • gerenciamento de tabelas de banco de dados
  • Modelos de front-end e back-end
  • módulo editor MySQL
  • suporte a várias imagens e upload de arquivos

Experimente se quiser economizar tempo com um modelo CRUD PHP.

2. PDO Crud:Construtor de formulários e gerenciamento de banco de dados


Aqui está outro poderoso gerador PHP CRUD. Este modelo de código PHP PDO faz bem o gerenciamento de banco de dados. Mas isso não é tudo o que faz. Você também pode usar o PDO CRUD para construir formulários úteis diretamente de suas tabelas de banco de dados. É um recurso útil que muitas outras opções não têm.

3. Cicool:Página, Formulário, API Rest e Gerador de CRUD


Cicool é outro construtor multiuso que vale a pena analisar. Não apenas oferece um construtor CRUD, mas também possui:
  • construtor de páginas
  • criador de formulários
  • construtor de API de descanso

Além desses recursos, você também pode adicionar extensões ao Cicool e personalizar facilmente seu tema.

4. Gerador PHP CRUD


Construtor de painel de administração fácil? Verificar. Interface fácil de navegar? Verificar. Análise aprofundada do banco de dados? Outro cheque. Este gerador PHP CRUD tem tudo o que você precisa para construir ótimos painéis e armazenar seus dados. Com diferentes recursos de autenticação de usuário e gerenciamento de direitos, vale a pena conferir este modelo PHP PDO.