Factory Pattern e PHP

at 09/01/2009
tagged as #PHP
Pedro Mendes

Voltando a visitar alguns bookmarks de blogs sobre PHP, encontrei um material simples mas interessante do Brian DeShong. Ele publicou no seu site o slide de sua palestra sobre o padrão Factory e sua implementação em PHP. O link é esse aqui.

PHP.JS - port de funções PHP para o Javascript

at 28/11/2008
tagged as #PHP #Javascript
Pedro Mendes

Procurando algumas funções Javascript que fossem equivalentes a funções em PHP acabei esbarrando no projeto PHP.JS, que é uma biblioteca Javascript com várias funções "portadas" do PHP. O contador do site deles informa que até a data deste post, 196 funções já foram recriadas e parece que o projeto esta ativo.

Como a biblioteca esta ficando cada vez mais extensa, consequentemente esta ficando cada vez mais pesada (52.kb comprimida e 219kb não comprimida). Acho que o ideal é ir adicionando ao projeto somente as funções que forem sendo usadas, o que poupará bastante a conexão dos usuários do seu site.

Helper button_to no Code Igniter

at 17/11/2008
tagged as #PHP
Pedro Mendes

O Rails tem um helper interessante que é o button_to - ele cria um formulário e botão pra postagem com a opção de se passar um array para criação de hiddens. Bem prático, se por exemplo você tem uma listagem que tenha opções como excluir ou editar e você não ache elegante passar parâmetros por get. Trazendo para o mundo do CodeIgniter, para quem estiver escrevendo a view, tem a sensação de que esta usando um <php echo anchor('')> que posta dados.

Copiando essa idéia do RoR para o CI, criei o helper button_to (prêmio para mim pela criatividade do nome) que tem o mesmo conceito. Cadastrei o helper no wiki do framework. Para acessar, clique aqui.

Layout e Elements no CodeIgniter

at 17/10/2008
tagged as #PHP
Pedro Mendes

Primeiramente quero pedir desculpas a galera que acessa o blog diariamente, já que notaram que o blog tem uma semana sem atualizações! Mas não fiquem com raiva : como recompensa consegui autorização de um grande autor gringo para publicar seus artigos traduzidos. Em breve falo mais sobre isso.

Estamos na correria aqui na 3Jane passando um projeto do CakePHP para o Code Igniter. Uma das primeiras coisas que precisamos criar no Code Igniter foi o esquema de Layouts e Elements (como no Cake). Não dá pra acreditar que o Code Igniter não venha com algo built-in, mas, felizmente o CI tem algumas formas de você construir adds.

Eu sei que quem trabalha com o Code Igniter mais tempo vai reclamar feito uma velha ranzinza "mas já existem uns 10 sites falando sobre como plugar algum esquema de layout no CI". Eu realmente achei algumas soluções na web mas nem sempre se propunham a resolver meu problema de uma maneira simples e "desacoplada". Um simples exemplo é a Layout Library do próprio site do CodeIgniter, que é bem completa mas, para funcionar você tem que substituir a chamada da view das actions dos seus controllers por um método próprio. Além do problema da refatoração do código, isso acaba fugindo do padrão do CodeIgniter ( que é o que eu tenho mais medo). E nem me venha falar daquelas soluções que usam hooks...

Para chegar a algo que me atendesse, eu peguei a Library acima e dei uma adaptada para funcionar sobreescrevendo o Loader padrão para trabalhar com o esquema de Layouts - e acrescentei um método para trabalhar com Elements também. Vamos lah:

Crie uma library parecida com a seguinte:

<?php if (!defined('BASEPATH')) exit('No direct script access allowed');

/**
* Customized Loader Class
*
* Overwrite default Loader which loads views and files
*
*/
class MY_Loader extends CI_Loader {

var $layout = "default";

function MY_Loader() {
parent::CI_Loader();
}

/**
* Load View
*
* This function is used to load a "view" file, including layout. It has three parameters:
*
* 1. The name of the "view" file to be included.
* 2. An associative array of data to be extracted for use in the view.
* 3. TRUE/FALSE - whether to return the data or load it. In
* some cases it's advantageous to be able to return data so that
* a developer can process it in some way.
*
* @access public
* @param string
* @param array
* @param bool
* @return void
*/
function view($view, $data = null, $return = FALSE) {

$loadedData = array();
$loadedData['content_for_layout'] = parent::view($view,$data,true);

if($return) {
$output = parent::view('layouts/' . $this->layout, $loadedData, true);
return $output;
} else {
parent::view('layouts/' . $this->layout, $loadedData, false);
}
}

/**
* Load View Element
*
* This function is used to load a "view" element file, simulating CakePHP's elements.
*
* 1. The name of the "element" file to be included.
* 2. An associative array of data to be extracted for use in the element.
*
* @access public
* @param string
* @param array
* @return string
*/
function element($element, $data = null) {
return parent::view('elements/' . $element, $data, TRUE);
}

/**
* Set Layout
*
* This function is used to set layout name
*
* 1. The name of the "layout" file to be renderized in view function.
*
* @access public
* @param string
* @return void
*/
function set_layout($value) {
$this->layout = $value ;
}

}


Teoricamente é só isso, copiar a library acima para o diretório de bibliotecas, criar os diretórios layouts e elements dentro do diretório views e criar um layout padrão. Com isso seu site já estará funcionando com layouts, sem precisar mudar suas actions ou criar hooks.

Explicando melhor, a library primeiro renderiza a view solicitada e depois coloca o resultado dentro do layout e o renderiza. Como já disse, fixei que todos os layouts estarão dentro da pasta layouts dentro das views, mas você pode mudar isso. Criei também o set_layout, que me recurso a explicar pra que funciona. E por fim os elements são "views" disfarçadas, que sempre retornam a view renderizada como string. Acho que os elements nem são tão necessários pra todos, mas os fiz só pra forçar o pessoal a concentrar o elementos no mesmo lugar.

Um layout (já usando um elemento) poderia ser o seguinte:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title> Titulo </title>

</head>

<body>

<h1> Esta carregando o layout </h1>

<?= $this->load->element('banner.php'); ?>


<!-- Conteudo -->
<?=$content_for_layout?>

</body>

</html>


O elemento banner acima é uma view normal, por isso nem vou postar o exemplo. Quem quiser uma cópia do framework seco só com o esquema de layouts funcionando, eu coloquei no rapidshare. A versão da framework é 1.6.3 então cheque no site do CodeIgniter qual é a versão atual antes de começar a desenvolver em cima da cópia que estou disponibilizando.

Projetos PHP e Integração Contínua

at 09/10/2008
tagged as #PHP #Agile
Pedro Mendes

Estamos lutando aqui na 3Jane para alcançarmos um formato indolor de Continuous Integration ( aqui e aqui ) em nossos projetos - que são (até então) em PHP.

Existe um número relevante de ferramentas disponíveis, o problema esta sendo fazer com que elas sigam um fluxo natural no projeto. Ou as ferramentas precisam de uma adaptação para PHP (como o CruiseControl com o PHPUnderControl), ou as ferramentas não se encaixam, ou são muito limitadas.

Embora um pouco complexo, estamos achando algumas coisas boas. Para começar, tinhamos decidido apostar no CakePHP, um framework sólido e com grande similaridade com o Rails. Ficamos realmente satisfeitos com a organização da "criança" e de como ele é bem feito. E também tem o fato de que o CakePHP já vem com uma integração com o SimpleTest, que até onde pude ver, a ponte entre eles é sólida e sem "adaptações" incomodas - até porque o SimpleTest também é em PHP.

Acontece que pelo CakePHP ser bem completo, ele também é mais lento que outros frameworks e por motivos de força maior decidimos trocar para o Code Igniter, que também é um bom framework, mas não possui tantas camadas quanto o CakePHP e teremos que "digitar mais". Outro ponto fraco do Code Igniter com relação ao CakePHP é o bake, que é um script generator do CakePHP que agiliza muito a vida.

Quanto aos testes no Code Igniter ele já vem com uma library bem simples para teste unitário, mas é tão simples que estou propondo aqui que troquemos para o SimpleTest ou PHPUnit. Como este último parece ter uma integração com o PHPUndercontrol, estou lendo como plugá-lo ao CodeIgniter.

Já construímos o Tracer Bullet para os testes do ambiente e estamos implantando-o. Estou vendo o Phing para automatizar o processo de deploy, mas ainda não parei para estuda-lo de verdade. Essa é uma das minhas metas nos próximos dias.

Para controle de código, migramos do SourceSafe para o SubVersion e apesar de alguns problemas com o Tortoise, valeu a pena. Pra ser bem sincero, o engraçado é como sempre os problemas envolvem o Windows. Para controle de bug/issues estamos usando o Jira e como Wiki o Confluence. Ah, e para a documentação do nosso código estamos usando o phpDocumentator.

Ufa! Acho que é isso... O problema é conseguir tempo pra ver tudo isso e dar continuidade no projeto. Mas posso dizer que demos um "salto quântico" no processo de desenvolvimento aqui na 3Jane. Se você quiser uma lista organizada e decente das ferramentas que podem te ajudar no desenvolvimento em projetos PHP, o Dave Marshall publicou um top 10 no blog dele.

Por fim, deixo com vocês um slide falando sobre PHP + Continuous Integration :

PHP + YAML via SPYC

at 22/09/2008
tagged as #PHP
Pedro Mendes

O Rails usa um formato muito simples de documentos para a substituição do XML, o YAML. Esse formato além de extremamente ágil é mais "human friendly" que o XML.

Procurando algum loader em PHP para esse formato, achei o SPYC. A implementação é simples, basta dar um Spyc::YAMLLoad('arquivo.yml') que ele carrega e gera um array - e você também pode fazer dump com ele.

Usando o Authenticate do CakePHP

at 10/09/2008
tagged as #PHP
Pedro Mendes

Estou trabalhando ultimamente com o CakePHP (1.2) e achei um componente muito útil: o AuthComponent. Ele centraliza todo o fluxo de autenticação no sistema e se você seguir algumas regras básicas dele, poderá fazer toda parte de login do seu site com praticamente esforço zero.

Primeiro passo é definir se a maior parte do seu site será publica ou privada por que isso dirá onde você deve acionar o Auth. Se você notar que quase todas as áreas do seu site será de acesso publico, é melhor chamar o Auth direto nos controllers que terá actions privadas. Caso não, você pode colocar direto no app_controller da sua aplicação.

Não que você não possa colocar direto na configuração de chamada do auth a lista de controllers e/ou actions e suas respectivas visibilidades, mas é só por uma questão de economia de esforço

A idéia é simples, e vou assumir que o controller com o auth será o app_controller


class AppController extends Controller {

var $components = array('Auth');

function beforeFilter() {

// Auth config
$this->Auth->allow(array('action_publica'));
$this->Auth->loginError = __("Usuario nao encontrado", true);
$this->Auth->loginAction = array('controller' => 'users', 'action' => 'login');
$this->Auth->loginRedirect = array('controller' => 'users', 'action' => 'profile');
}

}


No exemplo acima, coloquei a chamada do componente no var $components = array('Auth');, logo depois no beforeFilter ( que sempre é executado antes do controller) configurei o Auth da seguinte forma: o allow() serve para você dizer quais actions são de acesso publico, o loginError() é a mensagem de erro, o loginAction() define onde esta o action de login e o loginRedirect() serve pra apontar pra onde o usuário será redirecionado após o login. Agora basta no meu controller login colocar as actions login() e logout() que ficaria parecido com o seguinte:


class UsersController extends AppController {

function login() { }

function logout() {
$this->redirect($this->Auth->logout());
}

}


Assim ficar o login e o logout. Simples não ? O action login() pode ficar completamente em branco e o logout() faz um redirect pro logout do Auth. E a view do login também é bem simples:


<div class="users">

<?php if ($session->check('Message.auth')):?>
<?php $session->flash('auth'); ?>
<?php endif;?>

<?php echo $form->create('User', array('action' => 'login'));?>
<fieldset>
<legend><? __('Login') ?></legend>
<?= $form->input('username'); ?>
<?= $form->input('password'); ?>
</fieldset>
<?php echo $form->end('Logar');?>
</div>


Na view eu coloquei o $session->flash('auth'); principalmente para mostrar a mensagens do tipo "usuário não encontrado", que você configura previamente no Auth.

Algumas considerações finais



O Auth tem várias configurações que podem ser alteradas, mas por default ele assume que você tem um modelo chamado User, que tem dois campos: username e password. Ele também assume que o campo password foi criptografado com um hash dele. A questão da criptografia do password é a única coisa que não pode ser alterada - ele sempre assume que o password esta criptografado.

Para saber mais sobre o Auth, vá na página da API dele e da documentação no CookBook. Agora vou continuar estudando sobre o ACL para definir as permissões de usuário automaticamente pelo grupo que ele pertence. Quando estiver com melhores conhecimentos tento escrever algo sobre isso.

Alterando configurações do php.ini via apache

at 09/09/2008
tagged as #PHP #Apache
Pedro Mendes

Pra quem trabalha com vários projetos PHP em um mesmo servidor, sabe que ficar alterando o PHP.INI para cada besteira que algum projeto queria fazer não é uma coisa muito legal. Para falar a verdade não é nada legal... Por exemplo, não é legal trocar a pasta temporária de upload para um diretório que não possui permissão de escrita ou que esta em uma partição com pouco espaço disponível.

Entretanto ficar confiando no ini_set() do PHP realmente não é legal, pois ao meu ver caímos em dois problemas: as configurações do php.ini ficam extremamente espalhadas ( não queremos violar o DRY correto ?), e segundo é que não podemos fazer tudo com as funções ini_set() like.

Para quem não sabe, algumas configurações do php.ini não pode ser alteradas "on the fly". A Zend criou um nível de segurança chamado PHP_INI_SYSTEM, que não podem ser alteradas em runtime ( clique aqui para ver a lista de funções e privilégios necessários).

A solução que encontrei foi simples mas eficaz ( além de seguir as orientações da própria Zend) : usar uma diretiva de diretório do Apache, lançando um PHP Admin Value. Fazendo isso você pode redefinir algum parâmetro do php.ini para um diretório específico no servidor. A idéia é mais ou menos a seguinte: No httpd.conf do apache, dentro da sessão Ifmodule , crie um diretório para sua aplicação e coloque o seguinte parâmetro:


<Directory "/caminho/para/o/projeto/">
php_admin_value parametro_do_php_ini "novo_valor"
</Directory>
Com isso você pode sobrescrever o comportamento do php.ini inclusive em configurações mais avançadas. Sei que é redundante, mas como se pode perceber tive que usar o php como módulo para poder proveitar essa diretiva.

Gerenciamento de campanhas via OpenX

at 05/09/2008
tagged as #PHP
Pedro Mendes



Vejo pouca gente comentando sobre uma ferramenta de gerenciamento de publicidade online muito interessante feita na dupla PHP & MySQL: OpenX.

O OpenX é uma ferramenta já estável usada para o gerenciamento de banners e texto publicitários de N anunciantes (advertisers) para N publicadores (publishers) no esquema de campaigns. No início é meio complexo entender como funciona as campaigns, zones, filters e os esquemas de clicks, mas não é nenhum ciplope. Eu estive futucando o design do software e os caras que desenvolveram focaram muito (muito mesmo) em desempenho - o que às vezes não os deixam seguir algumas regras da cartilha do "bom desenvolvedor", mas nada alarmante.

Outra coisa muito legal é os diversos relatórios que ele gera, além de um instalador que torna a vida mais fácil para o primeiro deployment.

Para saber mais sobre a ferramenta, clique aqui.

PHP para aplicações Enterprise

at 25/08/2008
tagged as #PHP
Pedro Mendes

Esta discursão é antiga, mas foi bem explanada por Ivo Jansch na PHP London Conference 2008. O PHP tem recursos interessantes para o desenvolvimento de aplicações Enterprise, mas parece que a comunidade aqui no Brasil não acordou para isso. Fica a dica de usar os tópicos explanados na apresentação para nortear os estudos!

Aspect Oriented Programming e PHP

at 19/08/2008
tagged as #PHP
Pedro Mendes

Chegando com mais um slide do Sebastian Bergman, o criado do PHPUnit, desta vez o rapaz dá uma pequena palinha sobre AOP, que é uma técnica complementar a OOP.

Code Igniter - Code Generator

at 15/08/2008
tagged as #PHP
Pedro Mendes

Tenho estudado ultimamente sobre o CakePHP e de cara já encontrei uma ferramenta muito útil, o bake que é um PHP CLI que permite desde a criação do projeto a scripts de forma automatica. A idéia é até simples, mas na prática ajuda a acelerar o processo de desenvolvimento e manter organizado.

Como conheço o Code Igniter faz um tempo e sei que ele não tem oficialmente uma ferramenta parecida, procurei na internet e achei algo que nem se compara criado por um Brazuca. Não é uma ferramenta "formal" e pelo visto nem pretende ser um grande projeto, mas já dá alguma facilidade. A página da ferramenta é essa. Só roda em ambientes *nix.

PDO - Conceitos Fundamentais

at 15/08/2008
tagged as #PHP
Pedro Mendes

Com a chegada da quinta versão do PHP (na verdade na 5.1), nasceu uma poderosa ferramenta que ainda hoje pouca gente já parou pra estudar: o PHP Data Objects ou PDO.

Pra inicio de conversa, o PDO é uma camada de acesso a dados que como o php.net promete, "indiferente do banco de dados que esteja usando, você poderá usar as mesmas funções para executar queries ou pegar dados". Desenvolvida pelo Wez Furlong - um desenvolvedor do core PHP que até tenho na minha lista de links no lado esquerdo, o PDO realmente cumpre o que promete em unificar as interfaces de acesso a dados. Ele foi escrito em C e segundo alguns evangelistas da extensão, não perde em nada em desempenho para as extensões tradicionais.

Ainda hoje temos a opção de usar no PHP os antigos drivers especificos para cada DB, mas isso já tem caído em desuso. Vale repetir o que a Zend comentou, que o PDO não é uma abstração do que já tinha, ele é a reescrita dos drivers fornecendo uma mesma interface (na maioria das vezes) para o desenvolvedor. Pra quem usa o Pear (se você não conhece deveria) talvez já tenha se esbarrado no PearDB, que esta sim é uma abstração. Mas o PDO não.

Composição e Bases Suportadas



O PHP Data Objects suporta nativamente as seguintes extensões: PostgreSQL, MySQL (3,4,5), Firebird, Sybase, Informix, Oracle, ODBC, DBLIB, IBM DB2, SQLite (2,3), MSSQL e FreeTDS.

Para usar o PDO você terá que ter no mínimo duas extensões : a do core, que geralmente já vem instalada por default, e a do banco desejado, como por exemplo o pdo_mysql.

O forma mais fácil para instalar os PDO drivers em uma versão do PHP previamente instalado é através do PHP Extension Comunity Library. Uma vez tendo o PECL instalado, basta digitar pecl install <nome_do_driver> e depois atualizar o php.ini adicionando na parte de extensões o driver instalado.

Conectando ao bd



Vou comentar só sobre como conectar ao banco de dados e criar um handle para a conexão, pois basicamente é isso que difere de um bd para o outro - ao final, vou deixar alguns links com melhores exemplos.

// Criando o handle de uma conexão com o PostgreSQL
$db = new PDO("pgsql:dbname=MEU_DB;host=localhost", "USUARIO", "SENHA" );

// Criando o handle de uma conexão com o MySQL
$db = new PDO("mysql:dbname=MEU_DB;host=localhost", "USUARIO", "SENHA" );


Viu como é simples? E com os outros drivers o procedimento é bem parecido. Vale ressaltar que por dicas da própria Zend, que o processo de criação de um handle sempre deve estar dentro de um try/catch, para que informações do servidor não sejam lançadas para o usuário. Fique atento!

Para dar um close na conexão basta você atribuir qualquer valor ao handle, como null por exemplo.

Conclusão



O PDO veio para substituir de vez as antigas formas de acesso a dados no PHP. Existe um número generoso de artigos sobre essa ferramenta, e para não ficar recriando a roda, deixo abaixo alguns links interessantes de fontes que já publicaram algumas receitas de bolo:

Manual Oficial em Português
DevShed - Using PDO Objects in PHP5
Post anterior com slides do criador do PDO
HTMLStaff - PDO: Bancos de dados no PHP 5

PHP 5.3 e seu Garbage Collector

at 28/07/2008
tagged as #PHP
Pedro Mendes

O PHP tem(ou tinha) um pequeno problema para tratar referências circulares, principalmente entre objetos. No blog do Alex Netkachov, um ZCE desconhecido da vida que as vezes posta umas coisas legais, ele fez o seguinte benchmark :


class Node {
public $parentNode;
public $childNodes = array();
function Node() {
$this->nodeValue = str_repeat('0123456789', 128);
}
}
function createRelationship() {
$parent = new Node();
$child = new Node();
$parent->childNodes[] = $child;
$child->parentNode = $parent;
}
echo 'Initial: ' . number_format(memory_get_usage(), 0, '.', ',') .
" bytes\n";
for($i = 0; $i < 10000; $i++) {
createRelationship();
}
echo 'Peak: ' . number_format(memory_get_peak_usage(), 0, '.', ',') .
" bytes\n";
echo 'End: ' . number_format(memory_get_usage(), 0, '.', ',') .
" bytes\n";

E o output disso foi:
Initial: 62,224 bytes
Peak: 34,905,216 bytes
End: 34,905,016 bytes


Muito interessante o resultado não ? 34mb para 10.000 requisições. Segundo o próprio Alex, isso seria o equivalente a "Modern systems with 1-2Gb can run 30-60 similar processes at the same time. But in shared hosting environment or when support of 100 simultaneous connections is a system requirement, such memory consumption is inadequate."


Pois bem, um cientista da computação de algum lugar do mundo chamado David Wang escreveu um patch para o garbage collector do PHP sanando este problema com as referências circulares. Ele mesmo confessa que o PHP usa "a simple garbage collection system", precisando de alguns improvements. Ele publicou um resumo do de suas idéias relativas a este patch e ao problema em si no news.php.net, mas eu trago abaixo uma cópia da mensagem dele:


Hello, everyone. My name is David Wang and I am one of the students
participating in Google Summer of Code this year. As you may remember,
my project is to implement a garbage collector for circular references
in PHP. As the midterm for Summer of Code is coming up, my mentor,
Derick Rethans, thought it would be a good idea if I shared my
progress with the community.

As you know, PHP uses reference counting as a simple garbage
collection system. One of the primary weaknesses of reference counting
systems is that objects that refer indirectly or directly to
themselves, i.e. reference cycles, are not collected. The accumulation
of unreferenced memory that is only deallocated at the end of a
request can be prohibitively expensive. The cycle collector I am
implementing directly addresses this problem.

The cycle collector is, of necessity, a type of tracing garbage
collector. However, it uses reference count information to accelerate
the collection process. Essentially, it works by removing the internal
reference counts (that is, references from an object within the cycle
to another object within the cycles )from candidate cycles. In a cycle
that can be collected, after all internal reference counts have been
removed, the reference count of all objects within the cycle should be
0. The particular algorithm that I am using is the synchronous cycle
collector described by David Bacon and V. T. Rajan in Concurrent Cycle
Collection in Reference Counted Systems (see the article for further
details). Various optimizations allow the cycle collector to be run
relatively infrequently and execute speedily when it does run.

Note that because PHP is designed to be single-threaded, a synchronous
algorithm is used which does pause program execution for cycle
collection when cycle collection becomes necessary. If a program has
no reference cycles, the cycle collector does not run at all.

The initial phase of implementation is complete, and I am currently
profiling, optimizing and trying the modified version of PHP on
various test programs in an effort to find bugs. Meanwhile, here are
some recent benchmarks.

Some aspects of the eZ Components (http://ez.no/ezcomponents,
available from SVN with the instructions here:
http://ez.no/community/articles/an_introduction_to_ez_components/installation)
testing suite use reference cycles heavily. The Template test uses
circular references the most frequently, the Graph test also uses
circular references, albeit less heavily.

On the Graph test, maximum memory usage with unmodified PHP was 133.9
MB with an execution time of 8 seconds.
On the Graph test, maximum memory usage with gc was 51.6 MB with an
execution time of 9 seconds.
On the Template test, maxmium memory usage with unmodified PHP was 1.5
GB with an execution time of 30 seconds.
On the Template test, maxmium memory usage with gc was 67.3 MB with an
execution time of 1 minute.
On the whole suite of tests (which includes the Graph and Template
tests), execution time with unmodified PHP was 12:03. With cycle
collection, it was 12:43.
These tests were conducted on my dual core AMD X2 4400+ desktop with
./configure --with-gd --with-jpeg-dir --with-zlib. As you can see,
there is the classic time vs. memory trade-off.

My project is currently being hosted on the xdebug CVS. You can get
the latest version with the following commands:

cvs -d :pserver:srmread@cvs.xdebug.org:/repository login
CVS password: srmread
cvs -d :pserver:srmread@cvs.xdebug.org:/repository co circular
Note that I'm implementing my project on top of a CVS version of PHP
5.2 that is a couple of weeks old. However, the cycle collector can be
ported into other versions of PHP fairly easily as it does not affect
the existing Zend engine code too much.

If anyone has any questions, I'll be more than happy to answer them!

Regards,

Yiduo (David) Wang


Fico feliz por essa melhoria, pois é uma pequena alteração que faz muita diferença. Só espero que não tenha seus efeitos colaterais...

Não mude o escopo dos seus objetos

at 22/07/2008
tagged as #PHP
Pedro Mendes

Imaginemos a seguinte situação : você seguindo o modelo de classes criado para o projeto X, cria uma classe de usuários. Lá você tem todo o cuidado para definir os Gets e Sets, colocar seus atributos com seus devidos modificadores de acesso, cria todos os seus métodos e tudo fica perfeito, respeitando os mais elegantes padrões de programação. Logo após, você usa essa classe para, por exemplo, fazer uma busca pelo usuário de ID 7. Talvez a busca fique assim:

$usuario = new User();

$usuario->setId(7);

$usuarioDesejado = $usuario->selectUser();

Ok, tudo ok. Mas.... e se de repente você digita o nome do atributo de maneira errada, como por exemplo seid . O PHP vai retornar um erro, correto ? Errado. Ele não retorna erro algum. Ele não retorna nada. Na verdade, ele cria um atributo em tempo de execução chamado, neste exemplo, seid. Isso é um problema.

Claro que você, assim como eu, só alteraria o escopo de um objeto em tempo de execução por um enorme engano. Faria alguns testes, descobriria o erro e todos ficam felizes ( hipotéticamente ). Porém, existem alguns programadores que não pensam assim. Pensam que se a linguagem permite, tem que usar. Logo, aproveitam a festa pra fazer uma zona com seu objeto. Começam a criar atributos alterando o design original da sua classe.

Não faça isso. Em pouco tempo o projeto se tornará em uma bola de neve, onde não se tem controle nenhum sobre o comportamento do seu código. Use a cabeça.

Por hoje é só pessoal.

Test your PHP applications!

at 22/07/2008
tagged as #PHP
Pedro Mendes

Mais uma vez com um slideshow...Acho que vou mudar o nome do blog para blogdosslides. Bom, de qualquer forma, esse slideshow é deveras interessante. Trata-se de mais um do Sebastian Bergmann , um dos principais desenvolvedores do PHPUnit.

O slide traz uma vasta explanação sobre testes no PHP. Entenda bem, não estou dizendo que o slide fala tudo sobre TDD, mas fala sobre como aplicá-lo no PHP através do PHPUnit. O cara fez uma aplicação de teste e explanou sobre técnicas auxiliares para assegurar a qualidade do seu software.

Separando os meninos dos homens

at 21/07/2008
tagged as #PHP
Pedro Mendes

Lendo o artigo do Jim Plush, acredito que ele acertou me cheio em listar os principais conhecimentos que um profissional PHP deva ter. Desde que entrei pra 3Jane, já participei de algumas etapas no processo de seleção dos cadidatos para vaga de desenvolvedor PHP, e sempre os candidatos tem certos problemas com coisas elementares. Logo se você estive aprendendo e quer um "mapa do tesouro", acredito que os itens do Jim resumem tudo:

PHP5 vs PHP4
You should at least three major features that separate PHP5 from PHP4

Networks
You should be able to do some basic socket programming or at least understand how you would connect to other machines

OOP
You should have a deep understanding of OOP and be able to answer simple questions like how private and protected methods differ. You should understand the following concepts(not really critical you use all of them but at least know why you would need them)

* interfaces
* constructors
* private, public, protected
* inheritance
* polymorphism
* static methods


Database
You should know what a normalized database is, you should understand primary and foreign keys,

Design Patterns
You shouldn't say "huh?" when I mention design patterns. Again, not critical you use that many, but important you understand why they're helpful and know at least a couple.

Source Control
You should be well versed in at least one major source control system (ZIP FILES IN TEMP DIRECTORIES DON'T COUNT!). bonus points for being able to name at least one reason cvs is a pain in the ass.

Unit Testing
You should understand what unit testing is, and why it's important (bonus points for test driven design, knowing how to unit test javascript, or how to use selenium).

Part of the Community
I should be able to find all sorts of good things on google that you're doing with php or web technologies, It generally is a red flag when I google you and nothing comes up(bonus points for having a project of your own or contributing to one).

Javascript Skills
You should know the methods use to manipulate the DOM (appendChild, removeChild, nextSibling, etc...), you should know how to create your own classes in JS (FORM VALIDATION IS 1999), bonus points for being able to show how to make a private variable in javascript.

CSS Skills
You should know the box model inside and out, understand css selectors and how to use inheritance

Passion for Improvement
I want you love what you do and not be looking for a bare minimum, what's the least I can do to get out of here at 5 job. You should be looking to build your skill sets and become more valuable.


Fonte: http://www.litfuel.net/plush/?postid=166

Confesso que embora os itens sejam poucos, eles são bastante vastos e é impossível dominar todos de uma hora pra outra. E não somente isso, muitas vezes faltam livros técnicos voltados para nossa plataforma, o que nos obriga a procurar por materiais em outras linguagems, como em Java por exemplo. Aqui no Brasil, algumas vezes o PHP tem uma imagem de "menos enterprise" que outras plataformas de desenvolvimento web, muito por culpa do mercado que ele tem maior participação. Vamos estudar pra mudar isso!

PHP 5.3 Features

at 21/07/2008
tagged as #PHP
Pedro Mendes

O sr. Ilia Alshanetsky ( ufa!) andou liberando no blog dele um pdf com as features do PHP 5.3. Coloquei no Rapidshare e o link segue abaixo:

http://rapidshare.com/files/131456385/php53.pdf.html

A principais mudanças ao meu ver serão:

  • Feature complete implementation of namespaces
  • Overall Improvement 5-15%
  • Introduced __DIR__ magic constant indicating the directory where the script is located
  • ?: Operator : Allows quick retrieval of a values and/or expressions
  • __callStatic() : __call() equivalent, but for static methods

Existem outras importantes modificações, entre elas no php.ini, PDO, E_DEPRECATED ( novo error mode) e no Garbage Collector. Vamos ver no que dá...




Desenvolvimento Web e Segurança

at 18/07/2008
tagged as #PHP
Pedro Mendes

Continuando na onda dos slideshows, hoje estava lendo um sobre segurança na web em aplicações PHP. Aborda o básico de forma direta. Fala sobre Data Input, XSS, SQL Injection, Code Injection, alguma coisa sobre sessão e um pouquinho sobre servidores compartilhados. Seus autores são Anish e Mudha - não faço a mínima ideia de quem sejam...

Acessando atributos privados de um objeto em PHP

at 18/07/2008
tagged as #PHP
Pedro Mendes

Lendo o ultimo slideshow ( do Sebastian) sobre a OOP no PHP, no slide 28 ele mostrou inocentemente um exemplo que me deixou no mínimo curioso. Ele cria um método qualquer em uma classe, que recebe por paramentro um objeto qualquer, e então consegue trabalhar com esse objeto como se TODOS os atributos fossem publicos.Não muito satisfeito com o exemplo do slideshow do carinha, eu realizei meus próprios testes. Eis ai os resultados:
1º - Tirando a prova real do exemplo do rapaz ( acessando um atributo privado de um outro objeto do mesmo tipo ) :

<?php

class test {

private $privateAtribute = "Atribute accessible";

public function printMe( $obj ) {


privateAtribute .= ' changed';
print $obj->privateAtribute;

}

}

$test = new test;
$test->printMe(new test);

?>



Saida: Atribute accessible changed

2º - Acessando um atributo privado do mesmo objeto

<?php
class test {
private $privateAtribute = "Atribute accessible";

public function printMe( test $obj ) {


$obj->privateAtribute .= ' changed';

print $obj->privateAtribute;

}

}

$test = new test;
$test->printMe($test);
?>

Saida: Atribute accessible changed


3º - Acessando um atributo privado de um outro objeto de tipo diferente
<?php

class testA {

private $privateAtribute = "Type A - Atribute accessible";

}

class testB {

private $privateAtribute = "Type B - Atribute accessible";

public function printMe( $obj ) {

print $obj->privateAtribute;

}

}

$test = new testB;
$test->printMe(new testA);

?>


Saida: Fatal error: Cannot access private property testA::$privateAtribute in C:xampphtdocstestindex.php on line 15


Por fim, ele só lançou erro quando os objetos eram de tipos diferentes. Vendo alguns testes que o dx7lab fez aqui na 3jane, vi que em Java a coisa funciona do mesmo jeito. Eu hein...

Desenvolvimento Web e Segurança

at 18/07/2008
tagged as #PHP
Pedro Mendes

Continuando na onda dos slideshows, hoje estava lendo um sobre segurança na web em aplicações PHP. Aborda o básico de forma direta. Fala sobre Data Input, XSS, SQL Injection, Code Injection, alguma coisa sobre sessão e um pouquinho sobre servidores compartilhados. Seus autores são Anish e Mudha - não faço a mínima ideia de quem sejam...

PHP Object Model

at 17/07/2008
tagged as #PHP
Pedro Mendes

Mais um slide show... Desta vez é de um desenvolvedor chamado Sebastian Bergmann, um dos desenvolvedores do PHPUnit. Ele da um resumão da implementação da OOP no PHP.

Checando tipagem de objetos por parâmetro

at 30/06/2008
tagged as #PHP
Pedro Mendes

Em PHP, como tudo é dinâmico - até a tipagem de variáveis, é comum quando trabalhamos com objeto verificar seu tipo com o instanceof. Mas existem um jeito mais elegante que é o seguinte:


class carro {
... bla bla bla ...
}

class cavalo {
... bla bla bla ...
}

function imprimeCarros( carro $umCarro ) {
print $umCarro;
}

$meuCarro = new carro();
$meuCavalo = new cavalo();

imprimeCarros( $meuCarro );
imprimeCavalos( $meuCavalo );

Na primeira chamada de imprimeCarro vai ocorrer tudo ok. Na segunda chamada, como o tipo de objeto é diferente, vai estourar um erro. Sei que parece óbvio mas, deixa o código mais elegante...

Design Patterns no PHP

at 21/05/2008
tagged as #PHP
Pedro Mendes
Parte I : Introdução Geral

Ola pessoal, esse é o primeiro estudo relacionado a PHP que publicarei no blog - e espero que seja o antecessor de muitos outros. Por o PHP ser uma linguagem extremamente fácil, tanto pela sintaxe, quanto pela comunidade de programadores que mantem blogs e fóruns pela internet, cada programador PHP acaba tendo uma "escola" diferente. Obviamente, isso eh bom pois, cada um aprende de acordo com o seu próprio ritmo de estudos, mas, in other hand, vejo muita muita gente dizendo-se programador com deficiências em áreas basicas da programação. Falando de maneira simples, a galera ta mais preocupada em fazer um site do que construir uma solução.

Pensando nisso, resolvi começar falando a respeito de Padrões de Projetos ou Padrões de Desenho de Software, termos estes originários do inglês Designer Patterns. Ao longo desse estudo, vamos tentar abordar os principais pontos de desenvolvimento de software estruturado e no final pretendo realizar um passo-a-passo de um projeto junto vocês, ok?

Antes de comerçarmos o estudo em si, existe um ponto muito importante que necessita ser ressaltado: o PHP, ao contrário de outras linguagens como C ou Java por exemplo, não obriga o programador a desenvolver pensando nos moldes da Orientação a Objetos (OO). Não caindo no mérito desta caracteristica do PHP ser boa ou ruim, é importante o programador ver-se motivado a querer aprender esse padrão e utilizá-lo sempre em seus projetos. Como tem sempre aquele pessoal que aprendeu programar de uma forma, e fica meio reguardado para migrar para uma outra forma de pensar, gosto sempre de dizer que existem soluções e soluções. Como li em algum lugar certa vez "Qualquer chimpanzé consegue escrever um código que o computador entenda, o dificil é escrever um código que o homem também possa entender". Esse é o espirito da coisa.

Qual são os principios da Orientação a Objetos ?

Para podermos aprendermos os Design Patterns, devemos impreterivelmente entendermos como funciona um código Orientado a Objetos. Um código OO deve seguir os seguintes conceitos :

- Encapsulamento :
Todo código que segue os moldes da OO, deve encapsular, ou seja, dividir em pequenas partes um problema/solução bem definido. Cada parte ou capsula, deve ser independente e bem formulada, de maneira a ficar claro onde ela se aplica no seu projeto.

- Generalidade:
Todo código orientado a objetos deve ser construido pensando sempre em ser reaproveitado em outros projetos.

- Equilíbrio:
Quando escolhemos seguir um padrão em um projeto, devemos sempre usarmos o esquilibrio em até onde vamos padronizar nossos códigos. Devemos sempre analizar qual tipo de problema teremos que resolver, vermos como funcionam as soluções tradicionais e como funcionam as soluções ruins ou fracassadas. Com isso, conseguimos facilmente entender como se comportará o nosso código.

- Abstração:
Para desenvolvermos um código elegante, devemos usar abstrações, ou seja, analizarmos os conceitos do conhecimento cotidiano na nossa vida real e aplicarmos ao nosso código. Parece loucura, mas realmente é assim que funciona.

- Abertura:
Ao adotarmos o padrão OO em nosso código, ele deve ser flexível para que cada capsula tenha liberdade de se aprofundar tanto quanto for necessário em um problema.

- Combinatoriedade:
A capsulas em seu código deve ser relacionadas hierarquicamente. Isso significa que você deve ter partes maiores em seu código, que se relacionam com diversas outras partes menores.


Lembrando que não é necessário você ficar decorando esses conceitos. Basta entendê-los e fazer alguns poucos exercícios tentando combinar os itens acima. Em pouco tempo, esses conceitos serão notados naturalmente em seus códigos.

O PHP pode não ser considerada a linguagem-modelo ao falarmos de OO (tal como Java), mas, através da versão 5 do nosso tão amado HyperText Preprocessor conseguimos utililzar praticamente todos os padrões mais comuns do Designer Patterns. Boiou ? Fique atento nos "próximos capítulos" deste estudo que você poderá entender melhor. No próximo estudo falarei sobre o Modelo de Classes, explanando sobre Classes, Instâncias, Objetos, Métodos, Propriedades, Herança entre outras coisas e, vou montar um exemplo básico em PHP.

Links interessantes para quem quiser saber mais por enquanto:
- Apostila em PDF do Professor Fenando Lozano falando sobre diversos conceitos de OO no PHP : http://www.lozano.eti.br/palestras/oo-php.pdf
- Criar Web - POO no PHP 5 - http://www.criarweb.com/artigos/330.php
- Grupo de PHP no Yahoo! Grupos - sempre com alguém disposto a tirar duvidas - http://br.groups.yahoo.com/group/php-pt/

Um grande abraço e sorte nos estudos!
Pedro Mendes

Design Patterns no PHP

at 21/05/2008
tagged as #PHP
Pedro Mendes
Parte II: Criando classes


Dando continuidade ao estudo sobre Design Patterns no PHP, vamos hoje começar a falar sobre o Modelo de Classes e a sua aplicação usando o PHP. No ultimo post ( Design Patterns no PHP - Introdução Geral ), eu havia falado sobre teorias como : Encapsulamento, Generalidade, Equilíbrio, Abstração, Abertura e Combinatoriedade. Agora, levando em consideração que você entendeu o principio teórico da coisa, vamos lá. Caso não, envie perguntas através dos comentários e/ou tente ler novamente o primeiro tópico do estudo.


A invenção da Roda.


O paradigma, ou seja, modelo ou padrão da Orientação a Objetos não é novo. Foi criado na década de 60/70, quando os softwares começaram a ficar extremamente complexos. Além do motivo óbvio de melhor reutilização do que já foi escrito, era necessário uma forma mais eficaz na organização dos sistemas. Até por que, cada vez mais os projetos estouravam seus prazos e valores previstos.

Talvez, ao descrever o passado, muitos programadores enxerguem seu presente ou o da empresa onde trabalha. Projetos que pareciam ser extremamente simples, mas, acabam se tornando uma verdadeira Caixa de Pandora. Historicamente, a primeira linguagem a introduzir conceitos do paradigma de Orientação a Objetos foi a "Simula". Logo após veio o Smalltalk (criada pela Xérox) que se tornou a primeira linguagem popular Orientada a Objetos - e que alavancou o paradigma.


Mesmo tendo rodas, bicicleta ainda não é carro.


Talvez alguém afirme: Mas o meu código é organizado, afinal de contas eu o separo em varias funções. Será ? Em um sistema simplório, como de um pequeno gerenciador de notícias, você pode pensar que não tem tanto a perder. Mas ai surgem questões do tipo : E se a estrutura do banco tiver que mudar, o quanto você terá que alterar o seu código ? E se novas regras aparecerem ? E se a fonte de dados vier de diferentes meios (RSS, BD1, BD2, arquivos de texto, web services) ? E na hora de documentar o sistema, o que você faz ?

E lá vai o bendito programador abrir um arquivo com umas trinta functions diferentes, copiando e colando uma função qualquer para criar a mesma coisa mas agora com um ou dois parâmetros diferentes. Geralmente você terá que revisar TODO o projeto pois, não existe uma arquitetura flexível a mudanças.


Embora hoje a sigla OOP (Oriented Object Programming) ou POO (Programação Orientada a Objetos) cause certo frisson, ela não é algo tão complexo a ponto de somente nerds com coeficiente de rendimento 9.9 de Harvard possam entender. A POO nada mais é do que a evolução natural da programação procedural. Invista seus esforços para entender a lógica da POO - não fique tão preocupado em decorar " qual é a sintaxe no php que faz alguma coisa . É realmente simples.


Voltando a falar sobre Encapsulamento.

No ultimo post do estudo, eu defini encapsulamento da seguinte forma :

“Todo código que segue os moldes da OO, deve encapsular, ou seja, dividir em pequenas partes um problema/solução bem definido. Cada parte ou cápsula, deve ser independente e bem formulada, de maneira a ficar claro onde ela se aplica no seu projeto."


Partindo deste principio, imagine que você tenha umas 20 funções que você costuma usar sempre. Funções como acesso ao banco de dados, validação de formulários, cadastro de alguma coisa em alguma tabela, etc. Você tentou organizar seus códigos dividindo-os em pequenas partes. Mas imagine que você pode agora melhorar a interação dessas partes. Fazer com que elas façam o trabalho sujo de maneira mais "automatizada". Imagine que você pode agora alterar o comportamento das suas funções de acordo com algum evento, melhorar o tratamento de erros, reaproveitar melhor seu código enfim, imagine que você poderá ter mais tempo livre para se preocupar com outras coisas. Essas são as conseqüências naturais da POO.

Com um código seguindo as boas regras da POO, você consegue maior independência e controle entre as suas "cápsulas". Agora você começará a separar seus códigos não mais por functions, mas sim por classes, que terão um subconjunto de funções (métodos). Vamos ver alguma coisa mais prática no próximo tópico.


Dissecando o sapo.


Vamos à prática. Que tal analisarmos a estrutura de uma classe bem simples ? Ela só tem uma misera função (que vamos começar a chamar de método) que imprime "Ola Mundo". Como o objetivo da classe é estudarmos sua sintaxe, logo, não ligue muito para essa função tão tola.

class OlaMundo{

/**
* Classe de estudo cuja unica função é escrever Ola Mundo
*
* @author Chuck Norris.
*/
function imprime(){

echo( "Ola Mundo" );

}

}



Primeiro começamos dizendo que vamos escrever uma classe utilizando o comando class, pós-cedido de um espaço e o nome da classe que iremos criar. Darei dicas para uma boa nomenclatura de uma classe no próximo tópico. Logo após, colocamos o primeiro bracelete "{", escrevermos todos os métodos e atributos (veremos atributos depois) e finalizamos o método com o bracelete "}".

Em seqüência criamos os comentários. Isso é uma verdadeira preciosidade em qualquer código fonte. Utilizei o mesmo padrão usado pelo javadoc, onde o comentário deve dizer resumidamente o seguinte: O que o método faz, seu autor, o tipo de retorno que ela pode gerar (String, Array, Boolean, Integer, Double, Object) e os parâmetros (se houver). Como essa é uma classe pra estudo e portanto é bem simples, somente descrevi o método e coloquei seu autor. Sempre comente tudo o que você criar, a ponto de qualquer outro programador conseguir entender seu código se guiando apenas pelos comentários. Isso ajuda a deixar seus códigos auto-documentados.

Depois, criamos nosso primeiro método. Note que utilizei o comando function para dizer que o que vem após será um método. Assim como em uma função simples, devemos fornecer um nome ao método e, entre parênteses dizer se haverão parâmetros. Abrimos então o método com "{" e depois de tudo, fechamos com "}".

Claro que o método criado para o exemplo é extremamente simples. Mais tarde, veremos o uso do $this ( que faz referencia ao próprio objeto), modificadores de acesso( public, private e protected), o uso de atributos heranças e polimorfismo. Vamos prosseguir.


Cada macaco no seu galho.

Há uma filosofia no mundo Unix que é : "Não desenvolva coisas grandes que tenham inúmeras funções. Desenvolva coisas pequenas, que em primeiro lugar realize perfeitamente o propósito para qual elas foram designadas e, em segundo lugar, possam se encaixar uma com as outras, para que juntas possam fazer as mesmas inúmeras coisas mas com extrema perfeição".

Desenvolver seguindo a lógica Orientada a Objetos, não é você pegar todas as suas functions, escrever um "class NinhoDeUrubu { " no inicio do Armagedon e colocar um " } " no final. Como já disse, o principio do enca
psulamento é você criar blocos de código que irão se relacionar. Não adianta criar uma classe de conexão com o banco de dados e colocar métodos que irão manipular suas tabelas, envio de e-mail, contas a pagar, etc. Uma coisa é a classe de conexão, outra coisa são as suas tabelas, outra é enviar e-mails, e por ai vai.

Separe suas classes em arquivos diferentes e dê nome CERTO aos bois. Não chame a classe que irá manipular a tabela usuários de DbListaTodos . Pense com carinho na nomenclatura das suas classes. Tenho um amigo pseudo-chinês que sempre diz "O principio da sabedoria consiste em você chamar as coisas pelo nome". Chame a classe conexão com o banco de dados de algo parecido com ConectaBD , ou DBConnect caso há um padrão de nomenclatura em inglês. Outra coisa: assuma um padrão de nomenclatura para todas as suas classes. Veja um exemplo de como NÃO nomear as suas classes:

class connect_BasedeDados2eenviaemail {}

Vamos aos erros: separação visual com letras iniciais maiúsculas e underscore ao mesmo tempo; palavras em inglês e em português ao mesmo tempo (só faltou espanhol e kanji); nome grande que não diz muita coisa ( esta é a segunda classe de conexão ou ela se conecta ao segundo banco de dados ?); uma classe que conecta ao banco de dados e envia e-mail ? Conclusão : NUNCA coloque seu nome como autor desse anticristo.


Classes hoje, objetos amanhã.

Assumindo que você não saiba, um objeto nada mais é que a sua classe em ação, ou seja, nada mais é que a sua classe instanciada. Diferente de uma function, uma classe precisa ser inicializada ( transformada em objeto ) para poder ser utilizada. Veja o exemplo abaixo de uma função que imprime "ola mundo".

function ImprimeOlaMundo() {
echo("Ola mundo");
}


Para utilizar a função acima, basta somente você chamar a função da seguinte forma:

ImprimeOlaMundo();

E pronto. Seu texto aparecerá na tela. Agora, vamos construir isso utilizando uma classe ?

class OlaMundo{

/**
* Escreve Ola Mundo
*
* @author Chuck Norris.
*/
function imprime(){

echo( "Ola Mundo" );

}

}


Analisando a classe acima, podemos perceber que: ela se chama OlaMundo e tem um método chamado imprime() que cospe na tela o texto. Não adianta você escrever algo parecido com o seguinte:

OlaMundo(imprime());

Ao tentar fazer isso (leia-se besteira) você terá um erro catastrófico de sintaxe. Você precisa iniciar o seu objeto, utilizando a classe OlaMundo como base para esse objeto. Para isso você utilizará o construtor new, que cria um objeto no formato que você construiu sua classe. Veja o exemplo da utilização da classe acima.

$ObjetoOlaMundo = new OlaMundo();
$ObjetoOlaMundo->Imprime();

Ooooopa.... peraí, acaba de surgir um camarada novo em cena. Trata-se da seta ( -> ). Sinceramente, não faço a mínima idéia da onde Andi Gutmans tirou essa idéia de que a seta era mais prática ou tornava o código legível. Bom, mas ela existe e não pode ser ignorada. Essa seta serve para separar o objeto (a direta) da chamada de algum método ou atributo (à esquerda). A ordem é sempre a seguinte: $ (cifrão) nomeDoObjeto (objeto) -> (seta) chamadaDeAlgumaCoisa ( método ou atributo ). Em outras linguagens ( 99.9% das outras que tenha OO) a separação é feita não com seta, mas sim com ponto. Algo como $nomeDoObjeto.chamadaDeAlgumaCoisa.

Voltando ao exemplo do OlaMundo, veja que você criou um objeto chamado $ObjetoOlaMundo que é uma instância da classe OlaMundo(). Esse objeto agora pode utilizar todos os métodos ou atributos públicos da classe OlaMundo.

E quanto aos atributos, o que são ? Bom, eles são elementos que juntamente com os métodos, definem a estrutura de uma classe. Também chamados de variáveis de classe, eles são nada mais que uma espécie de "variáveis" onde são guardadas informações dentro da classe. Bom, é difícil ser simples demais sem pular vários conceitos, mas, A PRINCIPIO entenda atributos como um padrão para entrada de informação na classe. Vamos aprimorar a classe acima ? Além do Ola Mundo, vamos escrever o nome do usuário.


class OlaMundo{

var $nomeDoUsuario;

/**
* Escreve Ola Mundo
*
* @author Chuck Norris.
*/
function imprime(){

echo( "Ola Mundo e ola " . $this->nomeDoUsuario );

}
}



Ooooopa (novamente) .... Que história é essa de $nomeDoUsuario lá em cima ???? E que $this é esse no echo ? Simples: se lembra que foi dito que atributos são chamados também de variáveis de classe ? Pois bem, quando você cria uma variável FORA de algum método, essa variável ser torna automaticamente um atributo. Logo, o valor que estiver dentro do atributo $nomeDoUsuario poderá ser acessado por qualquer método da classe. O que eu fiz no echo do método imprime() foi justamente acessar o atributo criado.

Ah, quanto ao $this,
o conceito dele é um pouco mais complexo. Para simplificar, entenda que você necessita utilizá-lo toda vez que quiser chamar um atributo ou método dentro da mesma classe. No exemplo acima, eu utilizei o $this para alcançar o atributo nomeDoUsuario. Quando queremos chamar outros métodos pertencentes à mesma classe, nós também utilizamos o $this. Para você utilizar a classe acima, atribuindo um nome qualquer no atributo, basta somente você fazer o seguinte:


$ObjetoOlaMundo = new OlaMundo();
$ObjetoOlaMundo->
nomeDoUsuario = "Jeremias";
$ObjetoOlaMundo->Imprime();

Observações Finais.

Bom, por enquanto é isso. Acho que para um post eu passei bastante conteúdo. Eu tinha em mente passar modificadores de acesso( public, private e protected), o uso de heranças e polimorfismo no mesmo post, mas, acredito que vai ficar puxado para aqueles que estão vendo isso pela primeira vez. Vou criar um post futuro só com exemplos e depois continuamos. Minha meta é chegarmos o quanto antes em UML.


Links interessantes para você já ir lendo:

Centro de Computação da UNICAMP: http://www.ccuec.unicamp.br/revista/infotec/artigos/leite_rahal.html
Fernando Lozano, consultor independente: http://www.lozano.eti.br/palestras/oo-php.pdf

Se tiver alguma dúvida sobre o que já foi explicado, use os comentários.


Um abraço e sorte nos estudos.
Pedro Mendes

Simulando um With no PHP com Interfaces Fluentes

at 21/05/2008
tagged as #PHP
Pedro Mendes

Esses dias estava conversando com um grande colega programador sobre a carência do comando With no PHP. Estive procurando por algum tempo e como não tive uma solução que me agradasse joguei a idéia para o limbo.


Até que ontem, em mais uma das minhas noites de insônia, tive a idéia de simular o comando With com umas das melhores práticas de legibilidade de código: Fluents Interfaces, ou Interfaces Fluentes.


Primeiro Passo: Falando de Fluents Interfaces e PHP


Acredito que para muitos o termo "Interfaces Fluentes" não é novidade alguma. Mas, para quem não conhece, trata-se de uma maneira mais intuitiva de construir suas classes. Como a implementação de POO no PHP4 era deficiente (leia-se precária) não era possível a prática de Interfaces Fluentes graças à seguinte limitação: no PHP4 você não consegue criar uma referência direta ao objeto através do retorno dos seus próprios métodos.

Mas no PHP5 e sua OO totalmente reescrita, eis que tudo (ou quase) se fez novo. Agora, como a deficiência acima foi suprida, podemos facilmente fazer referencia direta ao objeto retornado por um dos seus próprios métodos.


Exemplo:

// Classe que retorna a própria referencia em todos os métodos
class escreveONomeCompletoUsandoInterfaceFluente {

public function escreveNome( $str ) {


// Escreve um nome qualquer
echo( $str );


// Retorna a referencia do próprio objeto
return $this;

}

public function escreveSobreNome( $str ) {


// Escreve um sobrenome qualquer
echo( $str );


// Retorna referencia ao próprio objeto
return $this;
}

}


Ao ler a classe de exemplo acima, você notará que eu sempre retorno o próprio objeto. Pois bem imaginemos uma possivel utilização NORMAL da classe acima:


$escreveNomeCompleto = new escreveONomeCompletoUsandoInterfaceFluente();
$escreveNomeCompleto->escreveNome( ‘ Pedro ‘ );
$escreveNomeCompleto->escreveSobreNome( ‘ Mendes ‘ );


Porém, como eu estou retornando o próprio objeto nos métodos da classe criada, a implementação Fluente do código seria a seguinte:


$escreveNomeCompleto = new escreveONomeCompletoUsandoInterfaceFluente();
$escreveNomeCompleto->escreveNome( ‘ Pedro ‘ )->escreveSobreNome( ‘ Mendes ‘ );


Desta forma, esta criada uma implementação simples das Fluents Interfaces no PHP. Como você pode perceber, a idéia central é você encadear a chamada dos seus métodos da seguinte forma: $objeto->metodo1()->metodo2()->metodo3()->…->metodofinal(); ao invés de ficar chamando o objeto a cada vez que você queira chamar um método.


Segundo Passo: Aplicando o conceito de Fluents Interfaces para alcançar o conceito de With


Em algumas linguagens você tem o comando With, que funcionada da seguinte forma:


With instanciaDoObjeto

metodoUm();
metodoDois();
metodoTres();

End With;


Com isso, você fornece a instância do objeto e simplesmente trabalha com seus atributos e/ou métodos dentro do bloco criado, diminuindo o código a ser escrito e deixando-o mais limpo. No PHP eu não achei nada que criasse o With diretamente, mas com o conceito de Interfaces Fluentes, o mesmo código acima poderia ficar da seguinte forma:


$instanciaDoObjeto
->metodoUm();
->metodoDois();
->metodoTres();


Pronto! Esta criado o conceito do With com uma estrutura mais aprimorada. Espero que tenham gostado e enviem suas duvidas/criticas/sujestões.



Um abraço,
Pedro Mendes

I've read and recommend

//]]>