goncin@wordpress.com:~$ _

Linux, programação e toda sorte de nerdices

Arquivos de etiquetas: PRADO

Apresentando o Yii Framework para PHP

Nos últimos quatro anos, trabalhei com o framework PRADO para PHP. Você pode conferir um pouco da minha experiência com ele aqui e ali também.

Quando iniciei com o PRADO, eu era um programador de aplicações desktop, e minha ferramenta predileta era o Borland Delphi Inprise Delphi CodeGear Delphi Embarcadero Delphi. Ao migrar para o ambiente web, a escolha de outra ferramenta que lembrasse o look and feel da antiga foi uma decisão natural, e isso foi-me proporcionado, em boa medida, pelo framework que escolhi.

O PRADO evoluiu, passou da versão 2.x para a 3.x, mas encontrou seu limite, como admitiu seu principal desenvolvedor. A partir do know how adquirido com o desenvolvimento do PRADO, Qiang Xue iniciou um novo framework, com o intuito de reimplementar o que o antecessor tinha de melhor, bem como aproveitar boas ideias introduzidas por outros projetos (veja a seção Credits). Assim vinha a público, em outubro de 2008, a primeira versão do Yii Framework.

Em julho de 2010, o Yii Framework encontra-se na versão 1.1.3, e conta com mais de duas centenas de extensões. Ele implementa rigidamente o padrão de desenvolvimento MVC, algo que o PRADO não fazia muito bem. Desde sempre, o Yii possui uma interface de linha de comando (o yiic), nos moldes do zf do Zend Framework, que automatiza tarefas como criar a estrutura de um projeto, scaffolding (geração de código CRUD), etc. A partir da versão 1.1.2, o framework passou a contar também com uma interface web, chamada Gii, para o scaffolding.

Para demonstrar o poder do Yii Framework, vamos gerar um modelo a partir de uma tabela com a seguinte estrutura:

CREATE TABLE `pessoa` (
  `cod_pessoa` INTEGER(11) NOT NULL AUTO_INCREMENT,
  `nome_pessoa` VARCHAR(100) COLLATE latin1_swedish_ci NOT NULL DEFAULT '',
  `data_nascimento` DATE NOT NULL,
  `sexo` CHAR(1) COLLATE latin1_swedish_ci NOT NULL DEFAULT '',
  PRIMARY KEY (`cod_pessoa`)
)ENGINE=InnoDB
AUTO_INCREMENT=1 CHARACTER SET 'latin1' COLLATE 'latin1_swedish_ci';

Eis o código gerado pelo Gii (ou via yiic shell -> model pessoa), a partir da estrutura acima:

<?php

/**
 * This is the model class for table "pessoa".
 *
 * The followings are the available columns in table 'pessoa':
 * @property integer $cod_pessoa
 * @property string $nome_pessoa
 * @property string $data_nascimento
 * @property string $sexo
 */
class Pessoa extends CActiveRecord
{
	/**
	 * Returns the static model of the specified AR class.
	 * @return Pessoa the static model class
	 */
	public static function model($className=__CLASS__)
	{
		return parent::model($className);
	}

	/**
	 * @return string the associated database table name
	 */
	public function tableName()
	{
		return 'pessoa';
	}

	/**
	 * @return array validation rules for model attributes.
	 */
	public function rules()
	{
		// NOTE: you should only define rules for those attributes that
		// will receive user inputs.
		return array(
			array('nome_pessoa, data_nascimento, sexo', 'required'),
			array('nome_pessoa', 'length', 'max'=>100),
			array('sexo', 'length', 'max'=>1),
			// The following rule is used by search().
			// Please remove those attributes that should not be searched.
			array('cod_pessoa, nome_pessoa, data_nascimento, sexo', 'safe', 'on'=>'search'),
		);
	}

	/**
	 * @return array relational rules.
	 */
	public function relations()
	{
		// NOTE: you may need to adjust the relation name and the related
		// class name for the relations automatically generated below.
		return array(
		);
	}

	/**
	 * @return array customized attribute labels (name=>label)
	 */
	public function attributeLabels()
	{
		return array(
			'cod_pessoa' => 'Cod Pessoa',
			'nome_pessoa' => 'Nome Pessoa',
			'data_nascimento' => 'Data Nascimento',
			'sexo' => 'Sexo',
		);
	}

	/**
	 * Retrieves a list of models based on the current search/filter conditions.
	 * @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.
	 */
	public function search()
	{
		// Warning: Please modify the following code to remove attributes that
		// should not be searched.

		$criteria=new CDbCriteria;

		$criteria->compare('cod_pessoa',$this->cod_pessoa);

		$criteria->compare('nome_pessoa',$this->nome_pessoa,true);

		$criteria->compare('data_nascimento',$this->data_nascimento,true);

		$criteria->compare('sexo',$this->sexo,true);

		return new CActiveDataProvider(get_class($this), array(
			'criteria'=>$criteria,
		));
	}
}

Como podem perceber, o código gerado para o modelo é bastante completo. O gerador aproveita as configurações existentes no banco de dados para estabelecer regras de validação (veja na função rules()): campos NOT NULL tornam-se atributos requeridos, o comprimento máximo de um atributo do tipo string é o mesmo definido no campo VARCHAR correspondente, etc. Define, inclusive, os rótulos dos atributos a partir dos nomes dos campos (função attributeLabels()), bastando uma pequena edição para que apareçam ao usuário final num português correto.

Meu propósito neste post foi apresentar o Yii Framework e um pouco do seu poder. Se você já conhece ou já trabalha com ele, compartilhe suas impressões nos comentários. Aos demais desenvolvedores PHP, espero ao menos tê-los atiçado a curiosidade e os deixado com água na boca 8) . Para quem deseja se iniciar no framework, recomendo seguir o Tutorial de Criação de um Blog, cujos passos podem ser facilmente adaptados para as necessidades do seu projeto.

PRADO para PHP 5: Active Controls (AJAX)

Post publicado originalmente em http://www.devfranca.com.br/2009/08/14/prado-para-php-5-active-controls-ajax/ em 14 de agosto de 2009.

Olá pessoal! Este é o segundo post da série sobre o framework PRADO para PHP 5. Se você chegou aqui diretamente, leia o primeiro post, pois estenderemos o projeto iniciado ali.

No primeiro projeto, implementamos um formulário simples que utiliza o método postback para o envio de requisições ao servidor web. O inconveniente desse método é o recarregamento da página inteira para que a exibição do resultado do processamento seja possível.

Uma forma melhor de obter o mesmo resultado, sem a desagradável atualização da página toda, é utilizar o método callback, que por sua vez se utiliza da tecnologia AJAX (Asynchronous Javascript and XML), capaz de atualizar apenas a região da página efetivamente alterada.

Quem desenvolve para a web sabe que trabalhar com AJAX pode ser penoso, principalmente se lidarmos diretamente com Javascript e XMLHTTPRequest. Felizmente, o Prado nos dá uma grande ajuda neste ponto, encapsulando as requisições AJAX em seus próprios componentes. E o que é melhor: em muitos casos, não é necessário sequer mexer com o Javascript!

Como assim? Vejamos como isso funciona na prática. Para começar, vamos fazer uma cópia de nosso projeto olamundo e renomeá-la como olamundo-2.0.

No arquivo /protected/pages/Home.page, vamos trocar os controles TTextBox, TButton e TLabel pelos seus “irmãos ativos”: TActiveTextBox, TActiveButton e TActiveLabel:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title></title>
</head>
<body>
  <h1>Olá, mundo!</h1>
  <com:TForm>
    Qual é o seu nome? <com:TActiveTextBox ID="txtNome" />&nbsp;
    <com:TActiveButton ID="btnEnviar" Text="Enviar" OnClick="Page.btnEnviarClick" />
    <br />
    <com:TActiveLabel ID="lblCumprimento" />
  </com:TForm>
</body>
</html>

Essa é toda a alteração necessária neste arquivo.

No arquivo /protected/pages/Home.php, vamos acrescentar apenas uma linha ao início do arquivo, antes da declaração da classe:

<?php

Prado::using('System.Web.UI.ActiveControls.*');

class Home extends TPage {

  public function btnEnviarClick($sender, $param) {
    $this->lblCumprimento->Text = "Olá, " . $this->txtNome->Text . "!";
  }

}

Como os controles ativos, por padrão, não são carregados automaticamente pelo PRADO, aquela linha serve para dizer ao framework que queremos utilizá-los. E isso é tudo. Você poderá ver o novo projeto em ação aqui e, se tiver olhos atentos, perceberá que a tela não “pisca” mais antes da exibição da saudação.

Para os mais “cismados”, e também para deixar nosso usuário ciente do que está acontecendo nos bastidores, vamos fazer um novo upgrade do projeto, agora para a versão olamundo-2.1. Acrescentaremos um notificador de atividade que será exibida na página enquanto a requisição AJAX vai e volta: uma div vermelha contendo o texto “Aguarde…”.

Vamos mexer no /protected/pages/Home.php:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title></title>
<!-- STYLE acrescentado -->
<style>
  #notif {
    background-color:#F00;
    color: #FFF;
    position:absolute;
    visibility:hidden;
  }
</style>
</head>
<body>
  <!-- DIV acrescentada -->
  <div id="notif">Aguarde...</div>
  <h1>Olá, mundo!</h1>
  <com:TForm>
    Qual é o seu nome? <com:TActiveTextBox ID="txtNome" />&nbsp;
    <!-- Propriedades ClientSide Acrescentadas -->
    <com:TActiveButton ID="btnEnviar" Text="Enviar" OnClick="Page.btnEnviarClick"
      ClientSide.OnLoading="$('notif').style.visibility='visible'"
      ClientSide.OnLoaded="$('notif').style.visibility='hidden'" />
    <br />
    <com:TActiveLabel ID="lblCumprimento" />
  </com:TForm>
</body>
</html>

Foram acrescentados um estilo (para configurar a DIV com fundo vermelho, posicionamento absoluto e sem visibilidade inicial), a DIV propriamente dita e configuradas duas novas propriedades do componente TActiveButton: ClientSide.OnLoading e ClientSide.OnLoaded. A primeira propriedade contém um código Javascript (finalmente!) a ser executado quando a requisição é despachada para o servidor e a segunda o código para quando a resposta chegar. Em nosso projeto, a lógica é simples: enviou a requisição, exibe a DIV; a resposta chegou, oculta a DIV. O resultado disso? Veja aqui.

Os mais atentos vão notar que, nas duas linhas Javascript foi utilizado o atalho $(‘notif’) ao invés do longo e tedioso document.getElementById(‘notif’). Isso porque o PRADO também não tem a intenção de reinventar a roda, e, ao contrário, incorpora algumas das melhores soluções desenvolvidas por terceiros. No caso do Javascript, o PRADO já traz consigo o Prototype (de onde vem o atalho $) e o script.aculo.us, entre outros.

Fico por aqui com este post, esperando ter sido didático na minha exposição. Para terminar, zipei as três versões do olamundo, juntamente com o PRADO, e fiz upload aqui, para facilitar. Para quem tem uma instalação PHP 5, basta descompactar num diretório acessível pelo seu servidor web.

Um abraço, e até a próxima!

PRADO: (não apenas mais um) framework para o PHP 5


Olá, pessoal! Este é o meu primeiro post aqui no devFranca. O objetivo dele é apresentar o framework PHP com o qual trabalho, e que acho bastante interessante para o desenvolvimento de aplicações web. Não deixe de comentar após a leitura. :)

Há cerca de três anos, percebi que as aplicações estavam migrando para a web, e a partir dessa constatação decidi mudar meu foco de desenvolvimento. Até então, meu trabalho consistia em desenvolver programas para desktop, e minha ferramenta favorita era o Delphi (embora eu já tivesse trabalhado também com o VB). Eu não era nenhum estrangeiro nas terras do desenvolvimento web, tendo já trabalhado por quatro anos com o ASP, e conhecia, portanto, as limitações dessa plataforma.

Como simpatizante das tecnologias opensource, escolher o PHP foi a decisão natural. Naquele momento, eu iria iniciar um projeto PHP do zero, e percebi que reinventar a roda não seria inteligente nem produtivo. Foi daí que parti em busca de um framework, uma caixa de ferramentas mais ou menos prontas, que me poupasse o esforço de codificar muita coisa “na unha”.

Após algumas perguntas ao Grande Oráculo, deparei-me com o PRADO (sigla para PHP Rapid Application Development Object-oriented). Dentre tantos frameworks para PHP, chamou minha atenção no PRADO o seu “jeitão” inspirado no Delphi, de que tomou emprestado vários conceitos, como a utilização de componentes e eventos, além de uma hierarquia de classes nitidamente inspirada na VCL.

classtree

Hoje, o PRADO já está na versão 3.1.6 3.1.7, e pode ser baixado gratuitamente aqui aqui, sob a licença BSD revisada. O framework vem num arquivo compactado (padrão ZIP), bastando descompactá-lo, mantendo a estrutura de diretórios, numa pasta acessível pelo seu servidor web (Apache, IIS, etc.).

Pois bem, deixemos de blablablá e vamos colocar a mão na massa, criando nosso primeiro projeto em PRADO, que terá o nome de olamundo (sugestivo e original, não?). O PRADO trabalha com uma estrutura de pastas predefinida, dentro da qual criaremos alguns arquivos, conforme mostra a figura abaixo.

O arquivo index.php, que fica na pasta-raiz do projeto, terá o conteúdo seguinte:

<?php
require('path/to/prado.php');

$application=new TApplication;

$application->run();

E só. Não se esqueça de trocar <pasta do PRADO> pelo caminho da pasta onde você instalou o PRADO.

O arquivo /protected/pages/Home.page, apesar da extensão pouco usual, é apenas um arquivo HTML no qual inserimos, além das tags padrão, as tags especiais do PRADO. No nosso projeto, seu conteúdo será o seguinte:

<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title></title>
</head>
<body>
  <h1>Olá, mundo!</h1>
  <com:TForm>
    Qual é o seu nome? <com:TTextBox ID="txtNome" />&nbsp;
    <com:TButton ID="btnEnviar" Text="Enviar" OnClick="Page.btnEnviarClick" /><br />
    <com:TLabel ID="lblCumprimento" />
  </com:TForm>
</body>
</html>

Veja que eu negritei as tags especiais do PRADO. Elas representam os componentes, que por sua vez vão se transformar depois em código 100% HTML. Aqui, utilizei três componentes: TTextBox (que se tornará uma caixa de texto), TButton (um botão) e TLabel (uma área de texto estático, que será renderizada como <span>). Note que nesse arquivo não há nenhum código PHP, e essa é exatamente a intenção: separar o que é design do que é código, implementando assim o paradigma MVC (Model-view-controller).

O PRADO é totalmente orientado a objeto. Por isso, a toda página do aplicativo corresponde uma classe, derivada de TPage (como você pode ver logo mais abaixo). Cada classe de página requer dois arquivos, um .page (para a parte visual) e outro .php (para o código). Ambos os arquivos devem ter o mesmo nome, que deve coincidir também com o nome da classe. O padrão para a página inicial do PRADO é Home (há como alterar isso, criando um arquivo de configuração personalizado, assunto que ficará para uma próxima oportunidade). Tudo muito bom, mas cadê o código PHP? Está no arquivo /protected/pages/Home.php:

<?php

class Home extends TPage {

  public function btnEnviarClick($sender, $param) {
    $this->lblCumprimento->Text = "Olá, "  .  $this->txtNome->Text . "!";
  }

}

Note que, no arquivo Home.page, há um atributo OnClick na tag do TButton, referenciando um método chamado Page.btnEnviarClick. Pois bem, esse método é implementado em Home.php. Acho que todos conseguiram sacar o que o nosso “aplicativo” vai fazer: pegar o nome digitado na caixa de texto e apresentar uma saudação a ele. Quem quiser ver a coisa funcionando ao vivo e em preto-e-branco (desculpe, gente, não deu tempo de colocar CSS para deixar coloridinho :p), clique aqui.

Esse primeiro projeto implementa um formulário pelo método postback, no qual os dados são enviados ao servidor para processamento e a página é completamente recarregada para exibir o resultado. No meu próximo post, vou mostar como, com pouquíssimas alterações, é possível transformar esse aplicativo numa chamada callback, devolvendo o resultado sem recarregar a página. Em suma, veremos como o PRADO trabalha com AJAX – e isso sem mexer numa linha sequer de Javascript!

Bom gente, aqui chega ao fim minha primeira colaboração. Espero que tenham gostado. Até mais!

Seguir

Obtenha todo post novo entregue na sua caixa de entrada.

%d bloggers like this: