Filed under php

Usando Vagrant para criar máquinas virtuais para desenvolvimento e testes

Recentemente trabalhei em um projeto grande, com equipes trabalhando remotamente, cada desenvolvedor usando o seu ambiente favorito para trabalhar (Linux, MacOS X e Windows) e o sistema tendo diversos requisitos (PHP, MySQL, Memcached, Solr, PHPUnit, etc). Era comum acontecerem problemas como “na minha máquina todos os testes funcionam, mas na máquina de fulano, que roda Windows não” ou “temos um novo programador na equipe, precisamos instalar todos os requisitos para ele começar a trabalhar”. Para resolver este tipo de problemas uma solução é usarmos máquinas virtuais, com todos os requisitos já instalados e prontos para uso. O VMWare e o VirtualBox são exemplos interessantes para estes casos, mas ainda assim exigem um pouco de trabalho para configurar e instalar tudo. O Vagrant é uma ferramenta que auxilia exatamente neste quesito, a criação das máquinas virtuais.
O Vagrant roda em Windows, Linux e MacOS X (onde eu fiz os testes que apresento nesse post) e necessita do VirtualBox para funcionar. Neste post vou descrever os passos que fizemos na Coderockr para criarmos máquinas virtuais Ubuntu dentro de nossos MacOS X.
O primeiro passo é fazer o download do Vagrant no link http://downloads.vagrantup.com/tags/v1.0.2
Depois precisamos fazer o download da máquina virtual “base” que será usada para gerar as máquinas para cada projeto, com o comando

vagrant box add base http://files.vagrantup.com/lucid32.box

Um arquivo de 260M é copiado para o diretório .vagrant.d de seu home (/Users/eminetto/.vagrant.d no meu caso). É uma imagem do VirtualBox com o sistema Ubuntu 10.04.

Agora vamos criar o nosso primeiro projeto. Eu criei um diretório:

mkdir ~/Projects/vagrant

E dentro deste diretório devemos executar o comando

vagrant init 

É criado um arquivo chamado Vagrantfile que é a configuração da sua máquina virtual
Vamos alterar o arquivo e alterar a linha abaixo, que indica qual é nossa VM original.

config.vm.box = "base"

Se inicializarmos a máquina neste momento ela será criada com o sistema Ubuntu “zerado”, sem nenhum pacote adicional, o que não é muito útil para nossa necessidade. Vamos usar uma ferramenta chamada Puppet (também é possível usar a ferramenta Chef) para automatizar o processo de instalação dos pacotes necessários.
Para instalar o Puppet é necessário o interpretador da linguagem Ruby, que já vem instalado no MacOS X e na maioria dos sistemas Linux atuais (ou pode ser instalado usando o apt-get ou yum, dependendo da distribuição). Vamos executar o comando:

sudo gem install puppet

Agora precisamos criar um arquivo de configuração para o Puppet. No diretório do projeto (~/Projects/vagrant) vamos criar o diretório manifests:

mkdir manifests

e o arquivo manifests/base.php, cujo conteúdo está no link https://gist.github.com/2288198
Neste arquivo definimos os comandos que queremos executar (exec), os pacotes que devem ser instalados (package) e os serviços que devem ser inicializados (service).
Precisamos também configurar o arquivo Vagrantfile para que ele execute o Puppet:

config.vm.provision :puppet do |puppet|
    puppet.manifests_path = "manifests"
    puppet.manifest_file  = "base.pp"
end

Agora basta criar a máquina virtual, com o comando

vagrant up

A primeira vez deve demorar alguns minutos, pois a máquina “base” é clonada e o Puppet é executado para instalar os pacotes que indicamos

Para acessar o Apache instalado na máquina virtual é só acessar a url http://127.0.0.1:8080 e para acessar o SSH basta executar

vagrant ssh

Quando precisar desligar a máquina é só executar

vagrant halt

e para inicializar novamente basta um

vagrant up

Caso queira remover a máquina e recriá-la o comando é

vagrant destroy

E repetir o processo anterior.

Também é possível compartilhar a máquina criada com o restante da equipe, como mostra a documentação oficial

O Vagrant facilita bastante o processo de criação do ambiente de desenvolvimento, e trás diversas vantagens, tanto para um programador solo (poder separar o ambiente de desenvolvimento da máquina real, ter vários ambientes distintos, para os diversos projetos) quanto para equipes (poder facilmente instalar novas máquinas e ter o mesmo ambiente de desenvolvimento em todas as máquinas da equipe).

Snippet do Sublime Text 2 para gerar getters e setters em PHP

Aqui entre nós… Escrever as funções de get() e set() para cada atributo de uma classe é uma daquelas tarefas repetitivas e chatas. Seguindo o conceito de DRY eu fiz uma pesquisa para encontrar alguma forma de gerar isso de maneira mais fácil, usando o meu editor de programação favorito, o Sublime Text 2.
Para resolver isso basta escolher a função Tools->New Snippet e substituir o texto pelo novo snippet

Depois de salvar o arquivo com o nome getset.sublime-snippet está pronto para uso.
Para demonstrar eu criei um pequeno video

Fonte

Usando componentes do Zend Framework

Uma das coisas mais legais do Zend Framework é a forma como ele foi construído, na forma de componentes que podem ser usados separadamente ou até substituídos. Dessa forma é possível usar somente alguns componentes em qualquer projeto, desenvolvido com outros frameworks ou mesmo sem nenhum. Exemplos de componentes que podem ser bem úteis:

- Zend_Mail
- Zend_Cache
- Zend_Db
- Zend_Config
- Zend_Date
- Zend_Log

Entre outros.
Um exemplo bem simples, usando o Zend_Cache:

<?php
//include do zend framework
$includePath  = get_include_path();
//o : é o separador de diretórios no Unix. No Windows seria ;
$includePath .= ':/var/www/html/library/';
set_include_path($includePath);

//inicia o autoloader, responsável por incluir os arquivos dos componentes
require_once 'Zend/Loader/Autoloader.php';
$autoloader = Zend_Loader_Autoloader::getInstance();
$autoloader->setFallbackAutoloader(true);

$frontendOptions = array(
    'lifetime' => 7200, // tempo de vida
    'automatic_serialization' => true
);
$backendOptions = array('cache_dir' => '/tmp');
// criando uma instancia do cache
$cache = Zend_Cache::factory('Core',//frontend
    'File',  //backend
    $frontendOptions,
    $backendOptions
);

if(!$result = $cache->load('cachePosts')) {
      //aqui podemos usar o Zend_Db, por exemplo
      $result = 'aqui vai o processamento, como buscar os dados do banco';
      $cache->save($result, 'cachePosts');
}
echo $result;


Dessa forma é fácil de extender seu projeto usando componentes bem estruturados e testados.

Meus dois centavos sobre o MicroPHP Manifesto

Nos últimos dias um post tem gerado alguma discussão entre os programadores PHP: o MicroPHP Manifesto (post original e o site que foi gerado depois)
Confesso que concordo com vários pontos levantados pelo Ed Finkler no seu artigo, principalmente no ponto de que alguns frameworks estão ficando muito mais complexos do que o necessário.
Logo depois da publicação do post surgiram algumas respostas (essa e essa, por exemplo), umas concordando e outras crucificando o autor.
A minha opinião é: depende :) Depende do projeto. Estou trabalhando atualmente em um projeto enorme, com vários requisitos técnicos bem avançados, com equipes trabalhando remotamente e paralelamente. Neste projeto estamos usando Zend Framework e Doctrine e foi a melhor decisão.
Ao mesmo tempo precisei ministrar um curso onde o foco eram tecnologias bem específicas e não precisava adicionar complexidade, então a melhor opção foi o Slim, conforme comentei em outro post. Aliás, gostamos tanto do Slim que estamos usando em outros pequenos projetos da Coderockr. Gosto também da abordagem do Symfony, seus componentes e o Silex, micro-framework baseado nestes componentes.
Eu acho que o post teve um bom efeito, que foi gerar a discussão sobre o assunto, mas ele não deve ser levado tão ao pé da letra e nem gerar flamewars intermináveis. A idéia é sempre analisar qual é a melhor situação para seu projeto, e mesmo usando algo completo, como o Zend Framework, tentar sempre manter o desenvolvimento o mais simples e bem implementado.

Etiquetado

Curso sobre PHP, Memcache, Sphinx e Gearman

Em Fevereiro vou repetir o curso “mão na massa” que ministrei no PHPConference de 2011, pela Tempo Real Eventos, em SP.
Os detalhes do curso encontram-se na página do evento

PHPConference 2011

Na última semana estive em Osasco-SP para a sexta edição do PHPConference, o maior evento de PHP da América Latina.
Novamente pude rever os amigos e lendas da programação PHP, além de conhecer novas pessoas, algumas que eu conhecia via Twitter. Na minha opinião essa é a parte mais importante do evento, a troca de conhecimentos que acontece fora das salas de palestras.
Quanto as palestras, não consegui ver todas as que gostaria, mas as que consegui ver foram muito boas.
Assistindo algumas palestras e conversando com algumas pessoas a sensação que tenho é que o “mundo PHP” ganhou nos últimos meses um novo impulso de qualidade e inovação. Fazia um bom tempo que eu não me sentia empolgado com o ambiente, mas com coisas legais como bancos NoSQL, novos frameworks como Symfony 2, Zend Framework 2, diversos micro frameworks, o Service Oriented Architecture finalmente deixando de ser “tendência” e virando realidade, o MVC evoluindo para algo novo, tudo isso abre novos horizontes para os profissionais.
O material da minha palestra está no meu Speakerdeck e os comentários estão no Joind.in
E que venha o PHPConference 2012!

Slim Framework

Alguns dias atrás estava preparando o material de um curso que vou ministrar no PHPConference 2011. O assunto do curso já é bem “denso”: Gearman, Memcached e Sphinx, então não queria aumentar a complexidade incluindo algum Framework, até porque o requisito do curso era apenas “conhecimentos em PHP”.
Então iniciei o desenvolvimento do material usando somente o PHP e me deparei com a situação: “eu não consigo mais trabalhar sem frameworks!!”. Parti então para a busca de um dos novos micro frameworks que surgiram nos últimos meses. Fiz uma pequena (micro?) pesquisa e encontrei algumas opções legais como o Silex, DooPHP, Recess e Slim.
Após uma pequena análise acabei optando pelo Slim. O Silex é muito legal, pois é baseado no Symfony, mas não gostei de ter que usar o Twig para a parte de views, pois isso aumenta a complexidade. O DooPHP me pareceu faltar documentação. O Recess eu gostei bastante, mas vai ficar para um próximo estudo, principalmente a parte de REST, que achei interessante. O Slim me pareceu bem simples e a parte de views é feita por scripts PHP normais, sem precisar de um sistema de templates como o Twig ou Smarty (apesar de ser fácil integrá-los caso desejado).
Usando o exemplo básico do site é possível ver a simplicidade do Slim:

<?php
require 'Slim/Slim.php';
$app = new Slim();
$app->get('/hello/:name', function ($name) {
    echo "Hello, $name!";
});
$app->run();
?>

A idéia dele é fornecer apenas a parte de rotas e views simplificadas, sem se preocupar com a parte de modelos e coisas mais complexas.

Organizando o projeto

Com um pouco de esforço é possível fazer um projeto pequeno mas bem organizado usando-se o Slim. Abaixo a minha “receita” de projeto.

Estrutura de diretórios

config
controllers
docs
public
	images
	scripts
	styles
index.php
vendors
	Slim
views

Conteúdos dos arquivos

.htaccess

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule !\.(js|ico|gif|jpg|png|css|htm|html)$ index.php

index.php

<?php
require 'vendors/Slim/Slim.php';
define('CONTROLLERS_PATH', './controllers/');
define('VIEWS_PATH', './views/');

$app = new Slim(array(
    'templates.path' => VIEWS_PATH
));
$controllerDir = opendir(CONTROLLERS_PATH); 
while ($controller = readdir($controllerDir)) {
	if($controller != '.' && $controller != '..')
		require CONTROLLERS_PATH . $controller;
}
$app->run();

Desta forma basta adicionar arquivos no diretório controllers e views. Um exemplo de controller e view

config/db.php

<?php
$dsn = 'mysql:host=localhost;port=3306;dbname=gallery';
$usuario = 'root';
$senha = '';
?>

controllers/Gallery.php
<?php
$app->get('/', function() use ($app) {
	require 'config/db.php';
	$pdo = new PDO($dsn, $usuario, $senha);
	$stmt = $pdo->query('SELECT * FROM gallery');
	$data = $stmt->fetchAll();
	$app->render('index.phtml', array('data' => $data));	
});

$app->get('/gallery/:id', function($id) use ($app) {
	require 'config/db.php';
	$pdo = new PDO($dsn, $usuario, $senha);
	$stmt = $pdo->query("SELECT * FROM gallery where id = $id");
	$gallery = $stmt->fetchAll();
	$stmt = $pdo->query("SELECT * FROM image where gallery_id = $id");
	$images = $stmt->fetchAll();
	$app->render('gallery.phtml', array('gallery' => $gallery, 'images' => $images));
});
?>

views/index.phtml
<h2>Galerias</h2>
<div id="gallery">
<?php if(isset($data)): ?>
	<?php foreach($data as $d): ?>
		<p><a href="/gallery/<?php echo $d['id'];?>"><?php echo $d['name'];?></a></p>
	<?php endforeach;?>
<?php endif;?>
</div>

views/gallery.phtml
<h2> <?php echo $gallery[0]['name']?></h2>
<h3><?php echo $gallery[0]['description']?></h3>
<?php foreach($images as $i): ?>
	
	<a href="/images/<?php echo $i['gallery_id'];?>/<?php echo $i['filename'];?>"  target="_blank">
		<img src="/images/<?php echo $i['gallery_id'];?>/<?php echo $i['filename'];?>200.png">
	</a>
<?php endforeach;?>
<p><a href="/">Voltar</a></p>

Claro que o Slim não substitui um framework completo como o Zend Framework ou o Symfony, mas para projetos pequenos, provas de conceito ou coisas mais simples ele é uma boa opção.

Pós-graduação em Umuarama

Fui convidado a ministrar uma disciplina na pós-graduação “Desenvolvimento de Software para Internet e Dispositivos Móveis” que vai acontecer em 2012, na cidade paranaense de Umuarama. A disciplina vai ser “Framework de desenvolvimento PHP”, onde vou apresentar o Zend Framework.
Mais informações no site da Faculdade ALFA

Palestra no PHP Conference 2011

Além do tutorial também vou palestrar no PHP Conference 2011!
A minha palestra será no dia 03/12, as 12:00, com o título “Otimizando aplicações com Zend Framework”
Aproveite e faça sua inscrição para o evento. Imperdível é pouco!

Artigo na PHP Review

Foi lançada a nova edição da revista PHP Review e conta com um artigo meu, sobre frameworks.
O download do PDF pode ser feito no site oficial da revista

Seguir

Obtenha todo post novo entregue na sua caixa de entrada.

Join 1.472 other followers