claudiop Posted June 9, 2012 at 07:31 PM Report #461671 Posted June 9, 2012 at 07:31 PM Boas. Eu fiz um CMS para o meu site, e como a parte do blog me estava a dar mais problemas de fazer á mão (porque ainda não sou grande espingarda em orientação a objectos), acabei por ir buscar uma classe a um tutorial e adapta-la ás minhas necessidades (integração/bilingue etc...) Agora que já estou a finalizar o trabalho resolvi substituir os "hello world's" e "lorem ipsum's" por algo mais palpável. Mas vi que o PHP está a ter problemas com o encoding. Do lado da base de dados, já tentei latin e utf-u. Quer um, quer outro me aparecem na perfeição no PhpMyAdmin (acentos/caracteres expeciais etc...), mas por algum motivo estão a ter diversos problemas a aparecer correctamente no site. Antes de mais nada(Antes de ser despromovido a "muito noob"): <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> Está presente no head. Já experimentei abrir uma query sozinha, sem templates ou qualquer outra coisa, e apareceu igualmente mal. Mas se colocar o conteúdo estaticamente, vai aparecer tudo bem, com acentos e tudo mais. A classe que faz os query's é assim: <?php class Article { // Properties /** * @var int The article ID from the database */ public $id = null; /** * @var int When the article is to be / was first published */ public $publicationDate = null; /** * @var string Full title of the article */ public $title = null; public $titlept = null; /** * @var string A short summary of the article */ public $summary = null; public $summarypt = null; /** * @var string The HTML content of the article */ public $content = null; public $contentpt = null; /** * Sets the object's properties using the values in the supplied array * * @param assoc The property values */ public function __construct($data = array()) { if (isset($data['id'])) $this->id = (int) $data['id']; if (isset($data['publicationDate'])) $this->publicationDate = (int) $data['publicationDate']; if (isset($data['title'])) $this->title = preg_replace("/[^\.\,\-\_\'\"\@\?\!\:\$ a-zA-Z0-9()]/", "", $data['title']); if (isset($data['titlept'])) $this->titlept = preg_replace("/[^\.\,\-\_\'\"\@\?\!\:\$ a-zA-Z0-9()]/", "", $data['titlept']); if (isset($data['summary'])) $this->summary = preg_replace("/[^\.\,\-\_\'\"\@\?\!\:\$ a-zA-Z0-9()]/", "", $data['summary']); if (isset($data['summarypt'])) $this->summarypt = preg_replace("/[^\.\,\-\_\'\"\@\?\!\:\$ a-zA-Z0-9()]/", "", $data['summarypt']); if (isset($data['content'])) $this->content = $data['content']; if (isset($data['contentpt'])) $this->contentpt = $data['contentpt']; } /** * Sets the object's properties using the edit form post values in the supplied array * * @param assoc The form post values */ public function storeFormValues($params) { // Store all the parameters $this->__construct($params); // Parse and store the publication date if (isset($params['publicationDate'])) { $publicationDate = explode('-', $params['publicationDate']); if (count($publicationDate) == 3) { list ( $y, $m, $d ) = $publicationDate; $this->publicationDate = mktime(0, 0, 0, $m, $d, $y); } } } /** * Returns an Article object matching the given article ID * * @param int The article ID * @return Article|false The article object, or false if the record was not found or there was a problem */ public static function getById($id) { $conn = new PDO(DB_DSN, DB_USERNAME, DB_PASSWORD); $sql = "SELECT *, UNIX_TIMESTAMP(publicationDate) AS publicationDate FROM articles WHERE id = :id"; $st = $conn->prepare($sql); $st->bindValue(":id", $id, PDO::PARAM_INT); $st->execute(); $row = $st->fetch(); $conn = null; if ($row) return new Article($row); } /** * Returns all (or a range of) Article objects in the DB * * @param int Optional The number of rows to return (default=all) * @param string Optional column by which to order the articles (default="publicationDate DESC") * @return Array|false A two-element array : results => array, a list of Article objects; totalRows => Total number of articles */ public static function getList($numRows = 1000000) { $conn = new PDO(DB_DSN, DB_USERNAME, DB_PASSWORD); $sql = "SELECT SQL_CALC_FOUND_ROWS *, UNIX_TIMESTAMP(publicationDate) AS publicationDate FROM articles ORDER BY publicationDate DESC LIMIT :numRows"; $st = $conn->prepare($sql); $st->bindValue(":numRows", $numRows, PDO::PARAM_INT); $st->execute(); $list = array(); while ($row = $st->fetch()) { $article = new Article($row); $list[] = $article; } // Now get the total number of articles that matched the criteria $sql = "SELECT FOUND_ROWS() AS totalRows"; $totalRows = $conn->query($sql)->fetch(); $conn = null; return ( array("results" => $list, "totalRows" => $totalRows[0]) ); } /** * Inserts the current Article object into the database, and sets its ID property. */ public function insert() { // Does the Article object already have an ID? if (!is_null($this->id)) trigger_error("Article::insert(): Attempt to insert an Article object that already has its ID property set (to $this->id).", E_USER_ERROR); // Insert the Article $conn = new PDO(DB_DSN, DB_USERNAME, DB_PASSWORD); $sql = "INSERT INTO articles ( publicationDate, title, summary, content ) VALUES ( FROM_UNIXTIME(:publicationDate), :title, :summary, :content )"; $st = $conn->prepare($sql); $st->bindValue(":publicationDate", $this->publicationDate, PDO::PARAM_INT); $st->bindValue(":title", $this->title, PDO::PARAM_STR); $st->bindValue(":summary", $this->summary, PDO::PARAM_STR); $st->bindValue(":content", $this->content, PDO::PARAM_STR); $st->execute(); $this->id = $conn->lastInsertId(); $conn = null; } /** * Updates the current Article object in the database. */ public function update() { // Does the Article object have an ID? if (is_null($this->id)) trigger_error("Article::update(): Attempt to update an Article object that does not have its ID property set.", E_USER_ERROR); // Update the Article $conn = new PDO(DB_DSN, DB_USERNAME, DB_PASSWORD); $sql = "UPDATE articles SET publicationDate=FROM_UNIXTIME(:publicationDate), title=:title, summary=:summary, content=:content WHERE id = :id"; $st = $conn->prepare($sql); $st->bindValue(":publicationDate", $this->publicationDate, PDO::PARAM_INT); $st->bindValue(":title", $this->title, PDO::PARAM_STR); $st->bindValue(":summary", $this->summary, PDO::PARAM_STR); $st->bindValue(":content", $this->content, PDO::PARAM_STR); $st->bindValue(":id", $this->id, PDO::PARAM_INT); $st->execute(); $conn = null; } /** * Deletes the current Article object from the database. */ public function delete() { // Does the Article object have an ID? if (is_null($this->id)) trigger_error("Article::delete(): Attempt to delete an Article object that does not have its ID property set.", E_USER_ERROR); // Delete the Article $conn = new PDO(DB_DSN, DB_USERNAME, DB_PASSWORD); $st = $conn->prepare("DELETE FROM articles WHERE id = :id LIMIT 1"); $st->bindValue(":id", $this->id, PDO::PARAM_INT); $st->execute(); $conn = null; } } ?> Poderá isto ajudar? http://php.net/manua...set-charset.php Se sim, como aplico nesta classe? (A unica parte da classe que é usada, é o recurso de busca á BD, o resto vai ser removido quando tiver tempo para ver se nada vai causar problemas) Para verem o que quero dizer: http://www.claudiop.com (Troquem a lingua para portugues e vejam um post no blog. Dependendo do browser e do O.S., aparecem ou espaços ou pontos de interrogação no lugar dos acentos) PS: Se fizerem o favor, podem dizer alguma desformatação que vejam no template? (Tambem só tem alguns dias) Cumprimentos
brunoais Posted June 9, 2012 at 07:35 PM Report #461672 Posted June 9, 2012 at 07:35 PM (edited) Já tentaste: http://www.php.net/m...truct.php#96325 ? Poderá isto ajudar? http://php.net/manua...set-charset.php Se sim, como aplico nesta classe? (A unica parte da classe que é usada, é o recurso de busca á BD, o resto vai ser removido quando tiver tempo para ver se nada vai causar problemas) Isso não é uma classe, é uma função. 😉 Para verem o que quero dizer: http://www.claudiop.com (Troquem a lingua para portugues e vejam um post no blog. Dependendo do browser e do O.S., aparecem ou espaços ou pontos de interrogação no lugar dos acentos) Pois... Isso é charset errado e parece-me o charset errado na ligação com a DB. Já agora, não existe utf-u, é utf-8. Tens a página com uma formatação (CSS) um pouco má. Há coisas fora do sítio. Já vi o problema principal. O HTML é inválido. Por exemplo, tens um <a> como child de <ul>. Edited June 9, 2012 at 07:44 PM by brunoais (emoticon para evitar interpretação errada) "[Os jovens da actual geração]não lêem porque não envolve um telecomando que dê para mirar e atirar, não falam porque a trapalhice é rainha e o calão é rei" autor: thoga31 Life is a genetically transmitted disease, induced by sex, with death rate of 100%.
claudiop Posted June 9, 2012 at 08:03 PM Author Report #461678 Posted June 9, 2012 at 08:03 PM (edited) Já tentaste: http://www.php.net/m...truct.php#96325 ? Isso não é uma classe, é uma função. 😉 Pois... Isso é charset errado e parece-me o charset errado na ligação com a DB. Já agora, não existe utf-u, é utf-8. Tens a página com uma formatação (CSS) um pouco má. Há coisas fora do sítio. Já vi o problema principal. O HTML é inválido. Por exemplo, tens um <a> como child de <ul>. Deixei agora assim: public static function getList($numRows = 1000000) { $conn = new PDO(DB_DSN, DB_USERNAME, DB_PASSWORD, array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\'')); E continua mal. Era a isso que te referias? Com classe referia-me ao "article" (o ficheiro todo que fiz paste). Desculpa, enganei-me a escrever. O u está em baixo do 8 😛 Sim, eu estou a par dos erros que o validador acusa, mas não é isso que está a causar o problema porque já testei sem template e sem mais nenhum html do que o proprio post. Quando acabar de corrigir os erros visiveis, passo para os bugs invisiveis. PS: Quando adicionei aquele parametro na função, apesar de nada ter mudado, reparei que a informação já está correcta aqui: http://www.claudiop.com/includes/blog/?action=viewpost&post=1 Mas se reparar no codigo fonte, não está ai nada mais do que o post. Nem sequer declara ser utf-8. Onde estou a errar agora? Cumprimentos Edited June 9, 2012 at 08:21 PM by brunoais o link estava mal + geshi
brunoais Posted June 9, 2012 at 08:25 PM Report #461680 Posted June 9, 2012 at 08:25 PM HTML inválido + n é indicado que o charset é utf-8. "[Os jovens da actual geração]não lêem porque não envolve um telecomando que dê para mirar e atirar, não falam porque a trapalhice é rainha e o calão é rei" autor: thoga31 Life is a genetically transmitted disease, induced by sex, with death rate of 100%.
claudiop Posted June 9, 2012 at 08:34 PM Author Report #461682 Posted June 9, 2012 at 08:34 PM (edited) HTML inválido + n é indicado que o charset é utf-8. Comentei temporariamente, todas as partes do documento que eram invalidas. Agora como podes ver o html está perfeitamente valido: http://validator.w3.org/check?uri=http%3A%2F%2Fwww.claudiop.com%2F%3Faction%3Dviewpost%26post%3D1&charset=%28detect+automatically%29&doctype=Inline&group=0&user-agent=W3C_Validator%2F1.3 Está presente no documento o: <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> A ligação á base de dados está a decorrer correctamente, e a função agora está assim: public static function getList($numRows = 1000000) { $conn = new PDO(DB_DSN, DB_USERNAME, DB_PASSWORD, array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\'')); $sql = "SELECT SQL_CALC_FOUND_ROWS *, UNIX_TIMESTAMP(publicationDate) AS publicationDate FROM articles ORDER BY publicationDate DESC LIMIT :numRows"; $st = $conn->prepare($sql); $st->bindValue(":numRows", $numRows, PDO::PARAM_INT); $st->execute(); $list = array(); while ($row = $st->fetch()) { $article = new Article($row); $list[] = $article; } // Now get the total number of articles that matched the criteria $sql = "SELECT FOUND_ROWS() AS totalRows"; $totalRows = $conn->query($sql)->fetch(); $conn = null; return ( array("results" => $list, "totalRows" => $totalRows[0]) ); } O que poderá estar a correr mal. Desculpa o incomodo e a insistência, mas não estou mesmo a conseguir descubrir o problema. Cumprimentos Edited June 9, 2012 at 08:40 PM by brunoais geshi!
HappyHippyHippo Posted June 9, 2012 at 08:40 PM Report #461683 Posted June 9, 2012 at 08:40 PM já confirmaste que os dados na base de dados estão em utf-8 ? tenta meter dados novos em utf-8 para confirmar se não são os dados antigos que estão numa codificação diferente IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
brunoais Posted June 9, 2012 at 08:43 PM Report #461684 Posted June 9, 2012 at 08:43 PM Já rescreveste os dados depois de alterar o encoding da coluna para utf-8? "[Os jovens da actual geração]não lêem porque não envolve um telecomando que dê para mirar e atirar, não falam porque a trapalhice é rainha e o calão é rei" autor: thoga31 Life is a genetically transmitted disease, induced by sex, with death rate of 100%.
claudiop Posted June 9, 2012 at 08:48 PM Author Report #461685 Posted June 9, 2012 at 08:48 PM Em 09/06/2012 às 22:43, brunoais disse: Já rescreveste os dados depois de alterar o encoding da coluna para utf-8? Sim, acabei de fazer mais uma row só com acentos. O resultado é este: Citação Quero testar os acentos: ������ O encoding é "utf8_unicode_ci" Cumprimentos
KTachyon Posted June 9, 2012 at 08:51 PM Report #461686 Posted June 9, 2012 at 08:51 PM Duas coisas (assumindo MySQL): - Se estás a aceder como root, nunca vais receber dados UTF-8, nem se configurares a ligação para devolver os dados em UTF-8. - O problema pode não ser o encoding da pase de dados, mas o encoding que é devolvido pela ligação (o MySQL recodifica os dados consoante o encoding pedido (ou o default). “There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult.” -- Tony Hoare
claudiop Posted June 10, 2012 at 12:02 AM Author Report #461713 Posted June 10, 2012 at 12:02 AM Em 09/06/2012 às 22:51, KTachyon disse: Duas coisas (assumindo MySQL): - Se estás a aceder como root, nunca vais receber dados UTF-8, nem se configurares a ligação para devolver os dados em UTF-8. - O problema pode não ser o encoding da pase de dados, mas o encoding que é devolvido pela ligação (o MySQL recodifica os dados consoante o encoding pedido (ou o default). Ás tantas, já nem sei qual é o problema. A base de dados agora está toda definida para utf-8 general, quer as colunas quer o default. Reparei num problema que pode indicar que não tem nada a ver com a base de dados. Antes de ter movido o site para o alojamento, fiz a construção quase toda localmente, e reparei num problema que não tinha. Tenho dois ficheiros que definem as traduções do menu/logo etc... en.php e pt.php. Uma imagem de um deles: http://www.claudiop.com/image/utf.png Abri o notepad++ propositadamente para ter certeza absoluta do encoding que o ficheiro tem. UTF-8 sem sombra de duvida. Reparem no carácter que está marcado na linha 3(um simples ponto). Quer defina UTF-8 no metadata, quer não, esse carácter assume um "?" em seguida ao titulo. Poderão estes erros todos relacionados com encoding estar relacionados com a instalação do interpretador de php? Porque localmente esse carácter aparece bem. Vou experimentar recriar a base de dados localmente para ver se o problema desaparece. EDIT: Consegui resolver o problema, se bem que ainda não entendi o como. Fui reorganizar a classe que continha todas as funções que interagem com a BD. Depois de apagar 2/3 daquilo, acabei por dar por mais uma ligação á base de dados (no getbyid). Juntei a essa ligação o parâmetro para forçar UTF-8, e a BD passou a passar os dados correctamente. Quanto aos dados estáticos que estavam a dar problema, alterei os scripts para que nunca chegassem a ser variaveis. Por exemplo o ponto, consegui coloca-lo em separado num require, de forma a que fosse parar ao mesmo sitio, mas nunca constando do script. Cumprimentos Cumprimentos
brunoais Posted June 10, 2012 at 07:28 AM Report #461730 Posted June 10, 2012 at 07:28 AM (edited) Atenção que o BOM pode estragar o teu código (se tentas alterar os headers) indicando que os headers já foram enviados. Edited June 10, 2012 at 07:29 AM by brunoais "[Os jovens da actual geração]não lêem porque não envolve um telecomando que dê para mirar e atirar, não falam porque a trapalhice é rainha e o calão é rei" autor: thoga31 Life is a genetically transmitted disease, induced by sex, with death rate of 100%.
claudiop Posted June 10, 2012 at 01:46 PM Author Report #461760 Posted June 10, 2012 at 01:46 PM Atenção que o BOM pode estragar o teu código (se tentas alterar os headers) indicando que os headers já foram enviados. Obrigado pela sugestão. Nem sabia o que era, agora que li isso é que fui pesquisar. 😉 Cumprimentos
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