nunolevezinho Posted May 31, 2012 at 09:05 AM Report #459332 Posted May 31, 2012 at 09:05 AM (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 May 31, 2012 at 10:47 AM by brunoais tópico separado de: http://www.portugal-a-programar.pt/topic/53880-sql-server-proteger-queries-com-php/
mjamado Posted May 31, 2012 at 11:21 AM Report #459428 Posted May 31, 2012 at 11:21 AM 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.
nunolevezinho Posted May 31, 2012 at 02:19 PM Author Report #459470 Posted May 31, 2012 at 02:19 PM (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 May 31, 2012 at 02:21 PM by nunolevezinho
mjamado Posted May 31, 2012 at 02:41 PM Report #459479 Posted May 31, 2012 at 02:41 PM 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.
nunolevezinho Posted May 31, 2012 at 03:18 PM Author Report #459491 Posted May 31, 2012 at 03:18 PM 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##);
mjamado Posted May 31, 2012 at 03:37 PM Report #459498 Posted May 31, 2012 at 03:37 PM 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(); 1 Report "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.
nunolevezinho Posted May 31, 2012 at 03:47 PM Author Report #459502 Posted May 31, 2012 at 03:47 PM Hmm, ok já entendi obrigado. Só uma coisa, é normal a página demorar cerca de10 segundos a carregar?
mjamado Posted May 31, 2012 at 04:05 PM Report #459504 Posted May 31, 2012 at 04:05 PM 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.
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now