Set
24
2009

Melhorar performance do site

Há uns dias andava a testar uma página para a empresa que estou a desenvolver um portal que servirá essencialmente para a promoção de cursos quando me deparei que numa simples listagem os tempos de PHP estavam algo exagerados.

Infelizmente muitas vezes as boas ideias ou soluções só nos vem à mente quando já passamos por vezes horas a fio, ou mesmo dias, a fazer testes e mais testes e quando nos damos conta, plimm, luzinha :)

Para terem uma ideia, o pagina em questão tinha que listar apenas 25 pedidos de informação, relacionados a cursos, mas tinha que fazer uma <select…> com todos os cursos, que neste caso era de 4000. Sei que o numero é algo alto, mas mesmo apenas com 500 cursos o tempo era demasiadamente exagerado 0.458961 segundos. Isto pensando que apenas eu estava a abrir esta página, e que após estar online servira centenas de utilizadores ao mesmo tempo, podem perceber a minha preocupação :)

Como referi acima, depois de muitas voltas, vários testes, cheguei à conclusão que o realmente demorava bastante era o tal <select> e quase, quase desisti, visto que nada podia fazer, precisava dele tal qual como estava.

Bem a solução passou por algo, que como referi acima foi tipo plimm (até me insultei a mim próprio), isto por que era tão simples como usar a função  ob_start(); no inicio da página e ob_end_flush(); mesmo no final da página.

Para quem não sabe esta função o que faz é ir carregando tudo em memoria (servidor) e mostrar a página de 1 vez só, evitando aquelas situações de páginas que parecem que estão a ser carregadas às prestações :)

De referir que se a sua ligação à internet for lenta e a página pesada, vai sempre haver alguma falha, mas voltando ao assunto.

Apenas com o aplicar desta função o tempo foi reduzido dos tais 0.458961 segundos para  0.006717 segundos, o que realmente é uma grande diferença.

Para verem a documentação desta função podem ver o seguinte link:

http://pt.php.net/manual/pt_BR/function.ob-start.php

Para finalizar, como podem entender aconselho muito mesmo o uso desta função nos vossos sites.

0
Jul
09
2009

Função Mail do PHP

Hoje recordei-me que ao usar a função mail do php, na sua forma normal sempre me deu algumas dores de cabeça, e não é porque ela não funcione bem, tem a ver com o facto de poderem ocorrer alguns problemas inesperados e que na maioria das situações, nós como utilizadores normais podemos não nos dar conta.

Os problemas de que falo são, em primeiro lugar o email ir para ao correio não solicitado ou ao spam de alguns servidores de email globais, tal como o gmail, yahoo ou hotmail. No meu caso testei esta função para estes 3 de forma a garantir que passavam sem problemas nos filtros, e sendo que estes são sem dúvida os maiores, e os mais “complicados” em relação ao SPAM, podemos quase garantir que um email, ou sistema de newsletter que passe correctamente os filtros destes 3 sistemas, garantidamente passara em qualquer outro.

Então cá vai.

O uso normal da função tal como podem ver no www.php.net poderia ser o seguinte:

<?php
$Name = "O Nome"; //nome de quem envia
$email = "email@dominio.com"; //O email de envio
$recipient = "PessoaQueRecebe@endereco.com"; //O email de quem recebe
$mail_body = "Aqui vai o texto do email..."; //corpo do email
$subject = "Assunto para rever"; //Assunto
$header = "From: ". $Name . " <" . $email . ">"; //Campos Opcionais

mail($recipient, $subject, $mail_body, $header); //Comando de envio
?>

Aqui começa o problema :)

Uma das coisas importantes a adicionar nos cabeçalhos (header) da mensagem é o Reply to, esta é uma das regras de controlo de SPAM da maioria dos servidores, logo deve ser devidamente colocado.

Então no código mencionado adicionaria a seguinte linha:

$header = "From: ". $Name . " <" . $email . ">"; //Campos Opcionais - Esta já cá estava
$header .= "Reply-To:  O Seu Nome <email@dominio.com>"; //O nome e  email que esta a usar para o envio

Outra linha Importante a adicionar é o tipo de  Conteúdo/ formato do email e então teriamos mais a seguinte linha (por exemplo):

$header .= "Content-type: text/html";

Podemos ainda adicionar mais ao Header que é o tipo de caracteres, etc, mas isso não me vou alongar aqui, quero referir apenas os pontos básicosque dizem respeito aos filtros de SPAM.

Por fim, uma situação que é de extrema importancia, para que tudo fique certinho, tem a ver com uma situação que, a não ser que você faça a gestão de um servidor proprio, será dificil de notar. E isto tem a ver com os emails devolvidos. Por alguma razão, os emails tipicos que se recebe a notificar que um determinado utilizador não existe, ou que tem a caixa de correio cheia, etc, deveriam ser devolvidos ao email que estamos a definir em Reply-to, mas como referi, mas isso não acontece, e o que tambem pode influenciar no SPAM, porque o email, mesmo colocado com todos os parametros certinhos vai nos headear com as definições da conta por defeito do servidor, geralmente um nobody@servidor.com e, claro está que os emails de erro serão devolvidos a este endereço e não ao endereço que definimos acima.

Para resolver esta situação o que devemos fazer é acrescentar um pequeno codigo à linha (comando mail) de envio do email:

mail($recipient, $subject, $mail_body, $header, "-f  email@dominio.com"); //Comando de envio correcto

Ou, seja acrescenta-mos um 5º parametro a seguir ao $header, com  ”-f  email@dominio.com”, este será o email no qual serão entregues as mensagens de erro, mais uma vez na minha opinião deverá ser o mesmo definido, anteriormente como quem envia.

Posto isto junto tudo e aqui fica o exemplo completo:

<?php
$Name = "O Nome"; //nome de quem envia
$email = "email@dominio.com"; //O email de envio
$recipient = "PessoaQueRecebe@endereco.com"; //O email de quem recebe
$mail_body = "Aqui vai o texto do email..."; //corpo do email
$subject = "Assunto para rever"; //Assunto

$header = "From: ". $Name . " <" . $email . ">"; //Campos Opcionais
$header .= "Reply-To:  O Seu Nome <email@dominio.com>"; //O nome e  email que esta a usar para o envio
$header .= "Content-type: text/html";
mail($recipient, $subject, $mail_body, $header, "-f  email@dominio.com"); //Comando de envio
?>
0
Jul
02
2009

Usando ficheiros .po e .mo para traduzir o seu site

Depois de já ter visto várias vezes sites com este tipo de ficheiros decidi fazer o teste com este tipo de tradução e realmente para quem está a pensar em fazer sites muli-lingua esta é sem dúvida a melhor forma de o fazer.

De referir que o que neste caso menciono como tradução são os textos e/ou mensagens colocados no código dos seus ficheiros, como por exemplo os echo(”mensagem”); nos html <label><?=(”mensagem”)</label>, etc…

De forma a facilitar o trabalho deve nos seus ficheiros mudar o seguinte.

Em todas as mensagens, titulos, alertas, etc., que queira ver traduzidos deve mudar o seguinte:

echo (”mensagem”);  - deve ser mudado para echo _(”mensagem); ou echo gettext(”mensagem”);

A função _(”")  e gettext(”") são a mesma coisa, pela qual eu prefiro a primeira apenas pela sua simplicidade.

De notar que ao usar uma destas opções, caso ainda não tenha criado os respectivos ficheiros de tradução em nada muda o que vai aparecer na página, ou seja, se desde o inicio do seu projecto colocar as mensagens desta forma vai facilitar no final recolher todas as variáveis que tem de ser traduzidas.

No final do projecto, ou antes, para testar, a melhor forma de criar os seus ficheiros de tradução é usar o programa grátis PoEdit, que pode ser encontrado no seguinte link. O PoEdit pode ser usado em várias linguas, incluindo Portugues.

No seu programa PoEdit, crie um novo Catalogo. Preenchendo os dados da primeira janela tal como o exemplo abaixo, e não esquecendo de colocar a codificação em UTF-8, isto para que depois ao colocar as mesagens traduzidas no seu site elas não apareçam com aqueles caracteres malucos :)

Janelas Inicias PoEdit

Na 2ª opção, imagem á direita acima, escolha a pasta no seu PC onde está localizado o seu site. Assim, poderemos automaticamente detectar todos os termos que no nosso projecto colocamos com o _(”texto”); ou gettext(”texto”); e rapidamente criar o ficheiro base para tradução.

Agora basta carregar na opção de Actualizar (imagem abaixo) para que automaticamente sejam detectados todos os termos a traduzir.

Actualizar a partir da fonte

Depois de  actualizado é começar a fazer as traduções dos termos apresentados na lista.

Agora a parte melhor, que é a do código. Imaginando que usam um ficheiro de configuração para os vossos projectos que é carregado globalmente, com as configurações de base de dados, etc.. devem acrescentar o seguinte código:

// variável de lingua, exemplo $_GET["lingua"]
$locale = 'pt';
//onde vão ficar os ficheiros .po e . mo  a estrutura deve ser
//../lib/lang/pt/LC_MESSAGES/msg_pt.{po,mo} para portugues
//e ../lib/lang/es/LC_MESSAGES/msg_es.{po,mo}, para espanhol
//mas aqui apenas indicamos a pasta de origem
$locale_dir = '../lib/lang';
//indica qual o nome do fiheiro a carregar, eu fiz nomes diferentes,
//mas poderá usar o mesmo, visto que ficam em pastas diferentes.
$message="msg_".$locale;
//define a variavel com a lingua escolhida
putenv("LANGUAGE=$locale");

Esta secção apenas uso em modo de desenvolvimento, isto porque estes tipo de ficheiro/informação ficam em cache, e a unica forma, de depois de fazer uma alteração a ver é reiniciar o servidor apache, ou mudar os nomes dos ficheiros. Desta forma verificamos qual o ficheiro mais actual e temos sempre a informação actualziada. Depois de concluir, comente esta secção ou elimine-a.

// Caminho para o ficheiro
$filename = "$locale_dir/$locale/LC_MESSAGES/$message.mo";
$mtime = filemtime($filename); // verifica se houve modificações

// o nosso ficheiro unico
$filename_new = "$locale_dir/$locale/LC_MESSAGES/$message-$mtime.mo";

if (!file_exists($filename_new)) {  // verifica se já temos algum
// se não criamos a partir do original
copy($filename,$filename_new);
}
// mudamos para o novo ficheiro
$message = "$message-$mtime";
}

e por fim o resto do código

bindtextdomain($message, $locale_dir);
textdomain($message);
// manter esta codificação devido aos caracteres especiais
bind_textdomain_codeset($message, 'UTF-8');

E prontos, está feito. Espero que a informação vos seja útil.

0
Jun
30
2009

Compactar CSS em tempo de execução utilizando Php

Tags: ,

Há uns tempos atrás encontrei um pequeno código PHP para compactar o código CSS em tempo de execução, fazendo assim com que o site seja carregado mais rápido.

Primeiro deverá  renomear o seu ficheiro de css ex: (arquivo.css) para arquivo.css.php
ou seja alterar para a extensão .php

Agora onde “chama” ou faz o include desse ficheiro .css só tem de alterar para arquivo.css.php

Agora que é um ficheiro com a extensão “php”, insira na primeira linha o código:

<?php if(extension_loaded('zlib')){ob_start('ob_gzhandler');}
header("Content-type: text/css");
?>

Após isso, ir  para a última linha e insira o código:

<?php if(extension_loaded('zlib')){ob_end_flush();}?>

Feito isso, grave o seu arquivo e envie para o servidor, para ver o tamanho no carregamento.

Repare que se tentar  ver o tamanho pelas propriedades por exemplo, o tamanho será o mesmo, ele só irá compactar o ficheiro quando ele for requisitado no servidor.

0
Mai
28
2009

Importância de código HTML e CSS valido

Tags: , ,

Qual a importância de ter uma página com HTML (XHTML) e CSS válido?

Bem, existem várias razões para isto, em primeiro lugar, opinião pessoal, podemos  minimizar as diferenças entre navegadores, ou seja, sempre que criarem uma página testem abrir a mesma em vários navegadores, eu pessoalmente testo sempre, nos seguintes, Opera, Firefox, Safari, Chrome, Internet Explorer (várias versões existe um aplicativo que server para ter várias versões do IE no mesmo PC), desta forma garanto que independentemente do navegador que usa a página será mostrada da mesma forma, ou pelo menos, com uma margem de diferença muito pequena.

Lógico que ao fazer isto, acertar o código para vários navegadores, por vezes somos levados a colocar no código CSS alguns hacks para fazer este ou aquele efeito, mas que por sua vez falham na validação.

Então, porque validar a pagina em XHTML e CSS se corremos o risco de perder um efeito? Bem, pela minha experiência, há sempre forma de dar a volta à situação usando códifo válido, pode é dar mais trabalho, mas vale a pena. E isto porque, os nossos queridos motores de busca usam regras/técnicas de leitura do código das nossas páginas para fazerem as suas indexações, o que por sua vez, se encontrar erros como por exemplo tags mal fechadas pode  muito bem acontecer que a sua página não seja indexada, e o objectivo que qualquer programador ou webdesinger é exactamente o contrário que os motores de busca indexem as nossas páginas e o máximo de páginas para melhorar os resultados a nivel das pesquisas.

Embora esxistam muitas formas de fazer estas validações as que eu aconselho pessoalmente são:

Validar XHTML – http://validator.w3.org/

Validar CSS - http://jigsaw.w3.org/css-validator/

Claro que como mencionei existem mais ferramentas, mas independentemente de qual usa, teste no final da construção da sua página usar estas duas validações.

Como nota final, logicamente que um codigo XHTML e CSS válidos não são suficientes para uma boa indexação nos motores de busca, mas é uma das regras dos mesmos. Posteriormente falarei mais sobre o tema de SEO (Search Engine Optimization – Optimização para Motores de Busca) que é realmente um tema algo complexo e com muitas formas diferentes de dar maior relevância às nossas páginas nos motores de busca.

0
Mai
05
2009

Editor de Código Livre – Notepad ++

Tags: , ,

Bom dia,

Hoje venho aqui colocar uma sugestão de um bom editor para várias linguagens de programação, Notepad  ++.

Este editor funciona sobre o ambiente windows e alem de poder funcionar em várias linguas têm muitas ferramentas (plugins) que podem ser associados ao mesmo, é um editor muito rápido, ou antes, bastante leve e claro está o melhor de tudo é grátis.

Algumas das funcionalidades do mesmo:

Destaque de Sintaxes e Sintaxe de Blocos

WYSIWYG (O que você vê é o que você tem)

Destaque de Sintaxes Definida pelo Usuário

Auto completar

Múltiplos Documentos

Múltiplas Visualizações

Suporta Expressões de Busca/Substituição

Suporta o Arrastar e Soltar

Posição Dinâmica de Visualizações

Auto detecção de Estado do Arquivo

Avanço/Recuo de Zoom

Ambiente com Suporte a Múltiplos Idiomas

Marcadores

Chaves, Colchetes e Parênteses com Destaque

Grava e Reproduz Macros

Como mencionei acima, este utilitário pode ainda ser personalizado com temas e da minha experiência de trabalho com eles é sem dúvida uma óptima ferramenta.

Para poderem descarregar e testar o Notepad ++ podem visitar o seguinte link:  Notepad ++

0
Abr
28
2009

Função para criar um array de categorias em forma de árvore – parte 2

Tags: ,

Bem, em continuação do artigo anterior onde mostrei como preparar um array para a construção de uma árvore de categorias, coloco agora outra parte onde vamos, usando esse array, colocar todas as categorias na página, e nos seus devidos lugares.

Não vou usar qualquer tipo de CSS neste momento para poder facilitar a compreensão da função, e, depois cada um poder usar o CSS como entender.

Então cá vai.

Depois de criado o array com todas as categorias e respectivas sub-categorias, apenas é necessário criar um ‘ciclo for’ de forma a colocar tudo na pagina.

Sendo  que o array criado anteriormente era:

<?
$tree=tree_to_folders($cat_array, 0, "parent", "name", SORT_ASC);
?>

Pegamos agora neste array e fazemos o ciclo de impressão:

/*Função que vai recorrer o array para imprimir na pagina as categorias*/
function recorre($tree) {
echo "<ul>";
/*procura e recorre os nomes no nivel actual */

foreach ($tree as $id => $subarray) {
echo '<li>'.$subarray["name"];
/* Verifica se esta categoria tem subcategorias, se sim, chama novamente a função*/

if (sizeof($subarray["folders"])>=1) {
recorre($subarray["folders"]);
}
echo "</li>";
}
echo "</ul>";
}
/*chamamos a função para que inicie o processo*/
recorre($tree);

Penso que ao colocar assim, sem CSS será bastante simples de entender o resultado final, que seria por exemplo:

  • Categoria 1
    • Categoria 1.1
    • Categoria 1.2
      • Categoria 1.2.1
      • Categoria 1.2.2
    • Categoria 1.3
  • Catgoria 2
    • Categoria 2.1
  • Categoria 3

E por ai em diante.

Sem o CSS este será o aspecto real que vai aparecer na página, agora é uma questão de se aplicar alum CSS e algum JavaScript de forma a tornar a árvore mais bonita e apenas estar visivel inicialmente as categorias 0, ou seja, as categorias Pai e, mediante vamos clicando em cada uma mostrar ou ocultar as filhas.

Esta forma de fazer a árvore de categorias, como mencionei antes, tem como objectivo, que no código fonte da página já estejam lá todas as categorias, o que para os motores de busca é optimo porque teremos em vez de 10 categorias (as principais), teremos todas as categorias listadas na página, apenas ocultas por CSS.

2
Abr
24
2009

Função para criar um array de categorias em forma de árvore

Tags: ,

Bem, cá vai a primeira dica para o blog :)

Há alguns meses pediram-me para rever uma função que tinha como objectivo criar uma lista de categorias em árvore, a função até nem estava muito mal, quando apenas existia Pais e Filhos, ou seja 2 niveis de categorias. O problema era quando se inseria um 3º nivel, ou mais.

Bem apos uns dias de teste e analise consegui melhor a funçã0, com uma tabela de teste com 771 categorias a função demorava por volta de 0.51 segundos, como disse até nem esta mau, mas se pensarmos em aumentar isto para 5000 categorias, seria complicado.

Logico que poderiamos fazer isto doutra forma, atraves de ajax por exemplo, carregando as filhas apenas quando se clicasse nos pais. Mas o que se pretendia era que toda a arvore fosse carregada de inicio (objectico indexação de palavras para o google), e depois atraves de CSS ir mostrando e ocultando as filhas.

Como disse ao fim de alguns dias, reduzi a função e o resultado para 0.0016 segundos.

Aqui fica a função, ou melhor as funções. Os comentários estão em ingles mas isso não deve ser problema:

1º passo, fazer o select á base de dados e criar um array com as categorias. Esta tabela é constituida pelos seguintes campos:

id – incremental, chave primaria

parent- campo inteiro, onde guardamos qual a categoria pai

name – nome da categoria

<?php
$cat_array = build_tree('categories', 'id, name, parent', 'parent ASC, name ASC', 'id');
?>

Abaixo está a função build_tree, com os devidos comentários e explicações.

<?php
/**
* Function build_tree($table, $fields, $fields_order, $master='id')
*
* OVERVIEW: Create a MultiDimensional Array with the data off a table
*
* RETURNS: Returns a unique array with all the values
*
* EXAMPLE: $tree=build_tree('categories', 'id, name, parent_id' , 'parent_id asc, name asc', 'id');
*
* @param string $table name to the database table
* @param string $fields name(s) for the table fields to get
* @param string $fields_order  sql order condition
* @param string $master name to the table unique key field, usualy id (optional if id is primary key value and unique)
*/
function build_tree($table, $fields, $fields_order, $master='id') {
/* check if fields order is set, if not set 1st field as asc order by*/

if ($fields_order=='') {
$temp=explode(',' ,$fields);
$fields_order = $temp[0].' asc';
}
/* build the query */
$query=mysql_query('select '.$fields.' from '.$table.' order by '.$fields_order);
/* read the query  and build the array */

while ($result=mysql_fetch_assoc($query)) {
/* $result[$master] is the unique key value  */
$tree[$result[$master]]=$result;
}
/* return the array */

return $tree;
}
?>

2º passo, chamar a função que vai criar o array com a estrutura pais, filhos, netos, etc., usando logicamente o array criado acima, $cat_array

<?php
$tree=tree_to_folders($cat_array, 0, 'parent', 'name', SORT_ASC);
?>

Aqui está a função, para converter em árvore e a respectiva ordenação:

<?php
/**
* Function tree_to_folders($tree, $root, $parent_var='parent', $order='id', $order_val=SORT_ASC)
*
* OVERVIEW: Create array with the a category tree or a map tree
*
* RETURNS: Returns a unique array with the tree information
*
* EXAMPLE: $links=tree_to_folders($tree, '0', 'parent', 'name', SORT_DESC);
*
* @param array $tree pre build tree array
* @param string/integer $root id from the master parent we want to design the tree
* @param string $parent_var name to the parent field on the array (optional - default value "padre")
* @param string $order name on the field on the array to make the order (optional - defalut value "id")
* @param string $order_val type or order we whant SORT_ASC/SORT_DESC (optional default value "SORT_ASC")
*/
function tree_to_folders($tree, $root, $parent_var='parent', $order='id', $order_val=SORT_ASC) {

foreach ($tree as $id => $subarray) {

if ($subarray[$parent_var] != $root) {

if (isset($tree_result[$subarray[$parent_var]])) {
$tree_result[$subarray[$parent_var]]['folders'][$subarray['id']]=$tree[$id];
} else {
$flag=0;
$valid=$id;
$var='';

while ($flag==0) {

if (isset($tree[$valid])) {

if ($tree[$valid][$parent_var]!='0' ) {
$var="['folders']['". $tree[$valid]['id']."']".$var;
} else {
$var='["'. $tree[$valid]['id'] .'"]'.$var;
$flag=1;
}
$valid=$tree[$valid][$parent_var];
} else {
$flag=1;
}
}
$var='$tree_result'.$var.'=$tree[$id];';
eval($var);
}
} else {
$tree_result[$tree[$id]['id']]=$tree[$id];
}
}
$tree_result=order_tree($tree_result,$order, $order_val);

return $tree_result;
}
function order_tree($tree, $order, $order_val ){

foreach ($tree as $key => $row) {
$ordered[$key] = $row[$order];

if (isset($tree[$key]["folders"])) {
$tree[$key]['folders']=order_tree($tree[$key]['folders'], $order, $order_val);
}
}
array_multisort($ordered, $order_val, $tree);

return $tree;
}

Agora seria apenas necessário fazer um ciclo para mostrar as categorias, mas isso fica para outro dia :)

0
Abr
24
2009

Bem vindo

Olá, neste blog vamos tentar reunir informação útil acerca da temática programação.

Provavelmente vamos focar os temas em linguagens de programação que estejam ligadas com a Internet, isto porque, opinião pessoal, é para onde desde já há algum tempo mais pessoas se estão a focar e a direccionar todas as atenções.

O meu nome é Henrique Barquero, e trabalho na área de programação há mais de 15 anos, não me considero um expert, mas sim um entusiasta da área, visto que é dela que vivo :) .

Além de ser o responsável principal pela criação da plataforma http://maistemas.com, tenho centenas de sites criados por mim, tenho dezenas de estruturas para quase todos os tipos de sites, e actualmente estou a desenvolver uma plataforma para uma empresa de formação online que é sem margem de dúvida o mair desafio que já tive até hoje, principalmente quando se esta a desenvolver esta plataforma do zero e sozinho.

Bem já chega de me gabar :) vou tentar colocar neste blog o máximo de informação possível relacionada com esta temática e espero que posso servir de ajuda aos interessados pela área.

Nota: Se gostava de fazer parte deste blog, e poder juntar-se a mim escrevendo sobre esta temática, visite o site http://maistemas.com leia a informação da página inicial e candidate-se a autor na página Autores.

0