Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Rogério Santana

Criar função em PDO

Recommended Posts

Salve!

 

Estou com um problema em criar uma função em PDO para inserir dados no banco por array

 

Ex.:

 

$a['nome']  = $_POST['nome'];
$a['email'] = $_POST['email'];
$a['data']  = $_POST['data'];

create('tabela',$a);

e o PDO com a função create

 

 

function create($tabela, array $datas){
 $fields = implode(", ",array_keys($datas));
 $values = "'".implode("', '",array_values($datas))."'";
 $qrCreate = "INSERT INTO {$tabela} ($fields) VALUES ($values)";
 try {
   $query = $bd->prepare($qrCreate); // linha 23
   $query->bindValue($qrCreate,PDO::PARAM_STR);
   $query->bindValue($values,PDO::PARAM_STR);
   $query->execute;
 } catch (PDOException $e) {
     echo 'Houve algum erro na insercao dos dados: '. $e->getMessage();
 }

Ele retorna esse erro:

 

Fatal error: Call to a member function prepare() on a non-object in E:\wamp\www\pdo-oo\classes\conexao.php on line 23

 

Ajudem-me por favor!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Isso ocorre pois a variável $bd não está visível de dentro da função.

Esse é um "problema" que a orientação à objetos soluciona.

 

Você pode enviar a variável $bd através de atributo da função ou torná-la global, mas nenhuma das formas é ideal. São somente soluções práticas.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Isso ocorre pois a variável $bd não está visível de dentro da função.

Esse é um "problema" que a orientação à objetos soluciona.

 

Você pode enviar a variável $bd através de atributo da função ou torná-la global, mas nenhuma das formas é ideal. São somente soluções práticas.

 

 

Pelo que li, ela serviria para retornar os valores da conexao com o banco

 

 

 

<?php
define(HOST,'localhost');
define(DB_NAME,'pdooo');
define(USER,'root');
define(PASS,'');

$dsn = 'mysql:host='.HOST.';dbname='.DB_NAME;

try {
        $bd = new PDO($dsn,USER,PASS); 
        $bd->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
        echo htmlentities('Houve algum erro com a conexão com o banco de dados: '. $e->getMessage());
}

function create($tabela, array $datas){
 $fields = implode(", ",array_keys($datas));
 $values = "'".implode("', '",array_values($datas))."'";
 $qrCreate = "INSERT INTO {$tabela} ($fields) VALUES ($values)";
 try {
        $query = $bd->prepare($values);
        $query->bindValue($qrCreate,PDO::PARAM_STR);
        $query->bindValue($values,PDO::PARAM_STR);
        $query->execute;
} catch (PDOException $e) {
        echo 'Houve algum erro na insercao dos dados: '. $e->getMessage();
}
}
?>

Está tudo na mesma página

Compartilhar este post


Link para o post
Compartilhar em outros sites

Como o Matheus Tavares disse, o problema ocorre porque a variável $db não está declarada dentro da função.

 

Variáveis tem escopo: se uma variável é declarada fora de uma função, esta é uma variável global. Se declarada dentro de uma função é uma variável local. Uma variável local só é acessível dentro da função onde ela foi declarada, enquanto variáveis globais só podem ser acessadas dentro deu uma função se você importá-las usando a palavra-chave global.

 

Então isso deve resolver seu problema:

function create($tabela, array $datas) {
    global $db;

 

Ou então você pode passar $db como parâmetro para a função:

 

function create($db, $tabela, array $datas) {

 

Leia mais: Escopo de Variáveis

Compartilhar este post


Link para o post
Compartilhar em outros sites

 

Como o Matheus Tavares disse, o problema ocorre porque a variável $db não está declarada dentro da função.

 

Variáveis tem escopo: se uma variável é declarada fora de uma função, esta é uma variável global. Se declarada dentro de uma função é uma variável local. Uma variável local só é acessível dentro da função onde ela foi declarada, enquanto variáveis globais só podem ser acessadas dentro deu uma função se você importá-las usando a palavra-chave global.

 

Então isso deve resolver seu problema:

function create($tabela, array $datas) {
    global $db;

Ou então você pode passar $db como parâmetro para a função:

function create($db, $tabela, array $datas) {

Leia mais: Escopo de Variáveis

 

Usando a 1ª opção passa o erro, mas não cadastra no banco.

 

Sendo que o html printa todas as mensagens, só não cadastra, nem apresenta mais erro. O nome da tabela está certa.

<form action="" method="post">

<?php
  require ('classes/conexao.php');
     global $bd; // declarei aqui (em um local de cada vez)
  if(isset($_POST['sub'])){
    global $bd; // declarei aqui (em um local de cada vez)

    echo'existe o post'; 

    $a['nome'] = $_POST['nome']; 
    $a['email'] = $_POST['email']; 

    echo'<pre>'; print_r($a); echo'</pre>'; 

    create('user',$a); 
   } 
?> 

<input type="text" name="nome" value="nome"/>     
<input type="text" name="email" value="email"/>     
<input type="submit" name="sub" value="cadastar"/> 

</form>

 

Usando a 2ª opção ele apresenta o erro abaixo:

 

 

Catchable fatal error: Argument 3 passed to create() must be of the type array, none given, called in E:\wamp\www\pdo-oo\index.php on line 29 and defined in E:\wamp\www\pdo-oo\classes\conexao.php on line 18

 

function create($bd, $tabela, array $datas) {   //linha 18

Compartilhar este post


Link para o post
Compartilhar em outros sites

O global é pra ser usado dentro da função... Você definiu uma função com três parâmetros onde o terceiro é um array e está passando apenas dois.... não seria create($db, 'user',$a); ?

Compartilhar este post


Link para o post
Compartilhar em outros sites

É melhor estudar o conceito e estruturas do PDOStatement antes de sair criando função.

 

Só de olhar vi que ta tudo errado.

 

Leia:

 

http://www.php.net/manual/pt_BR/pdostatement.execute.php

Compartilhar este post


Link para o post
Compartilhar em outros sites

O global é pra ser usado dentro da função... Você definiu uma função com três parâmetros onde o terceiro é um array e está passando apenas dois.... não seria create($db, 'user',$a); ?

 

Também a mesma coisa, não inseri os dados e não apresenta erro.

 

É melhor estudar o conceito e estruturas do PDOStatement antes de sair criando função.

 

Só de olhar vi que ta tudo errado.

 

Leia:

 

http://www.php.net/manual/pt_BR/pdostatement.execute.php

 

Tudo 100% errado?

 

Vou dar uma lida, obrigado.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Tirando:

try {

} catch (PDOException $e) {
	echo 'Houve algum erro na insercao dos dados: '. $e->getMessage();
}

O restante sem dúvida!

 

e tenta com $bd->query(), pois va vi gente quebrar cabeça e não solucionar PDOStatement dentro de classes e funções.

 

Fora é uma maravilha e recomendo.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Não faça OO de qualquer jeito. Um dos pontos "chaves" da OO: o estado não é global. Entenda o conceito de instâncias, ele é a base fundamental do paradigma.

 

A keyword global, assim como outras formas de se criar estado global são um perigo à manutenção e a testabilidade do sistema.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Eu recriei estou usando essa, não tem apresentado problemas nenhum, gravando normalmente, mas sabemos que a tarefa não é somente gravar e sim gravar com segurança. Está seguro?

function create($bd, $tabela, array $dados){
    $sql = "INSERT INTO $tabela (";
    $sql.= implode(",",array_keys($dados));
    $sql.= ") values (";
 
   $valores = array_values($dados);
     foreach($dados as $valor):
       $sql.= "'$valor'". ',';
   endforeach;

  $sql_insert = substr($sql,0,-1);
  $sql_insert.=")";
     //echo $sql_insert ;
  try{
    $cadastrar = $bd->prepare($sql_insert);
    $cadastrar->execute();
  }catch(PDOException $e){
      echo 'Houve algum erro na inserção dos dados: '. $e->getMessage();
  }
}

 

Além do strip_tags, tem algo para tentar prevenir o Injection?

$a['nome']  = $_POST['nome']; 
$a['email'] = $_POST['email']; 
$a['data']  = $_POST['data']; 

create($bd, 'tabela',$a);

Compartilhar este post


Link para o post
Compartilhar em outros sites

strip_tags é problemático. Remover não é a solução. Imagine um email, como você manda um email normalmente em uma mensagem? entre os símbolos de < e >, e o strip_tags simplesmente vai remover o email, e em alguns casos onde você quer postar um código, o strip_tags vai remover isso...... você vai perder conteúdo

 

A SQL injection os prepared statements já resolve, o XSS você resolve usando htmlspecialchars.

 

Você não está bem usando os prepared statements, apenas o método prepare. Leia: http://php.net/manual/en/pdo.prepared-statements.php

Compartilhar este post


Link para o post
Compartilhar em outros sites

Pelo que entendi do link que você mandou e http://codigofonte.uol.com.br/artigo/php/evite-sql-injection-usando-prepared-statements-no-php

Como do php.net diz:

 $stmt->bindParam(':name', $name);


Então eu fiz

$cadastrar = $pdo->prepare($sql_insert);
$cadastrar->bindParam(':$dados', $valor, PDO::PARAM_STR); 
$cadastrar->execute();


Fiz bobeira, ou era isso mesmo?

 

Ou eu teria que passar o Insert Into dentro do $pdo->prepare(); ?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Fez bobeira :P. Essa função é genérica demais, não há uma especificação de query, tente usar funções que fazem mais sentido. Não há como usar prepared statements, já que a query é variável. Um exemplo:

 

<?php

$query = '
    INSERT INTO users (
        name,
        email
    ) VALUES (
        :name,
        :email
    );
';

$pdo = new PDO(/* dados de conexão */);

$statement = $pdo->prepare($query);
$statemnt->bindValue(':name', $name, PDO::PARAM_STR);
$statemnt->bindValue(':email', $email, PDO::PARAM_STR);

$statement->execute();

Compartilhar este post


Link para o post
Compartilhar em outros sites

Dica! Seria mais fácil você entender o conceito de classes e seus métodos

 

e aplicar OOP de forma correta, http://goo.gl/0wKMP

 

Exemplo prático para seu código, mais tem que ler o link acima para entender melhor

 

<?php
class data {

	private $privateNome = null;
	private $privateEmail = null;
	private $privateData = null;
	private $privateStatus = null;
	
	//Métodos
	public function setPrivateNome($privateNome){
		$this->privateNome = $privateNome;
	}

	public function setPrivateEmail($privateEmail){
		$this->privateEmail = $privateEmail;
	}
	
	public function setPrivateData($privateData){
		$this->privateData = $privateData;
	}
	
	public function getPrivateStatus(){
		return $this->privateStatus;
	}
	
	public function insert (){
		
		$query = sprintf("INSERT INTO users (
				name,
				email,
				data,
			) VALUES (
				'%s',
				'%s',
				'%s'
			)", $this->privateNome, $this->privateEmail, $this->privateData);
		
		
		$this->privateStatus = $query;
	
	}
}

$privateNome  = $_POST['nome'] = 'Rogerio Santana'; 
$privateEmail = $_POST['email'] = 'mail@gmail.com'; 
$privateData  = $_POST['data'] = '2013-05-11';

$insert = new data(); // instanciando a classe
$insert->setPrivateNome($privateNome);
$insert->setPrivateEmail($privateEmail);
$insert->setPrivateData($privateData);
$insert->insert();
echo $insert->getPrivateStatus();
?>

 

 

Porque se começar da forma errada OOP, vai ter dor de cabeça la na frente.

 

POG não amigo! :natalwink:

 

Há e esses setters foram gerados automaticamente aqui http://www.icurtain.co.uk/getset.php e fica a dica para que quizer.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Mas o insert e outros comandos não fazem parte da entidade (class data nesse caso).

 

A entidade ou VO, armazenam os dados, fazem operações com ele, podem validar e filtrar, sempre trabalhando com os dados. E a DAO sempre recebe uma instância da PDO e um VO (para inserir e atualizar apenas) para executar comandos no DB.

 

Mas há outros padrões além de DAO/VO.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Como disse é exemplo básico para começar a entender, se ele quiser ir do meio pro início sera que entenderá?

 

é a mesma coisa do sujeito que ganha na loteria uma bolada de 50 milhões, se não tem uma base de conhecimento sobre finanças volta a estaca zero novamente, e se tiver dobra!

 

Por isso postei o link http://goo.gl/0wKMP

Compartilhar este post


Link para o post
Compartilhar em outros sites

Dica! Seria mais fácil você entender o conceito de classes e seus métodos

 

e aplicar OOP de forma correta, http://goo.gl/0wKMP

 

Exemplo prático para seu código, mais tem que ler o link acima para entender melhor

 

<?php
class data {

	private $privateNome = null;
	private $privateEmail = null;
	private $privateData = null;
	private $privateStatus = null;
	
	//Métodos
	public function setPrivateNome($privateNome){
		$this->privateNome = $privateNome;
	}

	public function setPrivateEmail($privateEmail){
		$this->privateEmail = $privateEmail;
	}
	
	public function setPrivateData($privateData){
		$this->privateData = $privateData;
	}
	
	public function getPrivateStatus(){
		return $this->privateStatus;
	}
	
	public function insert (){
		
		$query = sprintf("INSERT INTO users (
				name,
				email,
				data,
			) VALUES (
				'%s',
				'%s',
				'%s'
			)", $this->privateNome, $this->privateEmail, $this->privateData);
		
		
		$this->privateStatus = $query;
	
	}
}

$privateNome  = $_POST['nome'] = 'Rogerio Santana'; 
$privateEmail = $_POST['email'] = 'mail@gmail.com'; 
$privateData  = $_POST['data'] = '2013-05-11';

$insert = new data(); // instanciando a classe
$insert->setPrivateNome($privateNome);
$insert->setPrivateEmail($privateEmail);
$insert->setPrivateData($privateData);
$insert->insert();
echo $insert->getPrivateStatus();
?>

 

 

Porque se começar da forma errada OOP, vai ter dor de cabeça la na frente.

 

POG não amigo! :natalwink:

 

Há e esses setters foram gerados automaticamente aqui http://www.icurtain.co.uk/getset.php e fica a dica para que quizer.

 

Vou estudar ... agradeço a sua ajuda como também a do Enrico

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.