Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Boa tarde colegas,
Estou migrando meus sistemas para PDO (Antes utilizava mysql_connect e seus familiares), e tenho algumas dúvidas referente ao mesmo.
Percebi que ele já previne o SQL Injection, não necessitando utilizar addslashes, strip_tags, etc.
Gostaria de saber se ele só faz o tratamento de SQL Injection quando utilizado junto ao ->bindParam ou se ele faz também quando os dados a serem manipulados no banco são passados como array para o método ->execute(array("DADOS", "DADOS", "DADOS")).
Outra questão que acho relevante levantar aqui no fórum, é sobre o uso do bindParam. Com ele é possível escolher o tipo de dados vai ser usado no banco, utilizando PDO::PARAM_INT, PDO::PARAM_STRING, etc. E quando o dado for um float ou do tipo data? Seria passado como string mesmo? Ou algum outro tipo de dado que não venha à cabeça agora...
Agradeço a colaboração de todos!!!
O que trata a questão do sql injection não é o PDO e sim o prepared stament, que você pode usar até com o mysqli_*
Vamos lá
Não use a PDO se o projeto não sofrerá alteração de banco da dados. Se o projeto for MySQL pra sempre, tem a MySQLi
Se houver a possibilidade de mudança, tudo bem, use a PDO. Mas atente que ela não vai abstrair a parte léxica de suas queries, isto é, se:
SELECT * FROM tabela
Funciona no MySQL, talvez possa não funcionar no Oracle (só um EXEMPLO). Ou, lá na frente, inventam o banco Yoda, cuja sintaxe é do jeitinho que ele fala:
FROM tabela * SELECT
Seu sistema vai pro espaço (Mestre Yoda... Espaço... entendeu? :lol: )
Sobre a SQL Injection, tanto faz, seja usando PDOStatement::bindValue() ou apenas definindo os placeholders (nomeados ou por interrogações) e informando um array com as substituições para PDOStatement::execute(), em ambos os casos o tratamento ocorrerá.
Mas... Usar PDOStatement::bindValue() tem um inconveniente, um potencial problema e um pior desempenho.
O inconveniente é que dos vários códigos que já vi que usa deste método, um simples INSERT caba gerando um código enorme.
O potencial problema está no argumento $data_type (terceiro). Se acidentalmente você informar a constante PDO incorreta ou menos apropriada, a PDO vai tratar de acordo com a sua vontade.
Se você informa no segundo argumento um número inteiro, mas informa PDO::PARAM_STR, o dado passado será tratado como string (no caso uma string numérica) e não como o inteiro que o dado é.
Nesse exemplo em particular, tranquilo. A coisa pega mesmo é quando ou você não tem certeza do tipo ou precisa usar um tipo pouco comum, como os três últimos PDO::PARAM_* descritos no Manual.
Por fim, a performance prejudicada é quanto ao fato de, usando PDOStatement::bindValue() você está invocando o dito método para cada um dos parâmetros que você precisar.
Você fazendo via PDOStatement::execute(), esse procedimento é feito nos bastidores, na linguagem que a PDO foi criada que é MUITO mais rápida que o próprio PHP.
>
Vamos lá
Não use a PDO se o projeto não sofrerá alteração de banco da dados. Se o projeto for MySQL pra sempre, tem a MySQLi
Se houver a possibilidade de mudança, tudo bem, use a PDO. Mas atente que ela não vai abstrair a parte léxica de suas queries, isto é, se:
SELECT * FROM tabela
Funciona no MySQL, talvez possa não funcionar no Oracle (só um EXEMPLO). Ou, lá na frente, inventam o banco Yoda, cuja sintaxe é do jeitinho que ele fala:
FROM tabela * SELECT
Seu sistema vai pro espaço (Mestre Yoda... Espaço... entendeu? :lol: )
Sobre a SQL Injection, tanto faz, seja usando PDOStatement::bindValue() ou apenas definindo os placeholders (nomeados ou por interrogações) e informando um array com as substituições para PDOStatement::execute(), em ambos os casos o tratamento ocorrerá.
Mas... Usar PDOStatement::bindValue() tem um inconveniente, um potencial problema e um pior desempenho.
O inconveniente é que dos vários códigos que já vi que usa deste método, um simples INSERT caba gerando um código enorme.
O potencial problema está no argumento $data_type (terceiro). Se acidentalmente você informar a constante PDO incorreta ou menos apropriada, a PDO vai tratar de acordo com a sua vontade.
Se você informa no segundo argumento um número inteiro, mas informa PDO::PARAM_STR, o dado passado será tratado como string (no caso uma string numérica) e não como o inteiro que o dado é.
Nesse exemplo em particular, tranquilo. A coisa pega mesmo é quando ou você não tem certeza do tipo ou precisa usar um tipo pouco comum, como os três últimos PDO::PARAM_* descritos no Manual.
Por fim, a performance prejudicada é quanto ao fato de, usando PDOStatement::bindValue() você está invocando o dito método para cada um dos parâmetros que você precisar.
Você fazendo via PDOStatement::execute(), esse procedimento é feito nos bastidores, na linguagem que a PDO foi criada que é MUITO mais rápida que o próprio PHP.
Obrigado pelas informações, mas em relação do banco de dados ser sempre o mesmo, a vantagem de usar o PDO mesmo assim é não precisar decorar sintaxes para cada banco especificamente, por exemplo mysql_connect e mysqli_connect certo? Em questão de performance acredito que claro, usar diretamente os comandos do banco de dados específico da aplicação, no caso, o mysqli, deverá ser mais rápido pois não necessita verificar qual o banco de dados que estou invocando para a aplicação, igual o PDO faz.
Outra questão que achei interessante e é justamente o que venho estudando e querendo aprender sempre mais, é a questão de mesmo que a aplicação mude, pode acontecer das querys SQL precisarem mudar tbm, devido a sintaxe específica para cada SGBD. Sendo assim, acredito que então haja um padrão de projeto para abstrair isso, e então, quando necessário mudar a sintaxa, muda-se apenas a classe que constrói a SQL e então todo o resto da aplicação irá continuar funcionando certo?
Qual design pattern é que trata isso? Como funcionaria especificamente, para se trabalhar assim e com o PDO?
Se você deseja ter a flexibilidade de mudar de SGBD sem precisar ficar alterados as consultas manualmente deve implementer um ORM, ele vai abstrair isto para você.
Na verdade Cabral, a PDO vai abstrair a Interface, isto é, seja qual for o SGBD que você usar, você terá 100% de certeza que a forma de uso será a mesma:
$dbh = new PDO( /* ... */ );
$stmt = $dbh -> prepare( /* ... */ );
$stmt -> execute;
$data = $stmt -> fetchAll();
Mas você viu o exemplo do Mestre Yoda? A PDO não vai fazer isso pra você.
E é aí que entra a dica do ESerra. UMA das coisas de um ORM seria um interpretador léxico onde através de uma Interface cada adaptador geraria o SQL na pseudo-linguagem que necessita.
No meu caso, por exemplo, tenho uma Interface Query que define insert(), delete(), update(), delete(), where(), order() e etc.
Cada adaptador de banco que eu tenho define uma instância de uma classe que implemente essa Interface.
Assim, meu adaptador MySQL tem, no método select(), por exemplo:
public function select( $columns, $tables ) {
return sprintf( 'SELECT #%s FROM %s', rtrim( $columns, ', ' ), rtrim( $tables, ', ' ) );
}
Já para o banco de dados do Yoda, esse método seria:
public function select( $columns, $tables ) {
return sprintf( 'FROM %s %s SELECT', rtrim( $tables, ', ' ), rtrim( $columns, ', ' ) );
}
Mas o programador que usar fará sempre:
$data = $dbh -> select() -> fetchAll();
O método select() a partir do adaptador, usará o select() da Interface eu eu terei um SQL renderizado uniformemente, independente do SGBD usado.
Nota: Por meu método select() estar argumentos, eu assumo o * (asterisco - tudo)>
Se você deseja ter a flexibilidade de mudar de SGBD sem precisar ficar alterados as consultas manualmente deve implementer um ORM, ele vai abstrair isto para você.
ORM? Seria muito complexo adotar isto? Como que ele funciona específicamente?
>
Na verdade Cabral, a PDO vai abstrair a Interface, isto é, seja qual for o SGBD que você usar, você terá 100% de certeza que a forma de uso será a mesma:
$dbh = new PDO( /* ... */ );
$stmt = $dbh -> prepare( /* ... */ );
$stmt -> execute;
$data = $stmt -> fetchAll();
Mas você viu o exemplo do Mestre Yoda? A PDO não vai fazer isso pra você.
E é aí que entra a dica do ESerra. UMA das coisas de um ORM seria um interpretador léxico onde através de uma Interface cada adaptador geraria o SQL na pseudo-linguagem que necessita.
No meu caso, por exemplo, tenho uma Interface Query que define insert(), delete(), update(), delete(), where(), order() e etc.
Cada adaptador de banco que eu tenho define uma instância de uma classe que implemente essa Interface.
Assim, meu adaptador MySQL tem, no método select(), por exemplo:
public function select( $columns, $tables ) {
return sprintf( 'SELECT #%s FROM %s', rtrim( $columns, ', ' ), rtrim( $tables, ', ' ) );
}
Já para o banco de dados do Yoda, esse método seria:
public function select( $columns, $tables ) {
return sprintf( 'FROM %s %s SELECT', rtrim( $tables, ', ' ), rtrim( $columns, ', ' ) );
}
Mas o programador que usar fará sempre:
$data = $dbh -> select() -> fetchAll();
O método select() a partir do adaptador, usará o select() da Interface eu eu terei um SQL renderizado uniformemente, independente do SGBD usado.
Nota: Por meu método select() estar argumentos, eu assumo o * (asterisco - tudo)
Achei interessante cara essa sua abordagem de Interface, aí no caso eu substituiria somente nestes métodos a sintaxe da SQL para cada banco e a aplicação funcionaria sem a necessidade de alterar o resto, exato?
ORM? Seria muito complexo adotar isto? Como que ele funciona específicamente?
Desenvolver do zero pode ser complicado. São MUITOS Padrões de Projeto referentes à Banco de Dados.
Aos pouquinhos estou criando o meu, mas se quiser usar algo pronto, há o Doctrine ORM
>
Achei interessante cara essa sua abordagem de Interface, aí no caso eu substituiria somente nestes métodos a sintaxe da SQL para cada banco e a aplicação funcionaria sem a necessidade de alterar o resto, exato?
Exato
>
Desenvolver do zero pode ser complicado. São MUITOS Padrões de Projeto referentes à Banco de Dados.
Aos pouquinhos estou criando o meu, mas se quiser usar algo pronto, há o Doctrine ORM
Exato
Em relação ao ORM, não entendi muito bem sua utilidade real, já que poderia criar um model da tabela do meu banco de dados não?
Tem exemplos mais específicos do ORM? E em caso dos relacionamentos das tabelas, em que ele ajudaria? E se isso fosse feito com classes em PHP puro, sem a utilização do ORM?
bom manim PDO e bem seguro msm .. sempre bom usa um mysql_real_escape_string() da vida pra garanti né.
http://php.net/manual/en/book.pdo.php
foi uma boa pergunta ^^
essa eu num sei.. Mais eu acho que ele trata sim..
quanto ao PDO::PARAM_STRING --
http://php.net/manual/en/pdo.constants.php