Jump to content

Recommended Posts

Posted (edited)

Já consegui fazer a ligação usando o PDO, mas por algum motivo isto não está a fazer display dos erros <.< sou novo com isto do PDO, alguem me pode dar uma ajuda?

Ex:

<?PHP try
 {
   $DBH = new PDO('sqlsrv:server=' . $server . ';database=' . $database, $user, $password);

   $STMT = $DBH->prepare("INSERT INTO tabela (nome, idade) VALUES (:nome, :idade)");
   $STMT->bindParam(':nome', $nome);
   $STMT->bindParam(':idade', $idade);

   $nome  = 'Nuno';
   $idade = 21;
   $STMT->execute();

 }
catch (PDOException $e)
 {
   echo $e->getMessage();
 }
?>

A tabela não existe, foi colocado assim propositadamente para ver como faço display dos erros.

Edited by brunoais
tópico separado de: http://www.portugal-a-programar.pt/topic/53880-sql-server-proteger-queries-com-php/
Posted

O PDO, por defeito, tem as excepções desligadas; o controle de erros é feito verificando se os recursos foram correctamente criados. Tens duas hipóteses: usar esse comportamento, ou, bastante melhor, elevar o nível de erros do PDO.

Método #1:

<?php
try
{
   $dbh = new PDO('sqlsrv:server=' . $server . ';database=' . $database, $user, $password);
   $stmt = $dbh->prepare("INSERT INTO tabela (nome, idade) VALUES (:nome, :idade)");
   if($stmt !== false)
   {
       $stmt->bindParam(':nome', $nome);
       $stmt->bindParam(':idade', $idade);
       $nome  = 'Nuno';
       $idade = 21;
       $res = $stmt->execute();
       if($res === false)
           echo $stmt->errorInfo();
   }
   else
       echo $dbh->errorInfo();
}
catch (PDOException $e)
{
   echo $e->getMessage();
}
?>

Método #2:

<?php
try
{
   $dbh = new PDO('sqlsrv:server=' . $server . ';database=' . $database, $user, $password);
   // aqui levantas o nível de erros para atirar excepções
   $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
   $stmt = $dbh->prepare("INSERT INTO tabela (nome, idade) VALUES (:nome, :idade)");

   $stmt->bindParam(':nome', $nome);
   $stmt->bindParam(':idade', $idade);

   $nome  = 'Nuno';
   $idade = 21;
   $stmt->execute();
}
catch (PDOException $e)
{
   echo $e->getMessage();
}
?>

Como notas adicionais, antes de desenvolveres mais, cria já uma classe com o padrão singleton que te devolve sempre uma ligação PDO, para não teres que a andar a criar repetidamente. Nessa classe poderá (e deverá) constar a elevação do nível de erros, assim como várias outras coisas necessárias à ligação (por exemplo, a escolha do encoding UTF-8).

"Para desenhar um website, não tenho que saber distinguir server-side de client-side" - um membro do fórum que se auto-intitula webdesigner. Temo pelo futuro da web.

Posted (edited)

Sobre a classe arranjei uma que me parece boa para as minhas necessidades.

Quanto ao encoding não percebi o que querias dizer.

Já agora meto aquilo de elevar os erros no __construct ? Tipo isto:

self::$PDOInstance->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

class sdb
{
static private $PDOInstance;

public function __construct($dsn, $username=false, $password=false)
{
	if(!self::$PDOInstance) {
	 try {
  self::$PDOInstance = new PDO($dsn, $username, $password);
  self::$PDOInstance->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  } catch (PDOException $e) {
  die("Ligação sem Sucesso # Erro: " . $e->getMessage() . "<br/>");
  }
 }
   return self::$PDOInstance;		
}
public function beginTransaction() {
 return self::$PDOInstance->beginTransaction();
}

  public function commit() {
  return self::$PDOInstance->commit();
   }
public function errorCode() {
 return self::$PDOInstance->errorCode();
}
public function errorInfo() {
 return self::$PDOInstance->errorInfo();
}
public function exec($statement) {
 return self::$PDOInstance->exec($statement);
}
public function getAttribute($attribute) {
 return self::$PDOInstance->getAttribute($attribute);
}
public function getAvailableDrivers(){
 return Self::$PDOInstance->getAvailableDrivers();
}
   public function lastInsertId($name) {
   return self::$PDOInstance->lastInsertId($name);
   }
public function prepare ($statement, $driver_options=false) {
 if(!$driver_options) $driver_options=array();
 return self::$PDOInstance->prepare($statement, $driver_options);
}
public function query($statement) {
 return self::$PDOInstance->query($statement);
}
public function queryFetchAllAssoc($statement) {
 return self::$PDOInstance->query($statement)->fetchAll(PDO::FETCH_ASSOC);
}
public function queryFetchRowAssoc($statement) {
 return self::$PDOInstance->query($statement)->fetch(PDO::FETCH_ASSOC);	
}
public function queryFetchColAssoc($statement) {
 return self::$PDOInstance->query($statement)->fetchColumn();	
}
public function quote ($input, $parameter_type=0) {
 return self::$PDOInstance->quote($input, $parameter_type);
}
public function rollBack() {
 return self::$PDOInstance->rollBack();
}	
public function setAttribute($attribute, $value  ) {
 return self::$PDOInstance->setAttribute($attribute, $value);
}
}
?>
Edited by nunolevezinho
Posted
Sobre a classe arranjei uma que me parece boa para as minhas necessidades.

Uma coisa tão simples de fazer e vais copiar uma que encontraste na 'Net - ainda por cima, mal feita! Uma classe para gerir a ligação à BD devia ser singleton (que essa não é), com um método de factory. Além disso, encapsula métodos exactamente com o mesmo nome - mais código, zero benefícios.

Quanto ao encoding não percebi o que querias dizer.

Para evitar problemas com caracteres não ASCII, deve ser usado UTF-8; no entanto, isso requer que a ligação à BD seja "informada" desse encoding. Podes fazer isso com outra mudança de atributo:

$dbh->setAttribute(PDO::SQLSRV_ATTR_ENCODING, PDO::SQLSRV_ENCODING_UTF8);

Por acaso, é capaz de não ser necessário - penso que as ligações MsSQL, por defeito, são feitas em UTF-8. Mas verifica, com e sem essa mudança, para ver se os caracteres vêm em condições.

Já agora meto aquilo de elevar os erros no __construct ?

Deve ser colocado logo a seguir à ligação. No teu exemplo, sim, no construtor da classe (embora eu te aconselhe a largar essa classe).

"Para desenhar um website, não tenho que saber distinguir server-side de client-side" - um membro do fórum que se auto-intitula webdesigner. Temo pelo futuro da web.

Posted

Hmm, então estavas a falar de um classe só para fazer a ligação?

Tipo?

class db extends PDO {
private $error;
public function __construct($dsn, $user="", $passwd="") {
 $options = array(
  PDO::ATTR_PERSISTENT => true,
  PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
  PDO::SQLSRV_ATTR_ENCODING => PDO::SQLSRV_ENCODING_UTF8
 );
 try {
  parent::__construct($dsn, $user, $passwd, $options);
 } catch (PDOException $e) {
  $this->error = $e->getMessage();
 }
}

}
$database = new db(##Data##);
Posted

Hmm, então estavas a falar de um classe só para fazer a ligação?

Sim, mas que respeitasse o padrão singleton, para que não andasses sempre a reinstanciar a classe - poupas na memória. Assim:


class PDOSingleton
{
   /**
    * @var PDO
    */
   private static $_instance;

   /**
    * O construtor privado impede que alguém ande a criar novas instâncias da classe
    */
   private function __construct() { /* */ }

   /**
    * Método factory - devolve a instância criada do PDO, ou cria uma nova
    *
    * @return PDO
    */
   public static function GetObj()
   {
       if(!isset(self::$_instance))
       {
           self::$_instance = new PDO(
               "tua_string_ligacao",
               "teu_username",
               "tua_password",
               array(
                   PDO::ATTR_PERSISTENT => true,
                   PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
                   PDO::SQLSRV_ATTR_ENCODING => PDO::SQLSRV_ENCODING_UTF8
               )
           );
       }

       return self::$_instance;
   }

   /**
    * Já agora, impedir também o uso do clone
    */
   public function __clone()
   {
       throw new Exception("Hey! Os singletons não se clonam!");
   }
}

$database = PDOSingleton::GetObj();
  • Vote 1

"Para desenhar um website, não tenho que saber distinguir server-side de client-side" - um membro do fórum que se auto-intitula webdesigner. Temo pelo futuro da web.

Posted
Só uma coisa, é normal a página demorar cerca de10 segundos a carregar?

Não sei o que é que o request está a fazer, mas bom não é, de certeza... 😛

De qualquer forma, não me parece que esteja relacionado com este tópico, por isso: nova dúvida, novo tópico! 👍

"Para desenhar um website, não tenho que saber distinguir server-side de client-side" - um membro do fórum que se auto-intitula webdesigner. Temo pelo futuro da web.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.