Cloud programmers

O conceito de programador em nuvem (em inglês, cloud programmer) refere-se à utilização total da memória e das capacidades de raciocínio de um programador por meio de todos os meios de comunicações que estiverem disponíveis para abrir demandas.

O programador em nuvem pode ser acionado de qualquer lugar do mundo, a qualquer hora. Não há necessidade do programador comparecer a um local de trabalho, porque qualquer lugar onde ele possa conectar seu notebook e pegar sinal de celular é um local de trabalho. Você pode abrir demandas para o programador em nuvem remotamente, através da Internet, usando e-mail, mensageria instantânea, Skype, ou qualquer outro programa

O programador em nuvem tem elasticidade. Ele é capaz de aumentar a sua capacidade de resolver problemas de acordo com o aumento da demanda.

O programador em nuvem é multitarefa: ele trabalha em vários projetos simultaneamente. Ele usa várias janelas no seu desktop e vários monitores ao mesmo tempo. Ele codifica usando as mãos, os pés, a voz e os olhos. Enquanto ele desenvolve, atende ao telefone, participa de reuniões, faz relatórios e presta consultoria.

O programador em nuvem é 24X7. Não existe distinção entre vida profissional e vida social. Aliás, não existe vida social. Todos os recursos devem ser direcionados para o atendimento de demandas.

Você não precisa de mais programadores. Basta abrir as demandas para o programador em nuvem e ele automaticamente irá expandir o tempo para terminar dez demandas no período em que ele não conseguiria nem atender a uma.

O programador em nuvem está em algum local elevado, onde não existe necessidade de comida, lazer ou qualquer coisa mundana. Só precisa de um suprimento de oxigênio para o cérebro funcionar.

O programador em nuvem é onipresente. Envolva ele em quantos compromissos você quiser, agende quantas reuniões você precisar. Ele conseguirá tempo infinito para participar de todas as atividades dispensáveis e ainda fazer o seu trabalho.

Publicado em Humor | Com a tag , , , , , | Deixar um comentário

Construção de software – primeira parte

Em 1998, a Pirelli, empresa italiana que fabrica de pneus a cabos de aço e de fibras óticas a robôs, lançou um slogan: Potência não é nada sem controle. No campo automobilístico, podemos resumir qual o significado dessa frase ao pensarmos nas cenas de filme de carros em alta velocidade chegando próximos à ribanceiras e se salvando de quedas mortais por poucos centímetros.

Um carro é um produto de engenharia. Há um processo bem definido e controlado para construí-lo. É possível estimar com grande segurança o tempo e o custo necessários para fabricá-lo.

O software nasceu pelas mãos de matemáticos, físicos e engenheiros. A computação já existia antes de existirem os computadores como nós conhecemos hoje, que na verdade constituem apenas um tipo de computador específico: o computador eletrônico. Cada um desses grupos contribuiu na criação de software com aquilo que conhecia. Os engenheiros tentaram aplicar ao software o mesmo processo utilizado na construção de produtos tangíveis: aí nasceu a Engenharia de Software.

Mas o software é muito diferente de um produto ordinário de engenharia. Philippe Kruchten [1] afirma que o software apresenta quatro características diferenciais:

  • Ausência de uma teoria fundamental
  • Facilidade de mudança
  • Evolução rápida de tecnologias
  • Baixo custo de manufatura

A facilidade de mudança e o baixo custo de manufatura podem dar a impressão de que o software é muito fácil de construir do que qualquer produto de engenharia, então os processos de engenharia aplicados ao software darão muito mais resultado do que os aplicados a produtos tangíveis. Ledo engano.

Enquanto não padece dos males dos produtos tangíveis, o software apresenta muito mais complexidade do que eles. É incrível ver hoje como o software era desprezado pelas grandes empresas no final da década de 70. O desprezo pela importância do software tornou possível a ascensão meteórica da Apple e da Microsoft, que começaram seus negócios sem sequer ter o que vender.

Em artigo apresentado em 1972, ao receber o Turing Award, o pioneiro da programação de computadores Edsger Djikstra [2] já apontava para a complexidade do trabalho do programador:

“Mas eu chamei a essa uma causa menor; a causa maior é… que as máquinas se tornaram várias ordens de magnitude mais poderosas! Colocando de uma forma brusca: enquanto não haviam as máquinas a programação não era problema; quando passamos a ter poucos e pequenos computadores a programação tornou-se um problema moderado, e agora que temos computadores gigantescos a programação passou a ser um problema igualmente gigantesco. Nesse sentido a indústria eletrônica não resolveu um único problema; ela criou problemas – ela criou o problema de como usar seus produtos. Em outras palavras: tão logo a potência das máquinas disponíveis cresceu por um fator maior que mil, a ambição da sociedade em aplicar essas máquinas cresceu em proporção, e o pobre programador acabou se situando nesse campo explosivo de tensão entre fins e meios.”

Veja, ele diz que a programação se tornou um problema gigantesco. Só que nesse trecho do artigo ele estava se referindo aos anos 50 do século XX!

Em outro trecho, Djikstra fala sobre a importância da legibilidade de programas. Esse foi o tema do meu trabalho de graduação, inclusive. No livro Refatoração : Aperfeiçoando o Projeto de Código Existente, de Martin Fowler e Kent Beck, há uma frase que adoro: “Qualquer tolo pode escrever um código que um computador entenda. Bons programadores escrevem código que humanos podem entender”. Logo abaixo você vê que Djikstra concorda totalmente com isso:

“O programador competente é plenamente consciente do tamanho estritamente limitado de sua própria cabeça; portanto ele aborda a tarefa programação com muita humildade e dentre outras coisas ele evita como a praga os truques astutos. No caso de uma conhecida linguagem conversacional, eu tenho dito que tão logo a comunidade é equipada com o terminal, um fenômeno específico ocorre, cujo nome é bem estabelecido; é chamado “uma linha”. Tal fenômeno assume duas formas: um programador coloca um programa de uma linha na mesa de outro e diz orgulhosamente o que o programa faz acrescentando ‘você consegue codificá-lo com menos símbolos?’ ─ como se isso fosse de alguma relevância conceitual ─ ou diz apenas: ‘adivinhe o que ele faz!’. Dessa observação temos de concluir que essa linguagem, como ferramenta, é um convite aberto aos truques astutos; embora seja precisamente isso que explicaria seu atrativo, isto é, para aqueles que gostam de mostrar quão inteligentes são, considero uma das coisas mais condenáveis que podem ser ditas a respeito de uma linguagem de programação.”

É muito legal perceber que você consegue fazer com 1 linha de código o equivalente a 5 ou 10 linhas. Também é legal saber que você pode otimizar a execução de determinado trecho de código em 0,1s. Mas os respectivos problemas são: de nada adianta ter uma só linha de código que ninguém entende; não adianta fazer algo pontual mais rápido se o custo disso não afetar o conjunto da aplicação.

Compreender o software é muito importante para controlá-lo. O controle está ligado a manutenção do software, que é uma atividade que custa muito mais caro do que o seu desenvolvimento. Por isso que o desenvolvimento em um bom projeto e uma boa arquitetura implicam na redução de custo de manutenção. Quanto mais flexível e legível for o o seu software, mais fácil será acrescentar e alterar funcionalidades nele.

Potência não é nada sem controle. Se faltar alguma imagem à sua mente, assista ao desenho Carros da Pixar quando Doc Hudson desafia o Relâmpago McQueen para uma corrida onde tem uma curva na estrada.

[1] http://www.ibm.com/developerworks/rational/library/4700.html
[2] https://sites.google.com/a/integra.ufjf.br/professor-joao-carlos/t10.doc?attredirects=0

Publicado em Engenharia de Software | Com a tag , , , , | Deixar um comentário

PHP Conference Brasil 2011 – entrevistas em vídeo

Não foi na PHP Conference Brasil 2011? Não sabe o que perdeu. Vê se não perde a próxima edição!

Se quiser um pouco sobre o evento, assista a algumas entrevistas com membros de destaque da comunidade, na maioria palestrantes e instrutores no evento, e um autor de livros.

Publicado em Eventos, PHP | Com a tag , , , , , , , , | Deixar um comentário

Mão na Massa Zend Framework na PHP Conference Brasil 2011

PHP Conference Brasil

Como já ocorreu em edições anteriores, haverá cursos Mão na Massa na PHP Conference Brasil 2011. Um deles é o de Zend Framework MVC, ministrado por mim mesmo.

Eu também irei proferir quatro palestras no evento:

Como a PHP Conference é um momento muito especial no ano, sortearei alguns brindes em minhas palestras. Mas não esperem iPhones ou Macs. Talvez um modem wireless e clássicos dos quadrinhos.

Publicado em Eventos, PHP | Com a tag , , , , , | Deixar um comentário

PHP com Zend Framework e Javascript com Dojo Toolkit no SOLISC

Participarei do 6º Congresso Catarinense de Software Livre, nos dias 21 e 22 de outubro, na cidade de São José, Santa Catarina.

No dia 21, às 11h, darei a primeira palestra da Sala 1, intitulada Zend Framework, Componentes Poderosos para PHP.

Das 14h às 18h farei o workshop PHP Profissional, na Sala 4.

No dia 22, às 15h, darei a palestra Desenvolvendo com Dojo Toolkit, na Sala 3.

6º Congresso Catarinense de Software Livre

6º Congresso Catarinense de Software Livre

Publicado em Eventos, Javascript, PHP | Com a tag | Deixar um comentário

Palestra de Programação Orientada a Aspectos em PHP na Latinoware

Este ano terei o imenso prazer de dar a primeira palestra no COLAPHP (Congresso Latino Americano de PHP), que ocorre dentro da Latinoware 2011. O tema é Programação Orientada a Aspectos em PHP.

VIII Conferência Latino Americana de Software Livre

VIII Conferência Latino Americana de Software Livre

A VIII Latinoware (Conferência Latino Americana de Software Livre) ocorre no Parque Tecnológico Itaipu, em Foz do Iguaçu, de 19 a 21 de outubro. Minha palestra será no dia 19, às 11h, no Espaço Bolívia. Uma hora antes, no Espaço Brasil, o criador do PHP, Rasmus Lerdorf falará sobre o PHP em 2011.

Aliás, vai ter muito PHP na Latinoware. Veja só o que mais acontece no Espaço Bolívia:

No dia 19,

  • às 12h, Jota Júnior falará sobre PHP nas mídias sociais. Ele nem deve falar do Facebook…
  • às 13h, Gilmar Pupo falará sobre Integração Contínua em PHP com Jenkins.
  • às 16h, Ivo Nascimento falará sobre Processamento de Linguagem Natural com PHP.
  • às 17h, Alexandre Gaigalas falará sobre testes em PHP com uma palestra intitulada assertTrue($tdd)

No dia 20,

  • às 14h, Flávio Ricardo Bazana Meira dará a palestra CMS em PHP: essa briga ainda existe?
  • às 15h, Otávio Calaça Xavier ministrará a palestra Integrando a Web Social e a Web Semântica com PHP

No dia 21,

  • às 10h, Er Abott Galvão irá Além da Autenticação e falará sobre Permissões de Acesso com Zend Framework
  • às 11h, César Rodas falará sobre Programación Asíncrona (Introducción a NodeJS)

E no Espaço Brasil, onde o Rasmus abrirá o evento (sim ELE abre a Latinoware), ainda haverá, durante os três dias, palestras sobre Drupal, CMS escrito em PHP. Sem contar as palestras sobre Zabbix e Expresso, respectivamente sistemas de monitoramento e correio eletrônico em PHP.

Que o PHP esteja com vocês!

Publicado em Eventos, PHP | Com a tag , , | Deixar um comentário

Usando Smarty 3 com Zend Framework 1.11

No último treinamento de Zend Framework que ministrei, um dos alunos perguntou como seria possível usar o Smarty junto com o Zend Framework. O melhor jeito de responder, na minha opinião, era mostrar como se fazia. Então fizemos um exercício, no último dia de aula, mostrando UMA das formas possíveis de se usar Smarty como a camada de visão em uma aplicação Zend Framework, no lugar de Zend_View.

Criamos um projeto PHP chamado exercício. Um projeto PHP nada mais é do que uma pasta ou diretório, contendo arquivos, dentre os quais estão os de extensão .php. Transformamos esse projeto em um projeto Zend Framework seguindo os seguintes passos:

1) Criando o projeto
Executamos o Zend Tool para criar a estrutura MVC do projeto. Se você baixar o Zend Framework 1.11, pode fazer isso executando o comando no diretório do projeto:

php[.exe se for Windows] [diretório do Zend]/bin/zf.php create project [nome do projeto]

Isso cria a estrutura do projeto.

2) Habilitando a reescrita de URL
A camada de controle do Zend precisa do módulo rewrite do Apache. Verifique se esse módulo está carregado no arquivo httpd.conf. Se estiver, você precisa decidir por uma das duas formas de direcionar o processamento para o arquivo index.php que está no diretório public.

2.1) Virtual host
A primeira é usar um virtual host, criando uma configuração de diretórios no arquivo httpd.conf similar a este modelo:


ServerName exercicio.local
DocumentRoot /path/to/exercicio/public

SetEnv APPLICATION_ENV "development"


DirectoryIndex index.php
AllowOverride All
Order allow,deny
Allow from all


2.2) .htaccess na raiz do projeto
A segunda é copiar o arquivo .htaccess que está no diretório public para o diretório raiz do projeto, mas acrescentando “public/” à esquerda do arquivo “index.php”. Mas para isso, o diretório do projeto tem de ser afetado pela diretiva AllowOverride All, para que o arquivo .htaccess possa ser lido. Neste caso, é necessário adicionar uma linha no arquivo application.ini, configurando o atributo baseUrl da instância única de Zend_Controller_Front. No exemplo da aplicação “exercicio”, essa linha é a seguinte:

resources.frontController.baseUrl = /exercicio

3) Adicionando o framework
A pasta library do projeto deve conter a pasta Zend do framework, ou ter um link simbólico para ela.

4) Criando uma biblioteca para estender o Zend
Para encapsular o Smarty como camada de visão da aplicação, iremos criar uma biblioteca no padrão Zend Framework e personalizar o controlador, que passará a usar um objeto de visão diferente.
Como na edição deste post o assunto mais falado era a morte de Steve Jobs, criamos uma biblioteca chamada Jobs, dentro da pasta library.

Dentro dessa biblioteca, criamos uma classe customizada de visão, que encapsula o Smarty 3.

A estrutura é a seguinte:

library
->Jobs
–>View
–>View.php

O arquivo View.php contém o seguinte código:


define('SMARTY_DIR',realpath(__DIR__) . '/View/libs/');

require_once 'View/libs/Smarty.class.php';

class Jobs_View extends Zend_View_Abstract
{
private $_smarty = null;

public function __construct($config = array())
{
parent::__construct($config);
$this->_smarty = new Smarty();
$this->_smarty->setCompileDir(SMARTY_DIR . 'compile');
$this->_smarty->setConfigDir(SMARTY_DIR . 'config');
$this->_smarty->setCacheDir(SMARTY_DIR . 'cache');
}

public function assign($spec,$value = null)
{
$this->_smarty->assign($spec,$value);
}

public function setController($controller)
{
$this->_smarty->setTemplateDir(APPLICATION_PATH . DIRECTORY_SEPARATOR . 'views' . DIRECTORY_SEPARATOR . 'scripts' . DIRECTORY_SEPARATOR . $controller . DIRECTORY_SEPARATOR);
}

public function render($name)
{
$name .= '.tpl';

return $this->_smarty->fetch($name);
}

protected function _run() {}
}

A pasta View contém a biblioteca do Smarty. Baixamos a versão 3.1.3 do Smarty de http://www.smarty.net/download e copiamos a pasta libs para dentro da pasta View.

Este componente foi criado para substituir o Zend_View. Mas dentro da aplicação, isso só tem efeito se o controlador substituir o atributo $this->view por um objeto da classe Jobs_View.

Então o segundo passo foi criar um controlador personalizado.

A estrutura da biblioteca Jobs ficou assim então:

library
->Jobs
–>Controller
—>Action.php
–>View
View.php

O arquivo Action.php contém a seguinte classe:


class Jobs_Controller_Action extends Zend_Controller_Action
{
public function init()
{
/* Initialize action controller here */
$this->view = new Jobs_View();
}

public function postDispatch()
{
$this->view->setController($this->getRequest()->getControllerName());
echo $this->view->render($this->getRequest()->getActionName());
exit;
}
}

5) Usando a biblioteca Jobs
Para usar essa biblioteca, temos que registrar o namespace “Jobs”. Então criamos uma função na classe Bootstrap para isso:


public function _initApp()
{
Zend_Loader_Autoloader::getInstance()->registerNamespace('Jobs');
}

Implementamos o seguinte IndexController, em application/controllers:


class IndexController extends Jobs_Controller_Action
{

public function indexAction()
{
$this->view->assign('mensagem','Alô Mundo');
}
}

Na pasta application/views/scripts/index criamos o arquivo index.tpl, com o seguinte conteúdo:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Strict//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
{$mensagem}
</body>
</html>

Se você chamar o URL http://localhost/exercicio, deverá ver a frase “Alô Mundo”.

Bem, esse foi apenas um exercício. A biblioteca Jobs tem de ser melhorada para considerar o uso de módulos e layout. Mas isso é outra história.

Publicado em PHP | Com a tag , , , | Deixar um comentário

Humor Nerd – Executando Programas

Bitman e os Seres Virtuais - Executando um Programa

Bitman e os Seres Virtuais - Executando um Programa

Publicado em Humor, Quadrinhos | Com a tag , | Deixar um comentário

Meus comentários sobre Lanterna Verde, o filme

NÃO LEIA ESTE ARTIGO SE PRETENDE ASSISTIR LANTERNA VERDE NO CINEMA, POIS CONTÉM SPOILERS. EU NÃO SEI O QUE É UM SPOILER, MAS SE VOCÊ SOUBER, FICA AVISADO.

Como fã do Lanterna Verde, eu não posso me abster de fazer meus comentários sobre o filme produzido pela Warner, após quase um mês de sua estreia no Brasil.

Ryan Reynolds como Lanterna Verde

Ryan Reynolds como Lanterna Verde

Bem, quando fui ao cinema, eu já sabia do fracasso do filme nas bilheterias norte-americanas. Ele começou na frente dos demais lançamentos, mas com valor inferior ao esperado pelo estúdio e ao arrecadado por outros filmes de super-heróis.

O filme é tão ruim assim?

Eu não achei. Até agora, na verdade, eu não entendi o que esperavam desse filme.

O filme conta a origem do Lanterna Verde. Em um filme de origem, como Homem-Aranha 1 e Batman Begins, o herói só vai aparecer caracterizado quase na metade do filme. Então acho que não dá pra querer ação desenfreada desde o começo.

Eu li que muitos criticaram a falta de explicação sobre porque o Hal tinha coragem de pilotar aviões até o limite deles e tinha medo de ejetar seu assento para se salvar. Bem, existe um flashback que mostra o motivo, mas pra quem não presta atenção no filme, e fica só comendo pipoca e conversando, não dá pra entender mesmo.

Outras críticas falam que Hal sai de Oa e volta pra Terra sem explicação. Mas que explicação queriam? Ele teve um treinamento básico, com Tomar-Re e Kilowog. Depois o Sinestro deixou claro que arrancaria o anel de seu dedo se pudesse, que ele não era bem vindo. Ele ia ficar em Oa fazendo O QUÊ?

Criticaram a escolha do Parallax como vilão. Eu me regozijei. Eu me senti vingado. Nos terríveis anos 90 do século XX, para alavancar as vendas, a DC Comics foi até as últimas consequências com seus personagens. Ela matou o Superman. Aleijou o Batman. Piranhas comeram a mão do Aquaman. O Arqueiro Verde explodiu com a mão presa em uma avião. E o Lanterna Verde… Hal Jordan… o mais destemido… o primeiro e único… enlouqueceu, massacrou a Tropa, matou o Sinestro, sugou a energia da Bateria Central, causou a morte de quase todos os guardiões e tentou destruir o universo pra criar e de novo. Esta história se chamou Crepúsculo Esmeralda e, para mim, foi uma das piores que já criaram até hoje.

Emerald Twilight

Emerald Twilight

Transformaram meu super-herói em vilão! Hal Jordan agora era Parallax, e estava disposto a matar quem fosse preciso pra fazer um universo perfeito. Seu melhor amigo, o ainda vivo Arqueiro Verde, o deteve com uma flecha.

Depois disso, Jordan tentou voltar a ser Lanterna Verde. A qualquer custo. Tentou arrancar o anel de Kyle Rayner, escolhido como seu sucessor. Os heróis não o aceitaram de volta.

Para se redimir, Jordan morreu lutando contra a entidade conhecida como Devorador de Sóis. E assim, após vários atos inglórios, o eterno Lanterna Verde da Era de Prata se despedia.

Algum tempo depois, Hal Jordan volta… não à vida, mas à ação. O espírito de Jim Corrigan se liberta finalmente de sua sina de Espectro e Hal se torna o novo Anjo Vingador. Não fazia sentido, pois o Espectro é alguém que morre assassinado, e castiga aqueles que assim são mortos. Hal não foi assassinado.

Hal Jordan como Espectro

Hal Jordan como Espectro

Bem, o coitado do Hal tem que perambular como alma penada até que a DC resolve consertar a besteira que fez. Mas, e agora? Como trazer alguém da morte? Que desculpa inventar?

Num arroubo de imaginação, inventaram uma série de coisas, entre elas:

  • O corpo de Hal estava preservado dentro do sol. Como?!
  • Dentro da bateria energética havia uma criatura chamada Parallax. Como Hal entrou na bateria mais de uma vez (pelo menos segundo as histórias Amanhecer Esmeralda e Lanterna Verde: Mundo Surreal), essa entidade se apossou dele. Conforme ele passou por momentos difíceis, a entidade foi tomando conta de sua mente, até que surgiu o momento de maior fragilidade: a destruição de Coast City por Mongul, clássico antagonista do Superman.

A explicação era esta: não foi Hal quem promoveu o massacre da Tropa e quem quase destruiu o universo. Foi Parallax, usando o corpo de Hal. Quando Hal, ainda possuído, enfrentou o Devorador de Sóis, o Espectro tomou sua alma, junto com a essência de Parallax, para tentar separá-los. Quando o Espectro conseguiu separar os dois, Hal voltou para seu corpo e o primeiro Lanterna Verde do setor 2814 voltou à ativa.

Que desculpa mais horrível! E o pior é que Parallax volta depois, e se apossa de Kyle Rayner, na Guerra da Tropa Sinestro (Guerra dos Anéis no Brasil).

O lado bom foi que Hal Jordan voltou, com bons roteiros e a arte fantástica de Ivan Reis. Grandes sagas se sucederam, como a Guerra das Luzes, A Noite Mais Densa e o Dia Mais Claro.

Eu odeio o que fizeram com Hal Jordan e odeio Parallax. A maneira como ele é derrotado no filme é uma referência ao modo como o Devorador de Sóis é derrotado. Agora, sim, no filme achei fantástico isso! A derrota de Parallax, me pareceu uma mensagem “vamos enterrar essa bobagem que criamos”. Mesmo a origem do Parallax, no filme, tem muito mais sentido do que nos quadrinhos.

Bem, eu me estendi bastante. A questão é que o núcleo da história do Lanterna Verde, em si, é simples: é o triunfo da força de vontade sobre o medo. O medo coíbe a força de vontade, por isso, para dominar completamente o poder do anel, seu usuário não pode ter medo.

Mas isso é algo muito estranho e complexo. Força de vontade é fé, e é difícil ter fé. Uma mensagem que fica clara no filme é o fato dos Guardiões e da Tropa deixarem Hal sozinho, recusando-se a ajudá-lo a salvar a Terra.

Hal Jordan fazendo o juramento

Hal Jordan fazendo o juramento

E é assim que ocorre com quem tem como poder apenas sua fé. Quando você mais precisar, ninguém vai te ajudar. Ninguém vai vir te salvar. Você está sozinho, como um agente secreto quando é capturado.

Agora, quando, contra todas as possibilidades, você obter êxito sem ter recursos suficientes, sem ter chance, fazendo algo quase impossível, tenha certeza de que será como no filme: aqueles de quem você precisava antes vão aparecer para lhe cumprimentar.

Este é o caminho do herói.

Publicado em Cinema, Quadrinhos | Com a tag , , , | Deixar um comentário

I Encontro Regional de Computação – Compweek

Depois de um dia claro, e numa noite nada densa, em 14 de setembro, participantes da CompWeek estiveram na minha presença.

I Encontro Regional de Computação - Compweek

I Encontro Regional de Computação - Compweek

Publicado em Eventos, PHP | Com a tag , , , , | Deixar um comentário