Exemplos de PHP pdo mysql. Conexão com banco de dados PDO. Solicitações preparadas e diretas

  • Tradução

Muitos desenvolvedores PHP estão acostumados a usar as extensões mysql e mysqli para trabalhar com bancos de dados. Mas desde a versão 5.1 em PHP existem mais maneira conveniente- Objetos de dados PHP. Esta classe, abreviadamente chamada de PDO, fornece métodos para trabalhar com objetos e instruções preparadas que irão melhorar significativamente sua produtividade!

Introdução ao DOP

“PDO – PHP Data Objects é uma camada que oferece método universal trabalhando com vários bancos de dados."

Isso deixa a preocupação com os recursos de sintaxe de vários SGBDs para o desenvolvedor, mas torna o processo de alternância entre plataformas muito menos doloroso. Freqüentemente, isso requer apenas a alteração da cadeia de conexão do banco de dados.


Este artigo foi escrito para pessoas que usam mysql e mysqli para ajudá-las a migrar para o PDO mais poderoso e flexível.

Suporte SGBD

Esta extensão pode suportar qualquer sistema de gerenciamento de banco de dados para o qual exista um driver PDO. No momento em que este artigo foi escrito, os seguintes drivers estavam disponíveis:
  • PDO_CUBRID (CUBRID)
  • PDO_DBLIB(FreeTDS/ SQL da Microsoft Servidor/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 Oracle)
  • PDO_ODBC (ODBC v3 (IBM DB2, unixODBC e win32 ODBC))
  • PDO_PGSQL (PostgreSQL)
  • PDO_SQLITE (SQLite 3 e SQLite 2)
  • PDO_SQLSRV (Microsoft SQL Server)
  • DOP_4D (4D)
No entanto, nem todos eles estão no seu servidor. Você pode ver a lista de drivers disponíveis assim:
print_r(PDO::getAvailableDrivers());

Conexão

Os métodos para conectar-se a diferentes SGBDs podem diferir ligeiramente. Abaixo estão exemplos de conexão com os mais populares. Você notará que os três primeiros possuem sintaxe idêntica, diferentemente do SQLite.
try ( # MS SQL Server e Sybase via PDO_DBLIB $DBH = new PDO("mssql:host=$host;dbname=$dbname", $user, $pass); $DBH = new PDO("sybase:host=$host ;dbname=$dbname", $user, $pass); # MySQL via PDO_MYSQL $DBH = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass); # SQLite $DBH = new PDO("sqlite:my/database/path/database.db"); catch(PDOException $e) ( echo $e->getMessage(); )
Por favor, preste atenção ao bloco try/catch - sempre vale a pena agrupar todas as suas operações PDO nele e usar o mecanismo de exceção (mais sobre isso mais tarde).

$DBH significa “identificador de banco de dados” e será usado ao longo do artigo.

Você pode fechar qualquer conexão redefinindo sua variável como nula.
# fecha conexão $DBH = null;
Mais informações sobre o tópico de opções distintas de diferentes SGBDs e métodos de conexão a eles podem ser encontradas em php.net.

Exceções e DOP

O PDO pode lançar exceções em erros, então tudo deve estar em um bloco try/catch. Imediatamente após criar uma conexão, o PDO pode ser colocado em qualquer um dos três modos de erro:
$DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT); $DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING); $DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
Mas é importante notar que um erro ao tentar se conectar sempre gerará uma exceção.

PDO::ERRMODE_SILENT

Este é o modo padrão. Você provavelmente usará aproximadamente a mesma coisa para detectar erros nas extensões mysql e mysqli. Os próximos dois modos são mais adequados para programação DRY.

PDO::ERRMODE_WARNING

Este modo causará um aviso padrão e permitirá que o script continue a execução. Conveniente para depuração.

PDO::ERRMODE_EXCEPTION

Na maioria das situações, esse tipo de controle de execução de script é preferível. Ele lança uma exceção, permitindo que você lide com erros de maneira inteligente e oculte informações confidenciais. Como, por exemplo, aqui:
# conecte-se ao banco de dados try ( $DBH = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass); $DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION) ; # Droga! digitei DELECT em vez de SELECT! $DBH->prepare("DELECT name FROM people")->execute() ) catch(PDOException $e) ( echo "Houston, temos problemas."; "PDOErrors" .txt", $e->getMessage(), FILE_APPEND); )
Há um erro de sintaxe na expressão SQL que gerará uma exceção. Podemos registrar os detalhes do erro em um arquivo de log e sugerir ao usuário em linguagem humana que algo aconteceu.

Inserir e atualizar

A inserção de novos dados e a atualização dos dados existentes estão entre as operações de banco de dados mais comuns. No caso do DOP, esse processo geralmente consiste em duas etapas. (A próxima seção é sobre UPDATE e INSERT)


Um exemplo trivial de inserção de novos dados:
# STH significa "Identificador de instrução" $STH = $DBH->prepare("INSERT INTO folks (first_name) valores ("Cathy")"); $STH->executar();
Na verdade, você pode fazer a mesma coisa com um método exec(), mas o método de duas etapas oferece todos os benefícios das instruções preparadas. Eles ajudam a proteger contra injeções de SQL, por isso faz sentido usá-los mesmo para uma consulta única.

Declarações Preparadas

O uso de instruções preparadas fortalece a proteção contra injeções de SQL.

Uma instrução preparada é uma instrução SQL pré-compilada que pode ser executada repetidamente, enviando apenas diferentes conjuntos de dados ao servidor. Benefício adicionalé a impossibilidade de realizar injeção de SQL através dos dados utilizados nos placeholders.

Abaixo estão três exemplos de declarações preparadas.
# sem espaços reservados - a porta para injeções de SQL está aberta! $STH = $DBH->prepare("INSERT INTO pessoas (nome, endereço, cidade) valores ($nome, $endereço, $cidade)"); # espaços reservados sem nome $STH = $DBH->prepare("INSERT INTO pessoas (nome, endereço, cidade) valores (?, ?, ?)"); # espaços reservados nomeados $STH = $DBH->prepare("INSERT INTO pessoas (nome, endereço, cidade) valores (:nome, :endereço, :cidade)");
O primeiro exemplo está aqui apenas para comparação e deve ser evitado. A diferença entre espaços reservados sem nome e nomeados é como você passa dados para instruções preparadas.

Espaços reservados sem nome

# atribui variáveis ​​a cada placeholder, com índices de 1 a 3 $STH->bindParam(1, $name); $STH->bindParam(2, $addr); $STH->bindParam(3, $cidade); # insira uma linha $name = "Daniel" $addr = "1 Wicked Way"; $cidade = "Arlington Heights"; $STH->executar(); # insira outra linha, com dados diferentes $name = "Steve" $addr = "5 Circle Drive"; $cidade = "Schaumburg"; $STH->executar();
Existem duas etapas aqui. No primeiro, atribuímos variáveis ​​a todos os placeholders (linhas 2-4). Depois atribuímos valores a essas variáveis ​​e executamos a consulta. Para enviar um novo conjunto de dados, basta alterar os valores das variáveis ​​e executar a solicitação novamente.

Se a sua expressão SQL tiver muitos parâmetros, atribuir uma variável a cada um será muito inconveniente. Nesses casos, você pode armazenar os dados em um array e passá-los:
# o conjunto de dados que iremos inserir $data = array("Cathy", "9 Dark and Twisty Road", "Cardiff"); $STH = $DBH->prepare("INSERT INTO pessoas (nome, endereço, cidade) valores (?, ?, ?)"); $STH->executar($dados);
$data será inserido no lugar do primeiro espaço reservado, $data no lugar do segundo, etc. Mas tenha cuidado: se seus índices estiverem confusos, isso não funcionará.

Espaços reservados nomeados

# o primeiro argumento é o nome do espaço reservado # geralmente começa com dois pontos # embora funcione sem eles $STH->bindParam(":name", $name);
Aqui você também pode passar um array, mas ele deve ser associativo. As chaves devem ser, como você pode imaginar, os nomes dos espaços reservados.
# os dados que inserimos $data = array("name" => "Cathy", "addr" => "9 Dark and Twisty", "city" => "Cardiff"); $STH = $DBH->prepare("INSERT INTO pessoas (nome, endereço, cidade) valores (:nome, :endereço, :cidade)"); $STH->executar($dados);
Uma das conveniências de usar espaços reservados nomeados é a capacidade de inserir objetos diretamente no banco de dados se os nomes das propriedades corresponderem aos nomes dos parâmetros. Por exemplo, você pode inserir dados como este:
# classe para uma classe de objeto simples pessoa ( public $name; public $addr; public $city; function __construct($n,$a,$c) ( $this->name = $n; $this->addr = $ a ; $this->city = $c; ) # e assim por diante... ) $cathy = nova pessoa("Cathy","9 Dark and Twisty","Cardiff"); # e aqui está a parte interessante $STH = $DBH->prepare("INSERT INTO pessoal (nome, endereço, cidade) valores (:nome, :endereço, :cidade)"); $STH->executar((array)$cathy);
A conversão de um objeto em um array durante execute() faz com que as propriedades sejam tratadas como chaves do array.

Amostragem de dados



Os dados podem ser recuperados usando o método ->fetch(). Antes de chamá-lo, é aconselhável indicar explicitamente de que forma você os deseja. Existem várias opções:
  • DOP::FETCH_ASSOC: retorna uma matriz com nomes de colunas como chaves
  • PDO::FETCH_BOTH (padrão): retorna uma matriz com índices na forma de nomes de colunas e seus números de série
  • DOP::FETCH_BOUND: atribui valores de coluna às variáveis ​​​​correspondentes especificadas usando o método ->bindColumn()
  • DOP::FETCH_CLASS: atribui valores de coluna às propriedades correspondentes da classe especificada. Se não houver propriedade para alguma coluna, ela será criada
  • DOP::FETCH_INTO: atualiza uma instância existente da classe especificada
  • DOP::FETCH_LAZY: combina PDO::FETCH_BOTH e PDO::FETCH_OBJ
  • DOP::FETCH_NUM: retorna uma matriz com chaves como números de colunas
  • DOP::FETCH_OBJ: retorna um objeto anônimo com propriedades correspondentes aos nomes das colunas
Na prática, normalmente você precisará de três: FETCH_ASSOC, FETCH_CLASS e FETCH_OBJ. Para especificar o formato dos dados, use a seguinte sintaxe:
$STH->setFetchMode(PDO::FETCH_ASSOC);
Você também pode configurá-lo diretamente ao chamar o método ->fetch().

FETCH_ASSOC

Este formato cria matriz associativa com nomes de colunas como índices. Deve ser familiar para aqueles que usam as extensões mysql/mysqli.
# como esta é uma consulta normal sem espaços reservados, # você pode usar imediatamente o método query() $STH = $DBH->query("SELECT name, addr, city from folks"); # define 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() irá percorrer todo o resultado da consulta.

FETCH_OBJ

Este tipo de aquisição de dados cria uma instância da classe std para cada linha.
# cria uma consulta $STH = $DBH->query("SELECT nome, endereço, cidade das pessoas"); # selecione o modo de busca $STH->setFetchMode(PDO::FETCH_OBJ); # imprime o resultado while($row = $STH->fetch()) ( echo $row->name . "\n"; echo $row->addr . "\n"; echo $row->city . " \ n"; )

FETCH_CLASS

Ao usar fetch_class, os dados são gravados em instâncias da classe especificada. Neste caso, os valores são atribuídos às propriedades do objeto ANTES de chamar o construtor. Caso não existam propriedades com nomes correspondentes aos nomes das colunas, elas serão criadas automaticamente (com escopo público).

Se seus dados exigirem processamento obrigatório imediatamente após serem recebidos do banco de dados, eles poderão ser implementados no construtor da classe.

Por exemplo, vamos considerar uma situação em que você precisa ocultar parte do endereço residencial de uma pessoa.
class secret_person ( public $name; public $addr; public $city; public $other_data; function __construct($other = "") ( $this->addr = preg_replace("//", "x", $this-> endereço); $este->outros_dados = $outros;
Ao criar um objeto, todas as letras latinas minúsculas devem ser substituídas por x. Vamos verificar:
$STH = $DBH->query("SELECIONE nome, endereço, cidade das pessoas"); $STH->setFetchMode(PDO::FETCH_CLASS, "pessoa_secreta"); while($obj = $STH->fetch()) ( echo $obj->addr; )
Se o endereço no banco de dados for semelhante a '5 Rosebud', a saída será '5 Rxxxxxx'.

Claro, às vezes você desejará que o construtor seja chamado ANTES de atribuir valores. O DOP também permite isso.
$STH->setFetchMode(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, "secret_person");
Agora que você completou o exemplo anterior opção adicional(PDO::FETCH_PROPS_LATE), o endereço não será modificado, pois nada acontece após a escrita dos valores.

Finalmente, se necessário, você pode passar argumentos diretamente ao construtor ao criar o objeto:
$STH->setFetchMode(PDO::FETCH_CLASS, "secret_person", array("coisas"));
Você pode até passar argumentos diferentes para cada objeto:
$i = 0; while($rowObj = $STH->fetch(PDO::FETCH_CLASS, "secret_person", array($i))) ( // faça algo $i++; )

Outros métodos úteis

Embora este artigo não possa (e não tente) cobrir todos os aspectos do trabalho com o PDO (é um módulo enorme!), os seguintes recursos não podem ser deixados de lado.
$DBH->lastInsertId();
O método ->lastInsertId() retorna o id do último registro inserido. Vale ressaltar que ele é sempre chamado em um objeto de banco de dados (chamado $DBH neste artigo), e não em um objeto com expressão ($STH).
$DBH->exec("DELETE FROM pessoal WHERE 1"); $DBH->exec("SET fuso horário = "-8:00"");
O método ->exec() é usado para operações que não retornam nenhum dado além do número de registros afetados por elas.
$seguro = $DBH->quote($inseguro);
O método ->quote() coloca aspas em dados de string para que seja seguro usá-los em consultas. Útil se você não usar instruções preparadas.
$rows_affected = $STH->rowCount();
O método ->rowCount() retorna o número de registros que participaram da operação. Infelizmente, esta função não funcionou com consultas SELECT até o PHP 5.1.6. Caso não seja possível atualizar a versão do PHP, a quantidade de registros pode ser obtida assim:
$sql = "SELECT COUNT(*) FROM pessoal"; if ($STH = $DBH->query($sql)) ( # verifique o número de registros if ($STH->fetchColumn() > 0) ( # faça uma seleção completa aqui porque os dados foram encontrados! ) else ( # imprime uma mensagem informando que nenhum dado que satisfaça a solicitação foi encontrado))

Conclusão

Espero que este material ajude alguns de vocês a migrar das extensões mysql e mysqli.

metatags (5)

De vez em quando vejo dúvidas sobre como conectar-se a um banco de dados.
A maioria das respostas não é como eu faço ou simplesmente não consigo responder corretamente. De qualquer forma; Nunca pensei nisso porque a maneira como faço funciona para mim.

Mas aqui está um pensamento maluco; Talvez eu esteja fazendo tudo errado e, se estiver; Eu realmente gostaria de saber como conectar corretamente ao banco de dados Dados MySQL Com usando PHP e DOP e disponibilizá-lo.

Veja como eu faço isso:

Primeiro, aqui está o meu estrutura de arquivo (truncado) :

Public_html/ * index.php * inicializar/ -- load.initialize.php -- configure.php -- sessões.php

index.php
No topo eu require("initialize/load.initialize.php"); ,

carregar.initialize.php

# configurações do site require("configure.php"); # conectar ao banco de dados require("root/somewhere/connect.php"); // este arquivo é colocado fora de public_html para melhor segurança. # inclui classes foreach (glob("assets/classes/*.class.php") as $class_filename)( include($class_filename); ) # inclui funções foreach (glob("assets/functions/*.func.php") as $func_filename)( include($func_filename); ) # manipular sessões require("sessions.php");

Sei que existe uma forma melhor ou mais correta de incluir aulas, mas não lembro qual era. Ainda não tive tempo de investigar, mas acho que foi algo com autoload . algo assim...

configurar.php
Aqui estou basicamente substituindo alguns php.ini-properties e fazer algumas outras configurações globais para o site

conectar.php
Eu configurei a conexão com a classe para que outras classes possam expandir esse...

Classe connect_pdo ( protegido $dbh; função pública __construct() ( try ( $db_host = " "; // nome do host $db_name = " "; // nome do banco de dados $db_user = " "; // nome de usuário $user_pw = " "; // senha $con = new PDO("mysql:host=".$db_host."; dbname=".$db_name, $db_user, $user_pw); $con->exec("SET CHARACTER SET utf8"); // retorna todas as solicitações sql como UTF-8 ) catch (PDOException $err) ( echo "mensagem de erro inofensiva se a conexão falhar"; $err->getMessage() .
"; file_put_contents("PDOErrors.txt",$err, FILE_APPEND); // escreve alguns detalhes em um log de erros fora de public_html die(); // encerra a conexão ) ) public function dbh() ( return $this->dbh ; ) ) # coloque o manipulador do banco de dados em uma var para facilitar o acesso $con = new connect_pdo();

É aqui que eu realmente acredito que há espaço para melhorias massivas, já que recentemente comecei a aprender OOP e tenho usado PDO em vez de mysql.
Então eu apenas segui alguns tutoriais para iniciantes e experimentei coisas diferentes...

sessões.php
Além de lidar com sessões normais, também inicializo algumas classes da sessão assim:

If (!isset($_SESSION["sqlQuery"]))( session_start(); $_SESSION["sqlQuery"] = new sqlQuery(); )

Portanto, esta classe está disponível em todos os lugares. Esta pode não ser uma prática muito boa (?) ...
De qualquer forma, é isso que essa abordagem me permite fazer em qualquer lugar:

Echo $_SESSION["sqlQuery"]->getAreaName("condado",9); // saída: Aust-Agder (o nome do condado com esse id no banco de dados)

Dentro do meu aula sqlQuery que estende o meu Aula connect_pdo , tenho uma função pública getAreaName que trata da consulta em meu banco de dados.
Muito legal, eu acho.

Funciona perfeitamente
Então é basicamente assim que eu faço.
Além disso, sempre que preciso recuperar algo do meu banco de dados de uma classe, faço algo semelhante a isto:

$id = 123; $sql = "SELECIONE qualquer coisa DA MinhaTabela WHERE id = :id"; $qry = $con->preparar($sql); $qry -> bindParam(":id", $id, PDO::PARAM_INT); $qry -> executar(); $get = $qry->fetch(PDO::FETCH_ASSOC);

Porque estou inserindo a conexão em uma variável dentro connect_pdo.php, acabei de fazer referência e estou pronto para prosseguir. Funciona. Estou obtendo os resultados esperados...

Mas independentemente disso; Eu realmente apreciaria se vocês pudessem me dizer se eu sair daqui. Em vez disso, eu teria que mudar áreas que poderia ou deveria mudar para melhorias, etc.

Eu quero muito estudar...

Respostas

$dsn = "mysql:host=seu_host_name;dbname=seu_nome_db_aqui"; //define o nome do host e o nome do banco de dados $username = "you"; //defina o nome de usuário $pwd="sua_senha"; // senha try ( $db = new PDO($dsn, $username, $pwd); ) catch (PDOException $e) ( $error_message = $e->getMessage(); echo "isso é exibido porque um erro foi encontrado "; saída(); )

Recentemente, encontrei uma resposta/pergunta semelhante por conta própria. Isto é o que eu fiz, caso alguém esteja interessado:

args = func_get_args();

) função pública __call($método, $args) ( if (empty($this->db)) ( $Ref = new \ReflectionClass("\PDO"); $this->db = $Ref->newInstanceArgs($ this->args); ) return call_user_func_array(array($this->db, $method), $args) );

Para chamá-lo você só precisa alterar esta linha:

$DB = new \Library\PDO(/* argumentos normais */);

E um tipo de dica se você usá-lo (\Library\PDO$DB).

Isso é realmente semelhante à resposta aceita e à sua; no entanto, tem uma vantagem significativa. Considere este código:

Embora possa parecer um PDO normal (é modificado apenas por essa \Library\), na verdade ele não inicializa o objeto até que você chame o primeiro método, seja ele qual for. Isso o torna mais otimizado, pois criar um objeto PDO é um pouco caro. Esta é uma classe transparente, ou o que é chamado de Ghost, um formulário. Você pode tratar $DB como uma instância normal do PDO, distribuí-lo, fazer as mesmas operações, etc.

Eu sugeriria não usar $_SESSION para acessar sua conexão de banco de dados globalmente.

Você pode fazer uma de várias coisas (ok o pior para o melhor praticante):

  • Acessando $dbh usando $dbh global dentro de suas funções e classes
  • Use um registro singleton e acesse-o globalmente, por exemplo:

    $registry = MeuRegistro::getInstance(); $dbh = $registry->getDbh();

    Adicione o manipulador de banco de dados às classes necessárias:

    Classe MinhaClasse ( função pública __construct($dbh) ( /* ... */ ) )

Porém, é um pouco mais avançado e requer mais “fiação” sem moldura. Assim, se a injeção de dependência for muito complexa para você, use um registro singleton em vez de uma coleção de variáveis ​​globais.

Alvo

A meu ver, seu objetivo neste caso é duplo:

  • criar e manter conexão única/reutilizável para cada banco de dados
  • certifique-se de que a conexão esteja configurada corretamente

Solução

$provider = function() ( $instance = new PDO("mysql:......;charset=utf8", "nome de usuário", "senha"); $instance->setAttribute(PDO::ATTR_ERRMODE, PDO: :ERRMODE_EXCEPTION); $instance->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); $fábrica = nova EstruturaFactory($provedor);

Depois em outro arquivo ou abaixo no mesmo arquivo:

$algo = $fábrica->criar("Algo"); $foobar = $fábrica->criar("Foobar");

A fábrica em si deveria ser mais ou menos assim:

Classe StructureFactory ( protegido $provider = null; protegido $connection = null; função pública __construct(callable $provider) ( $this->provider = $provider; ) public function create($name) ( if ($this->connection = == null) ( $this->connection = call_user_func($this->provider); ) retornar novo $name($this->connection) )

Desta forma você pode ter uma estrutura centralizada que garante que uma conexão só seja criada quando necessária. Também tornaria o processo de teste de unidade e manutenção mais fácil do PHP e este código adicionaria barras invertidas aos seguintes caracteres: \x00 , \n , \r , \ , " , " e \x1a . Passe valores de entrada como parâmetros para minimizar a chance de injeção de SQL.

  • A forma mais avançada é usar o PDO.
  • Espero que isso ajude você.

    Considere a seguinte consulta:

    $iId = mysql_real_escape_string("1 OU 1=1"); $sSql = "SELECT * FROM tabela WHERE id = $iId";

    mysql_real_escape_string() não protegerá aqui. Se você usar aspas simples ("") em torno de suas variáveis ​​dentro de sua consulta, é isso que o protege disso. Abaixo está a solução abaixo:

    $iId = (int) mysql_real_escape_string("1 OU 1=1"); $sSql = "SELECT * FROM tabela WHERE id = $iId";

    Existem boas respostas para esta pergunta.

    Sugiro que usar DOP seja a melhor opção.

    Editar:

    mysql_real_escape_string() está obsoleto desde o PHP 5.5.0. Use mysqli ou DOP.

    Uma alternativa para mysql_real_escape_string() é

    String mysqli_real_escape_string (mysqli $link, string $escapestr)

    Exemplo:

    $iId = $mysqli->real_escape_string("1 OU 1=1"); $mysqli->query("SELECT * FROM tabela WHERE id = $iId");

    PDO (PHP Data Objects) é uma extensão para PHP que fornece uma interface simples para acessar vários bancos de dados. Para simplificar e resumir, usando PDO em PHP você se conecta a bancos de dados de vários tipos.

    Neste tutorial estaremos nos conectando a um banco de dados MySQL, pois é o banco de dados mais comum.

    Conectando-se ao banco de dados

    Você deve saber que o servidor de banco de dados possui um nome, e os usuários também podem se conectar a ele, ou seja, devem ser utilizados login e senha para se conectar.

    Um exemplo de como podemos nos conectar a um banco de dados:

    $db = new PDO("mysql:host=$host;dbname=$db", $user, $pass);

    Acho que se você está interessado em DOP, então seu conhecimento é suficiente e essa sintaxe não precisa ser explicada para você.

    Portanto temos um objeto de conexão para acessar o banco de dados.

    Tratamento de exceções

    Ao usar o PDO, aconselho você a detectar erros de conexão usando a construção try(...)catch(...). Aqui está um exemplo desse código:

    Try ( $db = new PDO("myql:host=$host;dbname=$dbname", $user, $pass); ) catch(PDOException $e) ( echo "Você tem um erro: ".$e-> getMessage()."
    "; echo "Online: ".$e->getLine(); )

    Existem opiniões diferentes em relação ao tratamento de erros, por exemplo, nem todos recomendam sempre usar a construção try(...)catch(...). O problema é que o PHP irá imprimir uma mensagem de erro na tela de qualquer maneira, então esse código é redundante. Embora se você quiser, por exemplo, reverter uma transação, essa construção será útil para você, mas mais sobre isso a seguir.

    Recuperando dados do banco de dados usando PDO, método de consulta

    Para selecionar no banco de dados, usamos o método de consulta, para o qual passamos uma string de consulta SQL.

    $db->query("SELECT * FROM usuários");

    Não esqueça que esta sintaxe funcionará para todos os tipos de bancos de dados.

    Além disso, não se esqueça da segurança dos dados transmitidos nas consultas SQL. PDO tem um análogo da função mysql_real_escape_string() - o método quote.

    $login = $db->quote($_POST["login"]); $sql = "SELECT * FROM usuários WHERE login = $login"; $resultado = $db->query($sql);

    Processamento de resultados, métodos FETCH e FETCHALL.

    Agora precisamos converter o resultado da variável $res em um array. Isso é feito usando o método FETCH, ao qual é passada uma constante.

    $res = $db->query($sql); $resultado = $res->FETCH(PDO::FETCH_NUM); // numerado $resultado = $res->FETCH(PDO::FETCH_ASSOC); // associativo $resultado = $res->FETCH(PDO::FETCH_BOTH); // associativo e numerado juntos $resultado = $res->FETCH(PDO::FETCH_OBJ); // tipo de objeto $result = $res->FETCH(PDO::FETCH_LAZY); //todos os tipos de uma vez

    Obviamente, a constante FETCH_LAZY torna o script mais lento, por isso é aconselhável não utilizá-la.

    O método FETCH retorna um registro do resultado. Se quiser recuperar todos os registros, você deve usar o método FETCHALL. Posteriormente, o resultado obtido com o uso de FETCHALL é processado em um loop foreach, conforme mostrado no exemplo:

    $query = $db->query("SELECT * FROM usuários"); $resultado = $query->FETCHALL(PDO::FETCH_ASSOC); foreach($resultado como $arry) ( echo $arry["nome"] . "
    "; }

    Constante FETCH_CLASS

    A constante FETCH_CLASS requer uma explicação especial, pois permite preencher uma classe pré-criada com dados do resultado de uma consulta ao banco de dados.

    Vejamos um exemplo usando a constante FETCH_CLASS:

    Classe Usuário ( public $login; public $pass; public function showInfo() ( echo "
    ". $this->pass."
    " . " : " . $this->login ."
    "; ) ) $resultado = $stmt->FETCHALL(PDO::FETCH_CLASS, "Usuário"); foreach($resultado como $usuário) ( $usuário->showInfo(); )

    Não se esqueça de uma regra importante - os nomes das propriedades na classe criada devem ser iguais aos nomes dos campos no banco de dados.

    Expressões Preparadas

    Expressões preparadas deverão ser usadas se sua consulta SQL contiver variáveis.

    Instruções preparadas PDO são o principal motivo para usar PHP Data Objects, pois são a única maneira segura de executar consultas SQL que contêm variáveis ​​criadas pelo usuário.

    As expressões preparadas no PDO são uma consulta SQL regular na qual uma variável é substituída por um marcador especial - um espaço reservado.

    Espaços reservados nomeados

    Primeiro, vamos dar uma olhada no espaço reservado nomeado, sua sintaxe é, por exemplo: :email.

    Vejamos um exemplo de consulta INSERT usando espaços reservados.

    $stmt = $db->prepare("INSERT INTO mensagens (email, mensagem) VALUES (:email, :message)");

    Neste exemplo, em vez de variáveis ​​na solicitação, usamos dois espaços reservados (:email, :message)").

    $stmt = $db->prepare("INSERT INTO mensagens (email, mensagem) VALUES (:email, :message)"); $stmt->bindParam(":email", $email); $stmt->bindParam(":mensagem", mensagem); $email = "E-mail nº 1"; $message = "Algum texto de mensagem"; $stmt->executar(); $email = "E-mail nº 2"; $message = "Algum texto de mensagem"; $stmt->executar();

    Observe que para preparar uma consulta SQL, nós a escrevemos no método prepare(). Então, para indicar qual espaço reservado vincular qual variável, usamos o método bindParam(). Para executar uma consulta SQL, chamamos o método execute().

    Então, mais uma vez a sequência de trabalho com expressões preparadas passo a passo:

    1. Atribuímos o resultado da execução do método prepare() à variável $stmt.
    2. Usando o método bindParam(), vinculamos variáveis ​​e espaços reservados.
    3. Atribuindo valores a variáveis.
    4. Usando o método execute(), executamos uma consulta ao banco de dados.

    Esta sintaxe pode ser escrita

    $stmt = prepare("SELECIONE nome FROM usuários WHERE email = :email"); $stmt->executar(array("email" => $email));

    Pode-se observar que um array deve ser passado para o método execute(), no qual as chaves devem corresponder aos nomes dos placeholders.

    A propósito, o método bindParam() tem um sinônimo bindValue() .

    Espaços reservados sem nome

    Agora vamos ver como trabalhar com espaços reservados sem nome.

    $stmt = prepare("SELECIONE nome FROM usuários WHERE email = ?") $stmt->execute(array($email));

    Nesta sintaxe, em vez de registrar o placeholder:nome, é indicada outra forma de sua gravação - um ponto de interrogação:? .

    Aqui os valores do array $email serão atribuídos aos espaços reservados um por um:? , mas em nosso exemplo há apenas um espaço reservado.

    Aqui está outro exemplo de uso de espaços reservados sem nome, usando o método bindParam():

    $stmt = $db->prepare("INSERT INTO artigos (título, texto) VALUES (?, ?)"); $stmt->bindParam(1, $email); $stmt->bindParam(2, $mensagem); $email = "E-mail nº 1"; $message = "Algum texto de mensagem"; $stmt->executar(); $email = "E-mail nº 2"; $message = "Algum texto de mensagem"; $stmt->executar();

    Inserindo em um banco de dados, método exec()

    Se quisermos escrever algo no banco de dados, também podemos usar o método PDO::exec().

    $sql = "INSERT INTO (login, senha) VALORES ($login, $senha)"; $resultado = $db->exec($sql);

    Se esta consulta for executada, a variável $result conterá o número de linhas afetadas na tabela.

    PDO::exec() executa consultas INSERT, mas não pode recuperar dados do banco de dados; isso é tratado pelo método PDO::query(). PDO::exec() apenas executa a consulta SQL e retorna o número de linhas envolvidas durante sua execução, não retorna o resultado da instrução SELECT.

    PDO trabalha com bancos de dados. Se você não consegue trabalhar com algum tipo de banco de dados, acesse php.ini e procure as linhas que começam com extension=php_pdo_(nome do banco de dados) e remova o comentário.

    PHP para iniciantes: funções de retorno de chamada, lição 34! https://www.youtube.com/watch?v=2NwLHXUoXcw https://www.youtube.com/watch?v=GMzI6jR_bE4 https://www.youtube.com/watch?v=gFJsBQIqpto Lição 9 de PHP Recursão https ://www.youtube.com/watch?v=gLAeJcKkd6c http://php.net/manual/ru/mysqli-result.fetch-array.php /* limpar os resultados da amostragem */ mysqli_free_result($result); /* fecha a conexão */ mysqli_close($link); http://myrusakov.ru/sql-osnovy.html Bom artigo: https://ru.wikipedia.org/wiki/Join_(SQL) OOP PHP. Ferramentas de extensão Capítulo "Ferramentas de extensão" do livro "PHP. Objetos, modelos e técnicas de programação" de Matt Zandstra. https://www.youtube.com/watch?v=6L2bxtTBCRo

    http://phpfaq.ru/pdo#intro - há um bom artigo aqui. Há informações importantes sobre exceções.

    É descrito de forma mais simples: http://myrusakov.ru/php-data-objects.html

    Vídeo: https://www.youtube.com/watch?v=ACUiBH5qV0U&list=PLr_acfJGVcirEijJXmKxj8QGkWkKb-Tj-&nohtml5=False


    3 de junho de 2018 Andrei Tchernyshov Tutorial de tradução 1737 0

    PDO é um acrônimo para PHP Data Objects: é uma extensão PHP para trabalhar com bancos de dados usando objetos. Uma de suas vantagens reside no fato de não estar diretamente vinculado a um banco de dados específico: sua interface permite acessar diversos ambientes diferentes, entre eles: MySQL, SQLite, PostgreSQL, Microsoft SQL Server.

    Este guia tem como objetivo fornecer uma visão geral completa do PDO e orientar o leitor passo a passo desde a criação e conexão a um banco de dados até a escolha dos métodos de recuperação mais adequados, demonstrando como criar consultas preparadas e descrevendo possíveis modos de erro.

    Criando um banco de dados e tabela de teste

    Primeiramente vamos criar um banco de dados:

    CRIAR BANCO DE DADOS solar_system; CONCEDER TODOS OS PRIVILÉGIOS NO solar_system.* PARA "testuser"@"localhost" IDENTIFICADO POR "testpassword";

    Concedemos ao usuário testuser todos os privilégios no banco de dados solar_system usando testpassword como senha. Agora vamos criar uma tabela e preenchê-la com algumas informações:

    USE sistema_solar; CREATE TABLE planetas (id TINYINT(1) UNSIGNED NOT NULL AUTO_INCREMENT, PRIMARY KEY(id), nome VARCHAR(10) NOT NULL, cor VARCHAR(10) NOT NULL); INSERIR EM planetas(nome, cor) VALUES("terra", "azul"), ("marte", "vermelho"), ("júpiter", "estranho");

    Descrição da conexão DSN (nome da fonte de dados)

    Agora que temos um banco de dados, precisamos definir o DSN. DSN significa Data Source Name e é um conjunto de informações necessárias para conectar-se a um banco de dados. DSN está na forma de uma string. A sintaxe difere dependendo do banco de dados ao qual você precisa se conectar, mas como estamos usando MySQL/MariaDB, precisamos definir o seguinte:

    • Tipo de driver utilizado para conexão;
    • O nome do computador host no qual o banco de dados está sendo executado;
    • Porta de conexão (opcional);
    • Nome do banco de dados;
    • Codificação (opcional).

    O formato da string no nosso caso será assim (vamos armazená-lo na variável $dsn):

    $dsn = "mysql:host=localhost;port=3306;dbname=solar_system;charset=utf8";

    Primeiro de tudo, definimos o prefixo do banco de dados ou prefixo do banco de dados. Neste caso, como estamos nos conectando a um banco de dados do tipo MySQL/MariaDB, estamos utilizando mysql. Em seguida, separamos o prefixo do restante da linha com dois pontos e cada seção subsequente foi separada do restante com ponto e vírgula.

    Nas próximas duas seções especificamos o nome do host no qual o banco de dados está sendo executado e a porta usada para conexão. Se nenhuma porta for especificada, a porta padrão será usada, neste caso 3306. Imediatamente após o nome do banco de dados ser charset .

    Criando um objeto DOP

    Agora que nosso DSN está pronto, começaremos a criar o objeto PDO. O construtor PDO usa a string DSN como o primeiro parâmetro, o nome de usuário do banco de dados como o segundo parâmetro, a senha como o terceiro e uma matriz de configurações opcional como o quarto.

    $opções = [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC ]; $pdo = novo PDO($dsn, "testuser", "testpassword", $options);

    As configurações também podem ser definidas após a criação do objeto, usando o método SetAttribute():

    $pdo->SetAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    Configurando o PDO para visualização de erros

    Vamos dar uma olhada em algumas das opções disponíveis para PDO::ATTR_ERRMODE. Estas opções são extremamente importantes porque determinam como o PDO se comporta quando ocorrem erros. Opções possíveis:

    PDO::ERRMODE_SILENT

    Opção padrão. O PDO simplesmente lançará um código de erro e uma mensagem de erro. Eles podem ser obtidos usando os métodos errorCode() e errorInfo().

    PDO::ERRMODE_EXCEPTION

    Esta opção é, na minha opinião, recomendada para uso. Com sua ajuda, além de emitir um código de erro e informações, o PDO lançará uma PDOException, que interromperá a execução do script, sendo também útil para transações PDO (veremos elas um pouco mais tarde).

    PDO::ERRMODE_WARNING

    Com esta opção, o PDO exibirá um código de erro e uma mensagem como PDO::ERRMODE_SILENT , mas também exibirá um aviso WARNING que não interrompe o script.

    Configurando o método de amostragem padrão

    Outra configuração importante é regulada usando a constante PDO::DEFAULT_FETCH_MODE. Permite configurar o funcionamento padrão do método fetch(), que será utilizado para obter os resultados da solicitação. Aqui estão as opções mais comumente usadas:

    DOP::FETCH_BOTH

    Ao utilizá-lo, os resultados obtidos serão indexados tanto por números inteiros quanto por nomes de colunas. Usá-lo em um método para obter uma linha de uma tabela de planetas nos dará os seguintes resultados:

    $stmt = $pdo->query("SELECT * FROM planetas"); $resultados = $stmt->fetch(PDO::FETCH_BOTH);

    Matriz (=> 1 => 1 => terra => terra => azul => azul)

    DOP::FETCH_ASSOC

    Com esta constante, os resultados serão escritos em um array associativo em que cada chave será um nome de coluna, e cada valor representará um valor específico na linha:

    $stmt = $pdo->query("SELECT * FROM planetas"); $resultados = $stmt->fetch(PDO::FETCH_ASSOC);

    Matriz ( => 1 => terra => azul)

    DOP::FETCH_NUM

    Usando a constante PDO::FETCH_NUM obtemos um array indexado em 0:

    Matriz ( => 1 => terra => azul)

    DOP::FETCH_COLUMN

    Essa constante é útil para obter apenas os valores de uma coluna, e o método retornará todos os resultados dentro de um array unidimensional simples. Por exemplo, aqui está uma solicitação:

    Matriz (=> terra => marte => júpiter)

    DOP::FETCH_KEY_PAIR

    Esta constante é útil quando você precisa obter valores de duas colunas. O método fetchAll() retornará os resultados como um array associativo. Nesta matriz, os dados da primeira coluna serão especificados na forma de chaves e da segunda - como valores:

    $stmt = $pdo->query("SELECIONE nome, cor FROM planetas"); $resultado = $stmt->fetchAll(PDO::FETCH_KEY_PAIR);

    Essa constante é útil para obter apenas os valores de uma coluna, e o método retornará todos os resultados dentro de um array unidimensional simples. Por exemplo, aqui está uma solicitação:

    Matriz (=> azul => vermelho => estranho)

    DOP::FETCH_OBJECT

    Ao utilizar a constante PDO::FETCH_OBJECT, um objeto anônimo será criado para cada linha buscada. Suas propriedades (públicas) terão o mesmo nome das colunas e os resultados da consulta serão usados ​​como valores. Usar este método para a mesma consulta acima produzirá o seguinte resultado:

    $resultados = $stmt->fetch(PDO::FETCH_OBJ);

    Objeto stdClass (=> terra => azul)

    DOP::FETCH_CLASS

    Assim como a constante anterior, esta atribuirá os valores das colunas às propriedades do objeto, mas neste caso devemos configurar uma classe existente que será utilizada para criar o objeto. Para demonstração, primeiro criaremos uma classe:

    Classe Planeta ( private $name; private $color; public function setName($planet_name) ( $this->name = $planet_name; ) public function setColor($planet_color) ( $this->color = $planet_color; ) public function getName () ( return $this->nome; ) função pública getColor() ( return $this->color; ) )

    Não liguem para a simplicidade do código, vamos olhar melhor para a classe Planet que criamos: ela possui private em suas propriedades e a classe não possui construtor. Agora vamos tentar obter resultados.

    Ao usar fetch() com PDO::FETCH_CLASS você deve usar o método setFetchMode() no objeto antes de tentar buscar os dados, por exemplo:

    $stmt = $pdo->query("SELECIONE nome, cor FROM planetas"); $stmt->setFetchMode(PDO::FETCH_CLASS, "Planeta");

    Especificamos a constante PDO::FETCH_CLASS como o primeiro argumento do método setFetchMode() e o nome da classe usada para criar o objeto (no nosso caso “Planeta”) como o segundo argumento. Agora vamos executar o código:

    $planeta = $stmt->fetch();

    Isso deve resultar em um objeto Planet:

    Var_dump($planeta);

    Objeto Planeta (=> terra => azul)

    A classe “Planet” não possuía nenhum construtor específico, portanto não houve problemas na atribuição de características; mas e se a classe tiver um construtor no qual as características são definidas e alteradas? Como os valores são atribuídos antes da execução do construtor, eles serão substituídos.

    O PDO ajuda a fornecer a constante FETCH_PROPS_LATE: quando usada, os valores serão atribuídos após a criação do objeto. Exemplo:

    Classe Planeta ( private $name; private $color; public function __construct($name = lua, $color = cinza) ( $this->name = $name; $this->color = $color; ) public function setName($ planet_name) ( $this->name = $planet_name; ) função pública setColor($planet_color) ( $this->color = $planet_color; ) função pública getName() ( return $this->name; ) função pública getColor() ( return $this->color; ) )

    Modificamos nossa classe Planet para criar um construtor que receberá dois argumentos: name name e color . Esses argumentos têm os valores base moon e grey, o que significa que se nenhum outro valor for fornecido, estes serão definidos.

    Neste caso, se não utilizarmos FETCH_PROPS_LATE, então não importa quais valores sejam obtidos do banco de dados, todas as características permanecerão básicas, pois durante o processo de criação do objeto, elas serão sobrescritas. Para verificar isso, vamos executar a seguinte consulta:

    $stmt = $pdo->query("SELECT nome, cor FROM solar_system WHERE nome = "earth""); $stmt->setFetchMode(PDO::FETCH_CLASS, "Planeta"); $planeta = $stmt->fetch();

    Agora vamos dar uma olhada no objeto Planeta e verificar quais valores correspondem às suas características:

    Var_dump($planeta);

    objeto(Planeta)#2 (2) ( ["nome":"Planeta":privado]=> string(4) "lua" ["cor":"Planeta":privado]=> string(4) "cinza" )

    Como esperado, os valores recuperados do banco de dados foram substituídos pelos valores padrão. Agora, demonstraremos a solução dos problemas utilizando a constante FETCH_PROPS_LATE (e a mesma consulta da anterior):

    $stmt->setFetchMode(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE, "Planeta"); $planeta = $stmt->fetch(); var_dump($planeta);

    Classe Planeta ( private $name; private $color; public function __construct($name, $color) ( $this->name = $name; $this->color = $color; ) [...] )

    Os argumentos do construtor agora são obrigatórios, então executamos:

    $stmt->setFetchMode(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE, "Planeta", ["lua", "cinza"]);

    Neste caso, os parâmetros que especificamos servem apenas como os valores básicos necessários para que o objeto funcione sem erros: serão sobrescritos pelos valores do banco de dados.

    Recuperando Vários Objetos

    É claro que é possível obter vários resultados de uma só vez na forma de objetos, usando o método fetch() ou através de um loop:

    While ($planet = $stmt->fetch()) ( // Algo a ver com os resultados )

    Ou obtendo todos os resultados de uma vez. Neste caso, como mencionado anteriormente, ao usar o método fetchAll() você precisará especificar o modo de busca não antes de executar o método, mas no momento em que ele é executado:

    $stmt->fetchAll(PDO::FETCH_CLASS|PDO_FETCH_PROPS_LATE, "Planeta", ["lua", "cinza"]);

    DOP::FETCH_INTO

    Ao utilizar esta constante, o PDO não cria um novo objeto, mas sim atualiza as características de um já existente, mas apenas se for público ou se o método __set() for utilizado dentro do objeto.

    Preparado contra solicitações diretas

    O PDO possui duas formas de trabalhar com consultas: utilizando as diretas e a mais confiável - as preparadas.

    Solicitações diretas

    Existem dois métodos principais para usar consultas diretas: query() e exec() . O primeiro cria um objeto PDOStatemnt, que pode ser acessado através dos métodos fetch() ou fetchAll(): caso você os utilize em casos onde a tabela não muda, como SELECT .

    O segundo método, por sua vez, retorna o número da linha que foi modificada pela consulta: utilizamos em casos que substituem linhas, como INSERT, DELETE ou UPDATE. Consultas diretas devem ser utilizadas apenas nos casos em que não existam variáveis ​​nas consultas e não haja dúvidas sobre a segurança do método.

    Consultas preparadas

    O PDO também suporta consultas preparadas em duas etapas: são úteis quando as consultas possuem variáveis ​​e são mais seguras em geral, pois o método prepare() fará todo o trabalho necessário para nós. Vamos dar uma olhada em como as variáveis ​​são usadas. Imagine que queremos inserir as características de um planeta na tabela Planetas. Primeiro, vamos preparar uma solicitação:

    $stmt = $pdo->prepare("INSERT INTO planetas(nome, cor) VALUES(?, ?)");

    Conforme dito anteriormente, utilizamos o método prepare() que toma a consulta SQL como argumento, utilizando valores temporários para as variáveis. Os valores temporários podem ser de dois tipos: posicionais e nominais.

    Posicional

    Usando? valores temporários posicionais, o código é mais conciso, mas devemos especificar os dados a serem inseridos na mesma ordem que os nomes das colunas no array fornecido como argumento para o método execute():

    $stmt->executar([$planeta->nome, $planeta->cor]);

    Personalizado

    Ao usar espaços reservados nomeados, não precisamos de uma ordem específica, mas como resultado obtemos mais código. Quando executamos o método execute(), devemos fornecer os dados na forma de um array associativo, onde cada chave é o nome do valor temporário utilizado, e o valor associado é o que é transportado para a consulta. Por exemplo, a solicitação anterior seria:

    $stmt = $pdo->prepare("INSERT INTO planetas(nome, cor) VALUES(:nome, :cor)"); $stmt->execute(["nome" => $planeta->nome, "cor" => $planeta->cor]);

    Os métodos prepare() e execute() podem ser usados ​​para consultas que modificam ou simplesmente recuperam informações do banco de dados. No primeiro caso, utilizamos os métodos de busca listados acima para obter informações e, no segundo, utilizamos o método rowCount().

    Métodos bindValue() e bindParam()

    Os métodos bindValue() e bindParam() também podem ser utilizados para fornecer os valores que serão inseridos na requisição. A primeira vincula o valor de uma determinada variável a um valor posicional ou temporário nomeado usado na preparação da solicitação. Tomando o caso anterior como exemplo, faremos:

    $stmt->bindValue("nome", $planeta->nome, PDO::PARAM_STR);

    Vinculamos o valor de $planet->name a um valor temporário:name . Observe que usando os métodos bindValue() e bindParam() também podemos especificar o tipo da variável como o terceiro argumento usando uma constante PDO adequada, neste caso PDO::PARAM_STR .

    Ao usar bindParam(), podemos vincular a variável a um valor temporário adequado usado na preparação da consulta. Observe que neste caso, a variável está vinculada à referência e seu valor só será alterado para temporário quando o método execute() for executado. A sintaxe é a mesma da última vez:

    $stmt->bindParam("nome", $planeta->nome, PDO::PARAM_STR)

    Vinculamos a variável, não seu valor, $planet->name a:name ! Como dito acima, a substituição só acontecerá quando o método execute() for executado, portanto o valor temporário será substituído pelo valor da variável naquele momento.

    Transações DOP

    As transações permitem manter a consistência ao executar várias consultas. Todas as consultas são executadas em lotes e aplicadas ao banco de dados somente se todas forem bem-sucedidas. As transações não funcionarão com todos os bancos de dados e nem com todas as construções SQL, pois algumas delas causam problemas.

    Como exemplo extremo e estranho, imagine que o usuário tivesse que selecionar uma lista de planetas e toda vez que fizesse uma nova seleção, teria que deletar o anterior do banco de dados antes de inserir um novo. E se a exclusão acontecer, mas a inserção não? Teremos um usuário sem planetas! Basicamente, as transações são aplicadas assim:

    $pdo->beginTransaction(); try ( $stmt1 = $pdo->exec("DELETE FROM planetas"); $stmt2 = $pdo->prepare("INSERT INTO planetas(nome, cor) VALUES (?, ?)"); foreach ($planetas como $planet) ( $stmt2->execute([$planet->getName(), $planet->getColor()]); ) $pdo->commit() ) catch (PDOException $e) ( $pdo-> rollBack ();

    Primeiro de tudo, o método BeginTransaction() no objeto PDO desativa o autocommit da solicitação e, em seguida, as solicitações são iniciadas na ordem necessária. Neste ponto, a menos que ocorra uma PDOException, as solicitações são passadas automaticamente através do método commit(); caso contrário, as transações são canceladas através do método rollBack() e o autocommit é restaurado.

    Dessa forma, com múltiplas solicitações, sempre haverá consistência. Isso é bastante óbvio, mas as transações PDO só podem ser usadas por PDO::ATTR_ERRMODE definido como PDO::ERRMODE_EXCEPTION .

    Conexão de banco de dadosé definido quando uma instância da classe PDO é criada. Não importa qual driver você escolha usar; Você sempre precisará usar a classe PDO. Seu construtor aceita parâmetros para especificar a origem do banco de dados (conhecido como DSN) e parâmetros opcionais para nome de usuário e senha.

    Conexão com MySQL:

    $dbh = new PDO("mysql:host=localhost;dbname=test", $user, $pass);

    Caso ocorra algum erro de conexão, será lançada uma exceção: um objeto da classe PDOException. Você pode capturá-lo se quiser lidar com esta situação ou pode deixá-lo para o manipulador de exceção global, que é definido via set_exception_handler().

    Tratamento de erros de conexão:

    try ( $dbh = new PDO("mysql:host=localhost;dbname=test", $user, $pass); foreach($dbh->query('SELECT * from FOO') as $row) ( print_r($ row); ) $dbh = null ) catch (PDOException $e) ( die("Erro! É isso. Aqui estamos... ".$e->getMessage()); )

    Atenção: Se você não capturar a exceção lançada pelo construtor PDO, a ação padrão tomada pelo mecanismo zend é parar o script e mostrar um traceback. Essa porcaria irá revelar todos os seus detalhes íntimos de comunicação com o banco de dados. Aquilo é mostrará detalhes detalhados da conexão do banco de dados, incluindo nome de usuário e senha! Depende de você capturar essa exceção, seja explicitamente (por meio de uma instrução tente pegar) ou implicitamente via set_exception_handler().

    Depois que uma conexão com o banco de dados for bem-sucedida, ela permanecerá ativa durante toda a vida útil da instância do objeto PDO. Para fechar uma conexão, você deve destruir o objeto, garantindo que todas as referências restantes a ele sejam removidas – isso pode ser feito atribuindo o valor NULL à variável que contém o objeto. Se você não fizer isso explicitamente, o PHP fechará automaticamente a conexão quando o script for encerrado.

    Fechando uma conexão:

    $dbh = new PDO("mysql:host=localhost;dbname=test", $user, $pass);

    // Estamos fazendo algo aqui: ... // E agora, atenção: fim da conexão!

    $dbh = nulo;

    Muitas aplicações web se beneficiam da criação de conexões persistentes com servidores de banco de dados. As conexões persistentes não são fechadas quando o script é encerrado, mas são armazenadas em cache e reutilizadas quando outro script solicita conexões usando as mesmas credenciais de conexão. Um cache de conexão persistente evita a sobrecarga de estabelecer uma nova conexão sempre que um script precisa se comunicar com o banco de dados, resultando na execução mais rápida de aplicativos da Web.

    Configurando uma conexão permanente:$dbh = new PDO("mysql:host=localhost;dbname=test", $user, $pass, array(PDO::ATTR_PERSISTENT => true)); Tenha em mente: Se quiser usar uma conexão persistente, você deve definir DOP::ATTR_PERSISTENT na matriz de opções do driver, que é passada para o construtor da classe PDO. Ao definir este atributo via PDO::setAttribute() após a instanciação do objeto, o driver não utilizará links persistentes. E também, neste caso, você não poderá estender a classe PDOStatement para algumas de suas necessidades, ou seja,

    Instruções