Criando um Data Grid com POO e PHP5
Um data grid nada mais é do que a apresentação de dados em forma de tabela (lembra das <table></table>? Algo assim). Cada conjunto de registros é mostrado em uma linha, e o data grid pode ter funcionalidades de ordenação dos dados e opções para sua edição ou exclusão.
Classe Data Grid PHP
Com esta simples classe é possÃvel criar um data grid a partir de um array com os dados que queremos apresentar na tabela. É simples criar e configurar e, com alguns comandos avançados, é possÃvel alterar o seu comportamento para que seja possÃvel implementar as necessidades habituais em uma estrutura desse tipo.
Essa classe foi criada com POO (Programação Orientada a Objetos) e caracterÃsticas que estão disponÃveis somente a partir do PHP5. Ela pode ser baixada clicando aqui.
Vamos começar a ver como funciona a classe utilizando um exemplo simples e inserindo funcionalidades no decorrer do artigo, para deixar nosso exemplo mais robusto.
Para começar é necessário inserir a classe nos scripts PHP antes de utilizá-la.
//incluimos a classe
require 'DataGrid.php';
Agora temos que criar um Array com os dados que serão apresentados no Data Grid. Será um array associativo, duas dimensões, onde a primeira, o array principal, receberá todos os registros a serem mostrados no data Grid, e na segunda estão cada um dos registros definidos como um array associativo.
Agora construÃmos o array com um algumas informações, mais adiante veremos como construir esse array através de uma consulta ao banco de dados.
//criamos o array com os dados a serem apresentados no Data Grid
$alunos = array(
array("id" => 1, "nome" => "Pepe Perez", "curso" => "Informática básica", "nivel" => 2),
array("id" => 2, "nome" => "MarÃa Suarez", "curso" => "Informática avançada", "nivel" => 1),
array("id" => 3, "nome" => "Roberto Soriano", "curso" => "Sistemas operacionais", "nivel" => 2),
array("id" => 5, "nome" => "Alberto Rodriguez", "curso" => "Inglés técnico", "nivel" => 1),
array("id" => 7, "nome" => "Julia Marcos", "curso" => "Sociologia", "nivel" => 3),
array("id" => 10, "nome" => "Socorro Rozas", "curso" => "Informática básica", "nivel" => 1),
array("id" => 11, "nome" => "Pablo Reñones", "curso" => "Informática básica", "nivel" => 2)
);
Agora, antes de continuarmos com a construção da estrutura, temos que criar alguns estilos CSS para podermos melhorar o aspecto do Data Grid
<style type="text/css">
.linhaI{background-color:#ffffcc;}
.linhaP{background-color:#ffcc99;}
.fdg_sortable {cursor:pointer;text-decoration:underline;color:#00c;}
</style>
Foram criadas três classes CSS, com seus respectivos estilos. As classes “linhaI” (linha Ãmpar) e “linhaP” (linha par) aplicaram estilo à s linhas do Data Grid e a classe “fdg_sortable” é responsável por estilizar os tÃtulos de cada coluna do Data Grid.
Vamos criar o data grid a partir dos dados que temos no array.
//instanciamos o objeto data grid, passando como parâmetro o array anterior
Fete_ViewControl_DataGrid::getInstance($alunos)
//VAMOS LANÇANDO DIVERSOS MÉTODOS SOBRE O OBJETO INSTANCIADO
//atributos gerais para a tabela
->setGridAttributes(array('cellspacing' => '3?, 'cellpadding' => '4?, 'border' => '0?))
//permitimos que hajam caracterÃsticas de ordenação
->enableSorting(true)
//fazemos um setup das colunas do data grid, indicando o valor que será mostrado na primeira linha do data grid
->setup(array(
'id' => array('header' => 'ID'),
'nome' => array('header' => 'Nome'),
'curso' => array('header' => 'Curso'),
'nivel' => array('header' => 'Nivel curso')
))
//definimos os estilos para as linhas Ãmpares
->setRowClass('linhaI')
//definimos os estilos para as linhas pares
->setAlterRowClass('linhasP')
//chamamos o método que construirá o data grid
->render();
Todas as linhas foram comentadas para que o entendimento se torne mais simples.
Agora vejamos como inserir ou apagar coisas do data grid, para personalizá-lo. Faremos algumas coisas como:
- Vamos ocultar o “ID” do array associativo, para que não seja mostrado.
- No campo de nÃvel do cursos, vamos mostrar o nÃvel com alguns asteriscos usando uma função que converterá os números em uma cadeia de asteriscos.
- Vamos coluna no data grid, que aparecerá antes de qualquer outra, para mostrar um contador que indicará a quantidade de registros apresentados.
Destas três coisas, a mais complicada é fazer um modelo para alterar a forma como é mostrado um campo. Para começar, precisaremos de uma função que devolva o dado que se quer mostrar, com o formato desejado.
function nivel_estrelas($num){
$estrelas = "";
for ($i=0; $i<$num; $i++){
$estrelas .= "*";
}
return $estrelas;
}
Utilizaremos essa função para atribuir como “template” para o campo nÃvel de curso.
Vamos agora ao código utilizado para implementar todas as funcionalidades citadas no data grid:
//OCULTAR UM CAMPO NO DATA GRID
//COLOCAR UMA FUNÇÂO PARA MOSTRAR UM CAMPO
//COLOCAR UM CAMPO ANTES DAS COLUNAS DO ARRAY DO DATA GRID
Fete_ViewControl_DataGrid::getInstance($alunos)
->setGridAttributes(array('cellspacing' => '3?, 'cellpadding' => '4?, 'border' => '0?))
->enableSorting(true)
//fazemos com que o campo "id" do array associativo não seja mostrado
->removeColumn('id')
->setup(array(
'nome' => array('header' => 'Nome'),
'curso' => array('header' => 'Curso'),
//utilizamos a função template para mostrar o nivel do curso com umas estrelas
'nivel' => array('header' => 'Nivel curso', 'cellTemplate' => '[[nivel_estrelas:%data%]]')
))
//inserimos uma coluna em todos os registros do data grid(a primeira coluna será esta)
//nesta coluna mostramos um contador de registros
->addColumnBefore('Contador', '%counter%.', 'Num', array('align' => 'right'))
//definimos a partir de que número será iniciado o contador
->setStartingCounter(1)
->setRowClass('linhaI')
->setAlterRowClass('linhaP')
->render();
Novamente as linhas foram comentadas para facilitar o entendimento. Chamo a atenção sobre a linha que faz uso da função anterior como um template para um campo.
'nivel' => array('header' => 'Nivel curso', 'cellTemplate' => '[[nivel_estrelas:%data%]]')
Isto faz com que o campo “nivel”, quando for mostrado em linhas distintas do data grid, chame a função nivel_estrelas(), passando como parâmetro %data%, que é o valor que tem cada um dos registros do array associativo, no campo “nÃvel”.
Por último vamos ver outro exemplo, um pouco mais desenvolvido, para mostrar os dados do mesmo array. Neste caso vamos simplesmente mostrar uma coluna adicional ao final de cada registro do data grid, onde iremos inserir uns links para editar e/ou apagar o registro atual.
//PARA COLOCAR UM BOTÃO PARA EDITAR OU APAGAR
Fete_ViewControl_DataGrid::getInstance($alunos)
->setGridAttributes(array('cellspacing' => '3?, 'cellpadding' => '4?, 'border' => '0?))
->enableSorting(true)
->removeColumn('id')
->setup(array(
'nome' => array('header' => 'Nome'),
'curso' => array('header' => 'Curso'),
'nivel' => array('header' => 'Nivel curso', 'cellTemplate' => '[[nivel_estrelas:%data%]]')
))
->addColumnBefore('Contador', '%counter%.', 'Num', array('align' => 'right'))
//agora mostro um campo depois de cada elelemto, com links para editar ou apagar o registro
//no interior deste campo utilizo $id$ para enviar o valor "id" do array
->addColumnAfter('actions', '<a href="exemplo3.php?editar=$id$">Editar</a> ?
<a href="exemplo3.php?apagar=$id$" onclick="return confirm('Está certo que quer apagar $nome$?')">Apagar</a>', 'Actions', array('align' => 'center'))
->setStartingCounter(1)
->setRowClass('linhaI')
->setAlterRowClass('linhaP')
->render();
Neste exemplo apenas inserimos uma linha de código para fazer uma chamada ao método addColumnAfter(), que serve para inserir uma coluna depois das colunas que formamos com o array.
->addColumnAfter('actions',
'<a href="exemplo3.php?editar=$id$">Editar</a> ? <a
href="exemplo3.php?apagar=$id$" onclick="return confirm('Está certo que
quer apagar $nome$?')">Apagar</a>', 'Actions', array('align'
=> 'center'))
Neste caso simplesmente temos que indicar como parâmetro a addColumnAfter() dois dados: o primeiro para especificar um tÃtulo para a coluna e o segundo para especificar o seu conteúdo. O conteúdo dessa coluna, neste caso, são os links para editar e apagar, onde são utilizadas urls que enviam os dados por GET, que é o identificador do registro.
Montando o data grid a partir de um banco de dados
Só falta agora falar sobre como extrair os dados de uma base de dados para fazer o array de elementos que será utilizado na montagem do data grid.
No exemplo que acompanha a classe data_grid há um código para extrair a informação do MySQL, como pode ser visto nas linhas abaixo.
$users = array();
$result = mysql_query("SELECT * FROM user", $dbLinkId);
while ($row = mysql_fetch_assoc($result))
{
$users[] = $row;
}
Como se pode ver, primeiro se cria um array e logo se faz um looping pelos resultados da consulta. Cada um dos elementos retornados pela consulta será introduzido no array criado anteriormente e para ele assinalamos o array associativo que nos devolverá mysql_fetch_assoc() desse primeiro array.
Bom, pessoal, espero que esse artigo possa ser útil a vocês. Clique abaixo para poder fazer o download da classe e de um exemplo.
Clique aqui para baixar a classe data grid junto com um exemplo
Fonte: Imasters
Frameworks no PHP: O que, quando, por que e qual?
PHP é a linguagem de programação mais famosa do mundo por várias razões: flexibilidade, facilidade de uso e vários outros fatores. Mas algumas vezes a programação se torna monótona e/ou repetitiva, e é aà que um framework pode ajudar.
O que é um framework de PHP?
De forma resumida o framework é uma estrutura, uma fundação para você criar a sua aplicação. Em outras palavras o framework te permite o desenvolvimento rápido de aplicações (RAD), o que faz economizar tempo, ajuda a criar aplicações mais sólidas e seguras além de reduzir a quantidade de código repetido. Os frameworks também permitem que os iniciantes criem aplicações mais estáveis garantindo uma boa relação entre o banco de dados e a camada externa de exibição. Isso tudo te permite gastar mais tempo desenvolvendo a aplicação em si do que repetindo os códigos que todas as aplicações têm.
A idéia padrão de trabalho por trás de um framework no PHP está ligada ao modelo MVC (Model View Controller). MVC é uma forma de programação que isola a lógica de negócio (como a aplicação funciona) da camada de exibição (a parte visual). O Model cuida do banco de dados, o View cuida da camada de exibição e o Controller cuida da lógica de negócio. Isso tudo faz com que você trabalhe mais rápido e de forma setorizada.
Por que usar um framework de PHP?
Os desenvolvedores utilizam frameworks por vários motivos, e o maior deles é para agilizar o processo de desenvolvimento. A re-utilização de código em vários projetos vai economizar muito tempo e trabalho? Isso é garantido, pois o framework já traz uma série de módulos pré-configurados (e funcionando) para fazer as mais variadas e comuns tarefas como envio de e-mails, conexão com o banco de dados, sanitização (limpeza) de dados e proteção contra ataques.
Estabilidade é outra grande vantagem dos frameworks. A simplicidade, que é um dos grandes “feitos” do PHP, também é o que possibilita inúmeros erros e falhas pelos principiantes? Nem todo código que funciona necessariamente está correto e bem desenvolvido.
Quando usar um framework de PHP?
Essa é uma dúvida muito comum em todos os nÃveis de desenvolvimento. Para a maioria dos iniciantes, usar um framework, além de ser mais fácil, vai ser mais estável, então é bom usá-los sempre que possÃvel.
Em contrapartida vários programadores experientes vêem os frameworks como ferramentas usadas por programadores fracos, que não sabem como criar um código limpo, sólido e seguro.
Quando se trabalha com projetos que têm um prazo muito curto (o que eu chamo de “prazo Jack Bauer”) é sempre bom usar um framework, pois ele vai agilizar todo o processo. Outro motivo forte para o uso do framework é que você não está criando “código artesanal”? Há todo um padrão que você deve seguir para que as coisas funcionem, e está tudo documentado e explicado em uma vasta comunidade de suporte.
CakePHP
O CakePHP é uma grande opção para iniciantes e desenvolvedores avançados. Ele foi criado usando as bases e modelos do Ruby on Rails e é pesadamente focado no desenvolvimento ágil e rápido. Recentemente ele tem se tornado muito famoso por sua simplicidade e facilidade de uso.
Eu pessoalmente recomendo o CakePHP. Minha vida de programador mudou depois que eu comecei a usar ele.
Zend Framework
O Zend Framework é um framework focado no desenvolvimento de aplicações pra web 2.0. Ele tem um grande número de seguidores, fontes de suporte e uma comunidade cheia de usuários ativos e participativos. O Zend é o framework mais famoso hoje em dia, ele é robusto e permite a criação de aplicações enterprise (de grande porte) mas seu uso exige um conhecimento vasto do PHP.
CodeIgniter
Já o CodeIgniter é bastante conhecido pela sua facilidade de uso, performance e rapidez. É ideal para aplicações rodando em servidores compartilhados. Ele oferece soluções simples e de pequeno porte, com um grande número de tutoriais em vÃdeo, fóruns e wikis.
Fonte: Imasters
Conectando C# ao MySQL
Quem está habituado a programar C# normalmente utiliza SQL Server como banco de dados, uma vez que ela está integrada no Visual Studio e, por isso mesmo, existe grande facilidade em trabalhar com as duas ferramentas.
Por vezes existem projetos em que se torna conveniente (por várias razões) utilizar outro tipo de base de dados. Seja que banco de dados for, a sua integração é sempre diferente do SQL Server.
Neste caso vou mostrar como fazer a integração entre o C# e o MySQL.
Supondo que já existe uma instalação do MySQL na máquina, precisamos instalar um intermediário entre o C# e a base de dados. Neste caso necessitamos instalar o MySQL Connector NET.
A versão 5.2 já tem suporte ao Visual Studio 2008, mas eu vou utilizar a última versão (6.0).
Instalamos o Connector Net 6.0.
Devemos já ter uma base de dados com uma tabela (users por exemplo), em que os campos da tabela são: id, nome, email.
Como exemplo criamos um projecto Windows Forms Application.
Antes de mais nada, devemos fazer uma referência à classe que vai ligar o C# ao MySQL. Para isso vamos ao painel Solution Explorer, na raiz do projeto, clicamos com o lado direito do mouse e selecionamos Add Reference.

Na primeira divisória (.NET) selecionamos a referência MySQL.Data e damos OK.
Não esquecer: incluir no inÃcio do código as classes:
using System.Data;
using MySql.Data.MySqlClient;
Sem adicionar a referência à MySQL.Data, a classe MySql.Data.MySqlClient não será reconhecida.
Para exemplificar fazemos um formulário de inserção de dados (nome e e-mail) na base de dados.
No form colocamos duas caixas de texto, uma para o nome (txtNome) e outra para o e-mail (txtMail) e um botão que terá a ação de inserir os dados na base de dados.

Vamos então definir, em primeiro lugar, o dataset e a string de conexão à base de dados.
private MySqlConnection bdConn; //MySQL
private MySqlDataAdapter bdAdapter;
private DataSet bdDataSet; //MySQL
Na ação do botão:
//Definição do dataset
bdDataSet = new DataSet();
 //Define string de conexão
bdConn = new MySqlConnection("Persist Security  Info=False;server=localhost;database=rfidapp;uid=root;server=localhost;database=rfidapp;uid=root;pwd=''");
Neste caso a base de dados não tem password.
//Abre conecção
 try{
    bdConn.Open();
}
catch{
 MessageBox.Show("ImpossÃvel estabelecer conexão");
}
//Verifica se a conexão está aberta
if (bdConn.State == ConnectionState.Open)
{
    //Se estiver aberta insere os dados na BD
MySqlCommand commS = new MySqlCommand("INSERT INTO regists VALUES('',\\'" + txtNome + "\\',\\'" + txtMail + "\\')", bdConn);
commS.BeginExecuteNonQuery();
}
Tome atenção na sintaxe do SQL para o MySQL (INSERT) que é um pouco diferente do C#/SQL Server.
Neste momento o formulário deverá inserir dados no BD.
Fonte: Imasters
O que é o Google Wave?
O Google anunciou, na sexta passada, uma ideia nova e experimental para modificar o futuro da comunicação na Web. O nome é Wave (“Onda”) e, se você acreditar no seu desenvolvedor, é “o que o email seria se fosse inventado hoje”. Além disso, vai ser totalmente open source. Já está intrigado?
Primariamente, o Wave tem como objetivo melhorar a comunicação em tempo real na web. Aqui tem um vÃdeo de quase hora e meia com a apresentação completa aos desenvolvedores na conferência Google I/O, mas se você não quiser ou não tiver tempo de ver, fique com os detalhes diretamente da boca do Google:
O QUE É UMA WAVE?
Uma wave é conversação e documento em partes iguais. As pessoas podem se comunicar e trabalharem juntos com texto formatado, imagens, vÃdeos, mapas e mais.
Uma wave é compartilhada. Qualquer participante pode responder em qualquer ponto da mensagem, editar o seu conteúdo e adicionar participantes em qualquer ponto do processo. A função Playback permite que qualquer um retroceda a Wave passo a passo desde o inÃcio, para ver quem disse o quê e quando.
Uma wave é viva. Com a transmissão instantânea à medida que você digita, os participantes de uma wave podem ter conversações mais rápidas, ver edições e interagir com extensões em tempo real.

Bastante amplo, né? O Google Wave é claramente algo que precisaremos ver em ação, usar mesmo, antes de entender completamente como funciona. Da mesma forma que o email, o Wave foi desenvolvido como um padrão que poderá ser rodado a partir de qualquer servidor, então ele não vai pertencer ao Google. Qualquer um vai poder ter o seu próprio Wave, e este Wave pode competir com o do Google ou se comportar como o dono quiser. Mas, sendo criado sobre um protocolo padrão, Waves diferentes podem entender e se comunicar entre si, da mesma forma que o Outlook pode trocar emails normalmente com um Thunderbird, GMail ou Yahoo Mail.
Isso resolve um problema que eu (e muitos outros bem mais inteligentes que eu) sempre tive com o Twitter: ele vive nos servidores de uma empresa, e a sua informação está suscetÃvel ao que quer que a empresa queira fazer com ela. RSS, email e mensagens instantâneas trabalham com protocolos padrões que podem ser utilizados por qualquer um. É o exemplo dos emails que eu dei acima.
O blog TechCrunch fez uma análise bem detalhada do Wave (link lá no fim, em inglês) e dos rumos que o Google tomou com ele até agora. O Wave ainda é incrivelmente novo e pouco desenvolvido, mas também é muito intrigante sob o ponto de vista do Futuro-da-Internet e coisa assim. Pode não dar em nada, mas considerando as reações que teve e a popularidade de serviços como o Twitter e o Facebook, a ideia de um protocolo que transforma uma comunicação deste tipo em padrão aberto soa muito promissora.
O Wave não está disponÃvel de nenhuma forma para mim e para você por enquanto, e muito da tecnologia por trás dele depende das atualizações do HTML 5, que não estarão disponÃveis pelo menos por mais um pouco de tempo, mas no site oficial você pode se inscrever para atualizações do Google Wave se estiver ansioso por toda e qualquer novidade do desenvolvimento. (N.T.: Eu mais do que certamente estou.)
Fonte: Imasters
Manipulação de dados BLOB com PHP e MySQL
Sem dúvida alguma, uma das perguntas mais frequentes em relação ao MySQL é: “como posso armazenar arquivos em uma base de dados?”. A resposta é: tens que usar o tipo de dados BLOB. Estes BLOBs (Binary Large Objects) podem armazenar praticamente qualquer tipo de dados, incluindo documentos do MS Word, imagens gif/jpeg, arquivos PDF, mp3, etc.
Neste artigo vamos ver como criar um repositório de arquivos binários usando PHP e MySQL para poder armazenar diferentes tipos de arquivos. Veremos como armazenar cada um dos arquivos em uma base de dados, para posteriormente recuperá-los.
Para testar os exemplos deste artigo, é necessário ter acesso a um servidor com suporte a PHP, além de contar com um servidor MySQL. Assumindo que você conte com os privilégios apropriados para criar a base dados, e que o MySQL está rodando no mesmo servidor que o PHP, vamos iniciar o desenvolvimento.
Criando a base de dados
Nosso repositório de documentos usará uma base dados que contenha unicamente uma tabela para armazenar todos os documentos. O banco de dados será chamado de “repositorio“, e a tabela de “arquivos“.
Código SQL para criar a tabela
CREATE TABLE arquivos(
id int not null auto_increment primary key,
nome varchar(50),
titulo varchar(50),
conteudo mediumblob,
tipo varchar(50));
Agora temos uma base chamada repositorio, que contém uma tabela chamada arquivos.
Veja abaixo informações sobre cada campo da tabela arquivos:
- id - um número inteiro que nos proporcionará um identificador único para cada arquivo que iremos armazenar. Este será incrementado automaticamente cada vez que for inserido um novo registro.
- nome - o nome original do arquivo, por exemplo, fot.gif, curriculum.doc, etc.
- titulo - uma breve descrição de cada arquivo que será gravada na tabela, por exemplo “Carta para minha noiva”, ou “A foto do meu irmão”. Este tÃtulo será usado posteriormente na visualização dos arquivos do repositório em uma página web.
- conteudo – um campo do tipo binário (blob) para guardar o conteúdo de cada arquivo. Na nossa tabela usamos um tipo mediumblob, o qual pode armazenar arquivos de até 16Mb.
- ipo – como veremos mais adiante, cada arquivo (seja um .doc, .gif, .pdf, etc) tem um tipo único. Quando se envia um
arquivo para o servidor web através de uma página web, o navegar envia ao servidor a informação acerca do tipo de arquivo, o tipo de conteúdo do arquivo, etc. Os tipos de conteúdo são simples cadeias. O tipo de conteúdo para um arquivo MS WORD é “application/msword”, o tipo de conteúdo para uma imagem é “image/gif”, etc.
Agregando arquivos à base de dados
Agora que temos a base de dados do nosso repositório e sabemos a finalidade de cada campo, vamos criar uma simples página web que permita selecionar um arquivo desde o navegador para posteriormente enviá-lo para um script em PHP que ficará encarregado de armazená-lo em nossa base de dados.A página web será nomeada escolher_arquivo.html e o script em PHP será chamado de guardar_arquivo.php.
A página web pode conter todo o código HTML que se deseje, mas é necessário que se inclua o seguinte formulário para que se tenha a opção de escolher um arquivo e enviá-lo ao servidor.
<!-- ...código anterior -->
<form enctype="multipart/form-data" action="guardar_arquivo.php" method="post">
Descrição <input type="text" name="titulo" size="30">
Arquivo <input type="file" name="arquivo">
<input type="submit" value="Enviar arquivo">
</form>
<!-- ...código posterior -->
Do código que escrevemos temos que frisar o seguinte:
- o formulário necessita de um atributo enctype com um valor multipart/form-data
- o método de envio tem que ser POST
- tem que ser usado pelo menos um campo do tipo FILE
Estes são os três requerimentos básicos que a página HTML deve cumprir para que seja possÃvel enviar o arquivo para o servidor.
Antes de escrever o código do script guarda_arquivo.php, vamos comentar algo acerca da forma como serão recebidos os dados do arquivo em questão.
Desde a versão 4.1 do PHP é recomendada a utilização da variável $_FILES para a leitura dos dados do arquivo que está sendo enviado ao servidor. Abaixo estão listadas os Ãndices e parâmetros recebidos pela variável. Note que o nome dos Ãndices depende de como é nomeado o campo do tipo FILE no formulário.
$_FILES['arquivo']['name']
Nome original do arquivo
$_FILES['arquivo']['type']
O tipo MIME do arquivo, … image/gif, application/pdf, application/msword,.. etc
$_FILES['arquivo']['size']
O tamanho do arquivo em bytes
$_FILES['arquivo']['tmp_name']
O local do arquivo temporário que se cria quando o arquivo é enviado ao servidor. É nesta variável que são lidos todos os dados do arquivo em si. Se estes dados não são copiados ou movidos para outro lugar, ou em nosso caso, armazenados em uma base de dados, podem ser perdidos, já que o PHP elimina esses arquivos depois de um determinado tempo.
Por exemplo, estes são os possÃveis valores para um arquivo j-odbc.zip que foi enviado ao servidor:
$_FILES["arquivo"][name] => j-jdbc.zip
$_FILES["arquivo"][type] => application/zip
$_FILES["arquivo"][tmp_name] => /tmp/phpvXQpqP
$_FILES["arquivo"][size] => 337945
Vale ressaltar que devem ser revistos e, se necessário modificar as seguintes variáveis no arquivo de configuração do PHP para que você possa fazer o upload dos arquivos para o servidor, e pode ser gerida por um script PHP.
- file_uploads – diz ao PHP se pode ou não ser feito o envio de arquivos para o servidor. Essa variável deve ter o valor “On”.
- upload_max_filesize – diz ao PHP qual o tamanho máximo do arquivo que pode ser enviado ao servidor. Pode ser utilizado o sufixo “M” para indicar o valor em Megabytes, por exemplo, com um valor 2M se aceita um arquivo máximo de 2 Megabytes.
- upload_tmp_dir – é o diretório para onde será copiado temporariamente o conteúdo do arquivo quando for enviado ao
servidor.
Agora é o momento de mostrar o código PHP que vai armazenar o arquivo em nossa base de dados.
/* guardar_arquivo.php */
require("dbconnect.inc.php");
 $arquiivo = $_FILES["arquivo"]["tmp_name"];
 $tamanho = $_FILES["arquivo"]["size"];
 $tipo   = $_FILES["arquivo"]["type"];
 $nome  = $_FILES["arquivo"]["name"];
 $titulo  = $_POST["titulo"];
 if ( $arquivo != "none" )
 {
 $fp = fopen($arquivo, "rb");
 $conteudo = fread($fp, $tamanho);
 $conteudo = addslashes($conteudo);
 fclose($fp);
 $qry = "INSERT INTO arquivos VALUES
 (0,'$nome','$titulo','$conteudo','$tipo')";
 mysql_query($qry);
 if(mysql_affected_rows($conn) > 0)
 print "O arquivo foi gravado na base de dados.";
 else
 print "Não foi possÃvel gravar o arquivo na base de dados.";
 }
 else
 print "Não foi possÃvel carregar o arquivo para o servidor.";
O arquivo dbconnetc.inc.php contém unicamente as instruções para conexão ao MySQL e selecionar a base de dados que será utilizada.
/* dbconnect.inc.php */
$conn = mysql_connect("localhost","usuário","senha");
 mysql_select_db("repositorio");
Listando os arquivos da base de dados
Já que gravamos alguns arquivos no nosso repositório, agora podemos listar as informações deles, para posteriomente fazermos o download.
/* listar_arquivos.php */
require("dbconnect.inc.php");
$qry = "SELECT id, nome, titulo, tipo FROM arquivos";
$res = mysql_query($qry);
while($fila = mysql_fetch_array($res))
{
print "$fila[titulo]
<br>
$fila[nome] ($fila[tipo])
<br>
<a href='baixar_arquivo.php?id=$fila[id]'>Fazer Download</a>
<br>
<br>";
}
Fazendo o download dos arquivos da base de dados
Como se pode observar no código anterior, foi colocado um link para cada arquivo, chamado baixar_arquivo.php. A funcionalidade deste script será ler os dados dos arquivos que estão gravados na base de dados e enviá-los ao navegador.
Dependendo do tipo de arquivo da qual se trate, o navegador poderá mostrá-lo por ele mesmo o conteúdo do arquivo.
/* Script baixar_arquivo.php */
require("dbconnect.inc.php");
 $qry = "SELECT tipo, conteudo FROM arquivos WHERE id=$id";
 $res = mysql_query($qry);
 $tipo = mysql_result($res, 0, "tipo");
 $conteudo = mysql_result($res, 0, "conteudo");
 header("Content-type: $tipo");
 print $conteudo;
Comentário Finais
Como se pode observar, o código PHP dos scripts é bem simples, e não tem nenhum grau de dificuldade. O código foi desenvolvido com o propósito mais simples possÃvel, para que possa ser melhorado e utilizado em aplicações mais robustas.
Fonte: Imasters
Google Earth no meu site
O que o Google diz sobre isto?
O plug-in do Google Earth e a API JavaScript permitem incorporar o Google Earth, um verdadeiro globo digital em 3D, nas suas páginas da web. Usando a API, você pode desenhar marcadores e linhas, dispor imagens sobre a área, adicionar modelos em 3D ou carregar arquivos KML, permitindo criar aplicativos sofisticados para mapas em 3D. Se você tem um site de API do Google Maps, pode ativar 3D em sua página com uma única linha de código.
Ótimo, podemos utilizar a API do Google Maps! Vamos ver então um exemplo simples da API do Google Earth e vamos também utilizar o nosso exemplo do artigo anterior (Colocando minha empresa no mapa), onde utilizamos a API do Google Maps, para incluir um novo Servidor de Mapas que será o Google Earth.
Bom, aconselho você ler o artigo anterior antes de seguir, pois necessitamos obter uma chave de segurança da API do Google para utilizá-la neste exemplo. Segue o link (Obtendo uma Chave de API).
Vamos ao Hello, Earth!
Obtendo o Pluggin para rodar o Google Earth no seu browser
Não adianta você ter instalado o Google Earth na sua máquina. Você precisa de um plugin especÃfico para rodar esta API no seu browser.
Para instalar, acesso o link http://code.google.com/apis/earth/ e clique no mapa para baixar o plugin.

Instale o plugin na sua máquina e pronto. Você já pode rodar o Google Earth no seu browser.
Vamos ao código:
<html>
 <meta http-equiv="content-type" content="text/html; charset=utf-8" />
 <head>
  <title>Hello Google Earth!</title>
    <!-- Adicionando a API (!!Não esqueça de alterar a sua chave!!)-->
  <script src="http://www.google.com/jsapi?key=SUA_CHAVE_AQUI"></script>
  <script>
    google.load("earth", "1");
    var ge = null;
    // Função Inincial -> Chamada no OnLoad
    function init() {
     // Instancia o Objeto dentro da DIV map3d,
     // caso sucesso, chama a função initCallback, senão, failureCallback
     google.earth.createInstance("map3d", initCallback, failureCallback);
    }
    function initCallback(object) {
     ge = object; //Adiciona o Objeto na variável global ge
     //Dá visibilidade ao Google Earth dentro do navegador.
     ge.getWindow().setVisibility(true);
    }
    function failureCallback(object) { }
  </script>
 </head>
 <body onload='init()' id='body'>
  <center>
   <div id='map3d_container'
      style='border: 1px solid silver; height: 600px; width: 800px;'>
    <div id='map3d' style='height: 100%;'></div>
   </div>
  </center>
 </body>
</html>
Resultado

Pronto, temos apenas um Hello World acima, uma visão do globo geral.
Para visualizar um exemplo de como adicionar controles de navegação, escala, grid, mapa de referência, etc, acesse este link: http://earth-api-samples.googlecode.com/svn/trunk/demos/options/index.html.
É muito simples ampliar as ferramentas do seu mapa.
Integrando o Google Earth API no Google Maps API
Ok, vamos pegar o nosso exemplo do artigo anterior e integrar com o a API Google Earth.
Lembram do código?

Resultado

Alterando o código

- Alteramos as linhas 8,9,10: trocamos a API do Google Maps pela API do Google Earth
- Linha 14: Adicionado o Load da API do Google Maps
- Linha 23: Adicionado o Layer do Google Earth
- Linha 27: Adicionado os controles de layers
Como ficou

Não se esqueça, acesse o site dos desenvolvedores, http://code.google.com/intl/pt-BR/apis/earth/, e visualize os exemplos e as referências das APIs do Google Maps e Google Earth. Apenas com os exemplos disponibilizados pelo Google você aumenta a qualidade do seu site sem muito esforço.
Fonte: Imasters
Barra de Progresso com AJAX
Uma das necessidades com que nos deparamos na hora de realizar projetos longos na web é indicar ao usuário o quanto é preciso esperar. Às vezes é bastante complicado criar uma barra de progresso que mostre o estado atual do processo que está sendo executado.
Uma forma de realizar essa tarefa é usando AJAX. Fazemos uma chamada AJAX que executa a ação, e quando o objeto AJAX tem o estado LOADING (readyState == 3), podemos obter a resposta do script chamado e passá-lo para mostrar o percentual da ação que está sendo realizada.
Para isso, desenvolveremos um script (res. php, por exemplo) que devolva a porcentagem seguida por um hÃfen. Por exemplo, quando passar por 1% será retornado pelo script “1-”, quando passar por 5% será retornado “1-2-3-4-5″. Processando isso podemos saber, através do último número, o percentual já processado.
O PHP seria o seguinte:
for($i=0; $i<10000000; $i++) {
if ($i%10000 == 0) echo ((int) $i/100000).'-';
flush();
}
E o JavaScript seria assim:
function ajaxobj() { Â
try { Â
_ajaxobj = new ActiveXObject("Msxml2.XMLHTTP"); Â
} catch (e) { Â
try { Â
_ajaxobj = new ActiveXObject("Microsoft.XMLHTTP"); Â
} catch (E) { Â
_ajaxobj = false; Â
} Â
} Â
if (!_ajaxobj && typeof XMLHttpRequest!='undefined') { Â
_ajaxobj = new XMLHttpRequest(); Â
} Â
return _ajaxobj; Â
}
function prueba () { Â
ajax = ajaxobj(); Â
ajax.open("GET", "res.php", true); Â
ajax.onreadystatechange=function() {
if (ajax.readyState == 3) { Â
// Mostramos o percentual
var res = ajax.responseText;
res = res.split('-'); Â
alert(res[res.length-2]); Â
} else if (ajax.readyState == 4) { Â
// Fim
alert('FIM'); Â
} Â
} Â
// Enviamos algo para que o processo funcione
ajax.send(null); Â
} Â
Como não existe nada perfeito, e menos ainda o Internet Explorer, esse script só funcionou no Firefox, Opera, Safari e Chrome.
Fonte: Imasters
Colocando minha empresa no mapa…
Este artigo, por mais simples que seja, tende a ser uma das maiores dúvidas e desejos dos usuários que estão iniciando nesta área. Como colocar minha empresa, estabelecimento, casa etc., no mapa. Com certeza no seu site é muito importante existir além do endereço da sua empresa um pequeno mapa representando tudo que está em volta dela para que os usuários possam se localizar mais facilmente.
Nosso foco hoje é criar um mapa utilizando a API do Google Maps. Com isso, não precisamos de nenhum banco de dados geográfico ou qualquer outro tipo de aplicação para desenvolvimento de mapas além das linguagens HTML e JavaScript.
Segundo o próprio Google, o que é a API do Google Maps?
A API do Google Maps permite usar JavaScript para incorporar o Google Maps em sua página da web. A API fornece diversos utilitários para manipular mapas (como na página http://maps.google.com) e adicionar conteúdo ao mapa através de diversos serviços. Você pode criar aplicativos de mapas robustos em seu site.
Passo 1: Obtendo uma chave para a API do Google Maps.
Para utilizarmos a API do Google, precisamos obter uma chave de identificação para o nosso site. É muito importante que você coloque a URL correta do caminho onde estará o mapa, caso contrário, ao instanciar a API no seu código, ela não funcionará.
Acesse o link : http://code.google.com/intl/pt-BR/apis/maps/signup.html, preencha as informações da URL do seu site e clique em GERAR chave de API. Não se esqueça de ler os termos de uso da API, nada de utilizá-la dentro de intranets.

Obs.: Você precisa ter um usuário cadastrado no Google para obtê-la.

Pronto, chave gerada, podemos ir para o próximo passo.
Passo 2: Obtendo o XY da sua empresa
Inicialmente, para identificarmos a sua empresa/estabelecimento/etc no mapa, precisamos da localização correta dela. A localização que comento é com relação ao seu XY. Mas o que é XY? Vamos à matemática…
Para a construção do modelo da superfÃcie topográfica de uma dada região, necessitamos das triplas (x, y, z) de uma série de pontos da superfÃcie do terreno. Os valores (x, y, z) são as coordenadas cartesianas de um ponto P, relativas a um sistema de coordenadas preestabelecido (como já vimos em meu outro artigo Sistemas de Informação Geográfica).
O plano XY é o plano horizontal de referência relativamente ao nÃvel médio dos mares, e z é a distância vertical do ponto P ao plano horizontal XY (se me permitem exemplificar desta maneira, seria a altura em relação ao nÃvel do mar, no nosso caso, não será necessária).
Como posso obter este ponto?
Existem diversas maneiras de se obter o XY de um endereço, vou exemplificar duas: a primeira é suscetÃvel a alguns erros, motivo pelo qual o mapeamento da numeração das ruas nas cidades do Brasil não ser de fato correto (mas confesso que é satisfatório). O que quero dizer é que muitas vezes quando você informa o seu endereço, por exemplo o número 567, seriam 567 metros do ponto inicial da sua rua, nem sempre esta numeração irá bater exatamente no local da sua casa (quando digo exatamente, ainda considero um erro de 50m). Pode acontecer de aparecer na quadra errada; quando ocorrer, sugiro utilizar o segundo exemplo de aquisição do XY.
A primeira maneira que me refiro é solicitar através da url http://maps.google.com/maps/geo?q=STRING+DO+ENDERECOoutput=xmlkey=SUA_CHAVE
Obs.: Separe a string com “+”.
Exemplo:
http://maps.google.com/maps/geo?q=avenidaipiranga1200portoalegrersbrasiloutput=xmlkey=
Exemplo da resposta (response) em XML:

Pronto, seu XYZ é a coordenada <coordinates>-51.2093204,-30.0451247,0</coordinates> .
Agora você pode pular o segundo exemplo e ir direto ao passo 3, mas antes vamos verificar se o ponto está mesmo no local correto.
Acesso o seguinte link:
http://maps.google.com.br/maps?f=qsource=s_qhl=pt-BRgeocode=q=(-30.0451247,-51.2093204)
OBS: Lembre-se de alterar a ordem dos pontos XY <-> YX
A segunda maneira de se obter as coordenadas XY é implementar um outro exemplo utilizando a API do Google Maps. Chamamos este exemplo de Geocode Reverso (através de um clique no mapa iremos obter as informações quanto a este local).
O exemplo abaixo está presente na página da API do Google Maps, mantive-o como o qual para explicar cada linha.
Código
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<title>Google Maps JavaScript API Example: Reverse Geocoder</title>
<script src="http://maps.google.com/maps?file=apiv=2.xkey=ABQIAAAAzr2EBOXUKnm_jVnk0OJI7xSosDVG8KKPE1-m51RBrvYughuyMxQ-i1QfUnH94QxWIa6N4U6MouMmBA"
type="text/javascript"></script>
<script type="text/javascript">
var map;
var geocoder;
var address;
function initialize() {
map = new GMap2(document.getElementById("map"));
map.setCenter(new GLatLng(-30.0270583,-51.2303402), 10);
map.addControl(new GLargeMapControl);
GEvent.addListener(map, "click", getAddress);
geocoder = new GClientGeocoder();
}
function getAddress(overlay, latlng) {
if (latlng != null) {
address = latlng;
geocoder.getLocations(latlng, showAddress);
}
}
function showAddress(response) {
map.clearOverlays();
if (!response response.Status.code != 200) {
alert("Status Code:" response.Status.code);
} else {
place = response.Placemark[0];
point = new GLatLng(place.Point.coordinates[1],
place.Point.coordinates[0]);
marker = new GMarker(point);
map.addOverlay(marker);
marker.openInfoWindowHtml(
'<b>orig latlng:</b>' response.name '<br/>'
'<b>latlng:</b>' place.Point.coordinates[1] "," place.Point.coordinates[0] '<br>'
'<b>Status Code:</b>' response.Status.code '<br>'
'<b>Status Request:</b>' response.Status.request '<br>'
'<b>Address:</b>' place.address '<br>'
'<b>Accuracy:</b>' place.AddressDetails.Accuracy '<br>'
'<b>Country code:</b> ' place.AddressDetails.Country.CountryNameCode);
}
}
</script>
</head>
<body onload="initialize()">
<div id="map" style="width: 500px; height: 400px"></div>
</body>
</html>


Você já viu um exemplo da resposta (response) em XML no exemplo anterior.
Exemplo da resposta (response) em JSON:

Através dos arquivos acima, você consegue identificar quais as variáveis necessárias para obter os dados do geocode.
Por fim e não menos importante, o corpo do HTML:
<body onload="initialize()">
  <div id="map" style="width: 500px; height: 400px"></div>
    <div id="temp"></div>
 </body>
Não se esqueça de utilizar o ONLOAD para chamar a função initialize() para tão logo carregar a página iniciar o procedimento da criação do mapa. Não quero ver ninguém comentando que o mapa não aparece!
Pronto, agora navegue no mapa, procure o endereço da sua empresa (ainda não criamos uma barra de pesquisa de endereço, nos próximos artigos irei explicar como), clique no local e copie as informações da linha latlng.
Agora temos o XY para continuar no nosso artigo.
Passo 3: Adicionando minha empresa no mapa
Bom, se você já criou o exemplo anterior do geocode reverso, este agora é muito mais simples. Caso contrário, vamos lá passo a passo.
Vamos ao código
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>Google Maps JavaScript API Example: Simple Markers</title>
<script src="http://maps.google.com/maps?file=apiamp;v=2amp;key=
ABQIAAAAzr2EBOXUKnm_jVnk0OJI7xSosDVG8KKPE1-m51RBrvYughuyMxQ-i1QfUnH94QxWIa6N4U6MouMmBA"
type="text/javascript"></script>
<script type="text/javascript">
function initialize() {
if (GBrowserIsCompatible()) { // Verifica se o browser é compativel com a API do Google
// Instância a API do Google e a adiciona na DIV map.
var map = new GMap2(document.getElementById("map"));
// Centraliza o mapa no XY, zoom 16 em uma escala de [1..17] (Varia de acordo com a região)
map.setCenter(new GLatLng(-30.0451247,-51.2093204), 16);
// (OPCIONAL) Adiciona os controle de a esquerda do Mapa (Zoom , Zoom -, barra de Zoom, etc)
map.addControl(new GLargeMapControl);
// Padronizamos o XY de acordo com o latlng da API: (Y,X)
var latlng = new GLatLng(-30.0451247,-51.2093204);
map.addOverlay(new GMarker(latlng)); // Adiciona o marker no mapa
}//if
}//function
</script>
</head>
<body onload="initialize()" onunload="GUnload()">
<div id="map" style="width: 500px; height: 300px"></div>
</body>
</html>

OBS: Não se esqueça de trocar a sua chave da API. Não se esqueça de declarar o ONLOAD, para que a função initialize(), no meu exemplo, crie o mapa assim que a página seja carregada.
Resultado

Caso você queira incrementar o seu mapa e adicionar um evento de clique no marker, façamos algumas modificações no código:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>Google Maps JavaScript API Example: Simple Markers</title>
<script src="http://maps.google.com/maps?file=api&v=2&key=
ABQIAAAAzr2EBOXUKnm_jVnk0OJI7xSosDVG8KKPE1-m51RBrvYughuyMxQ-i1QfUnH94QxWIa6N4U6MouMmBA"
type="text/javascript"></script>
<script type="text/javascript">
function initialize() {
if (GBrowserIsCompatible()) { // Verifica se o browser é compativel com a API do Google
// Instância a API do Google e a adiciona na DIV map.
var map = new GMap2(document.getElementById("map"));
// Centraliza o mapa no XY, zoom 16 em uma escala de [1..17] (Varia de acordo com a região)
map.setCenter(new GLatLng(-30.0451247,-51.2093204), 16);
// (OPCIONAL) Adiciona os controle de a esquerda do Mapa (Zoom +, Zoom -, barra de Zoom, etc)
map.addControl(new GLargeMapControl);
// Padronizamos o XY de acordo com o latlng da API: (Y,X)
var latlng = new GLatLng(-30.0451247,-51.2093204);
var marker = new GMarker(latlng); // Criamos um marker referenciado a uma variável
// Criamos um evento para ao se clicar no marker
GEvent.addListener(marker, "click", function() {
// Abrir um InfoWindow com o seguinte texto
marker.openInfoWindowHtml("Endereço da minha empresa! <br/> <strong>;)</strong>");
});
map.addOverlay(marker); // Adiciona o marker no mapa
}//if
}//function
</script>
</head>
<body onload="initialize()" onunload="GUnload()">
<div id="map" style="width: 500px; height: 300px"></div>
</body>
</html>

Pronto!
Adobe Flex – Como colocar gráficos em repeater
Estou desenvolvendo um modelo de Dashboard de Indicadores de Performace (KPI) utilizando o Adobe Flex, Asp.NET e SQL Server 2000.
Nesse Dashboard eu precisava exibir vários gráficos de acordo com o perfil de cada usuário. Por isso, construir um modelo fixo não seria possÃvel. Então busquei maneiras de fazer isso utilizando o mx:Tile e o mx:Repeater.
Na busca encontrei apenas um exemplo de Datagrid em um Repeater, com isso foi possÃvel construir o modelo para utilizar com Gráficos.
Primeiro é preciso entender a estrutura de DataProvider, necessária para que tudo funcione como o esperado.

Como na figura acima, o DataProvider é um ArrayCollection composto de um ArrayCollection para cada gráfico que será exibido no Repeater, cada um desse segundo ArrayCollection é composto por objetos que serão os pontos dos gráficos.
Abaixo está o código responsável pela configuração do ArrayCollection, que será o DataProvider do mx:Repeater.
<mx:Script>
    <![CDATA[
        import mx.utils.ObjectProxy;
        import mx.core.Application;
        import mx.utils.ObjectUtil;
        import mx.rpc.events.FaultEvent;
        import mx.rpc.events.ResultEvent;
        import mx.collections.ArrayCollection;
        //ArrayCollection que será o DataProvider do Repeater
        [Bindable]
        private var arDadosGraficoTotal:ArrayCollection = new ArrayCollection();
        private function load():void
        {
            var arDadosGrafico:ArrayCollection;
            var obDadosGrafico:ObjectProxy;
            //Gráfico 1
            //arDadosGrafico recebe um novo ArrayCollection
            arDadosGrafico = new ArrayCollection();
            //obDadosGrafico recebe um novo ObjectProxy
            obDadosGrafico = new ObjectProxy();
            //Cria a propriedade data1 e atribiu o 10, data1 será uma série no gráfico
            obDadosGrafico.data1 = 10;
            //Cria a propriedade data2 e atribiu o 5, data2 será outra série no gráfico
            obDadosGrafico.data2 = 05;
            //Cria a propriedade label e atribiu 'Jan', label será o eixo X do gráfico
            obDadosGrafico.label = 'Jan';         Â
//Cria a propriedade titulo e atribiu 'Vendas', titulo será o titulo do
gráfico, só existirá essa propriedade no primeiro ObjectProxy
            obDadosGrafico.titulo = 'Vendas';   Â
            //Adiciona o ObjectProxy obDadosGrafico ao ArrayCollection arDadosGrafico   Â
            arDadosGrafico.addItem(obDadosGrafico);
//obDadosGrafico recebe um novo ObjectProxy e receberá os mesmas
propriedades porém com valores distintos e também é inserido ao
ArrayCollection arDadosGrafico
            obDadosGrafico = new ObjectProxy();
            obDadosGrafico.data1 = 05;
            obDadosGrafico.data2 = 05;
            obDadosGrafico.label = 'Fev';         Â
            arDadosGrafico.addItem(obDadosGrafico);
            obDadosGrafico = new ObjectProxy();
            obDadosGrafico.data1 = 03;
            obDadosGrafico.data2 = 05;
            obDadosGrafico.label = 'Mar';         Â
            arDadosGrafico.addItem(obDadosGrafico);
            obDadosGrafico = new ObjectProxy();
            obDadosGrafico.data1 = 06;
            obDadosGrafico.data2 = 05;
            obDadosGrafico.label = 'Abr';         Â
            arDadosGrafico.addItem(obDadosGrafico);
//Quando terminam os pontos do gráfico é necessário inserir o
ArrayCollection arDadosGrafico ao ArrayCollection arDadosGraficoTotal
            arDadosGraficoTotal.addItem(arDadosGrafico);  Â
//Os passos anteriores devem ser feitos para cada gráfico que se deseja
exibir no Dashboard, abaixo estão identificos como Gráfico 2 e Gráfico 3
            //Gráfico 2
            arDadosGrafico = new ArrayCollection();
            obDadosGrafico = new ObjectProxy();
            obDadosGrafico.data1 = 07;
            obDadosGrafico.data2 = 02;
            obDadosGrafico.label = 'Jan';         Â
            obDadosGrafico.titulo = 'Custos';           Â
            arDadosGrafico.addItem(obDadosGrafico);
            obDadosGrafico = new ObjectProxy();
            obDadosGrafico.data1 = 08;
            obDadosGrafico.data2 = 02;
            obDadosGrafico.label = 'Fev';         Â
            arDadosGrafico.addItem(obDadosGrafico);
            obDadosGrafico = new ObjectProxy();
            obDadosGrafico.data1 = 05;
            obDadosGrafico.data2 = 02;
            obDadosGrafico.label = 'Mar';         Â
            arDadosGrafico.addItem(obDadosGrafico);
            obDadosGrafico = new ObjectProxy();
            obDadosGrafico.data1 = 04;
            obDadosGrafico.data2 = 02;
            obDadosGrafico.label = 'Abr';         Â
            arDadosGrafico.addItem(obDadosGrafico);
            arDadosGraficoTotal.addItem(arDadosGrafico);  Â
            //Gráfico 3
            arDadosGrafico = new ArrayCollection();
            obDadosGrafico = new ObjectProxy();
            obDadosGrafico.data1 = 10;
            obDadosGrafico.data2 = 08;
            obDadosGrafico.label = 'Jan';         Â
            obDadosGrafico.titulo = 'Produção';          Â
            arDadosGrafico.addItem(obDadosGrafico);
            obDadosGrafico = new ObjectProxy();
            obDadosGrafico.data1 = 12;
            obDadosGrafico.data2 = 08;
            obDadosGrafico.label = 'Fev';         Â
            arDadosGrafico.addItem(obDadosGrafico);
            obDadosGrafico = new ObjectProxy();
            obDadosGrafico.data1 = 06;
            obDadosGrafico.data2 = 08;
            obDadosGrafico.label = 'Mar';         Â
            arDadosGrafico.addItem(obDadosGrafico);
            obDadosGrafico = new ObjectProxy();
            obDadosGrafico.data1 = 08;
            obDadosGrafico.data2 = 08;
            obDadosGrafico.label = 'Abr';         Â
            arDadosGrafico.addItem(obDadosGrafico);
            arDadosGraficoTotal.addItem(arDadosGrafico);  Â
//Ao terminado de incluir todos os arDadosGrafico ao
arDadosGraficoTotal, é necessário declarar arDadosGraficoTotal como
dataProvider do repeater
            rpGrafico.dataProvider = arDadosGraficoTotal; Â
        }       Â
    ]]>
</mx:Script>
Abaixo está o código necessário para exibir os gráficos. Inicialmente foi utilizado um Tile e dentro um Repeater. Dentro do Repeater há um Panel e dentro do Panel está o gráfico que deve ser exibido de acordo com o dataProvider.
Como demonstrado acima, o dataProvider é associado ao término da função load(). Após a associação, o Repeater começará a renderizar o primeiro gráfico, e já no tÃtulo do Panel o valor atribuÃdo será a propriedade tÃtulo definida no primeiro objeto do arDadosGrafico.
Para isso é utilizada a instrução: {rpGrafico.currentItem.getItemAt(0).titulo}, ou seja, rpGrafico é o Repeater, a propriedade currentItem contém o arDadosGrafico do laço em questão e getItemAt(0) assegura que só buscará a propriedade tÃtulo no primeiro objeto dentro do arDadosGrafico.
Para o gráfico, só resta associar um dataProvider a ele para que sejam exibidos os seus pontos. O dataProvider em questão será o currentItem do Repeater rpGrafico, pois como dito acima, a propriedade currentItem contém o arDadosGrafico do laço em questão.
No eixo X, horizontalAxis, é definido label como o campo fonte dos dados. No eixo Y, verticalAxis, está configurado para não começar em zero. Logo abaixo estão as duas séries, uma para o data1 (Indicador Técnico) e outra para data2 (Meta).
<mx:Tile left="10" right="10" top="10" bottom="10" direction="horizontal">
    <mx:Repeater id="rpGrafico" width="100%">
    <mx:Panel width="250" height="200" layout="absolute" id="pnGrafico" title="{rpGrafico.currentItem.getItemAt(0).titulo}">
<mx:LineChart id="grIndicador" dataTipMode="single"
showDataTips="true" dataProvider="{rpGrafico.currentItem}" width="95%"
height="95%" horizontalCenter="0" verticalCenter="0">
            <mx:horizontalAxis>
            <mx:CategoryAxis categoryField="label" />               Â
        </mx:horizontalAxis>                                      Â
            <mx:verticalAxis>
                <mx:LinearAxis baseAtZero="false"/>
            </mx:verticalAxis>                                       Â
            <mx:series>          Â
            <mx:LineSeries form="segment" yField="data2" displayName="Meta"/>
            <mx:LineSeries form="segment" yField="data1" displayName="Indicador Técnico"/>
            </mx:series>
        </mx:LineChart>
    </mx:Panel>
    </mx:Repeater>
</mx:Tile>
Antes de executar o projeto e ver tudo funcionando legal, é necessário adicionar o código abaixo na segunda linha do código dentro da tag mx:Application
creationComplete=”load()”
Deixando-a assim:
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="load();">
Execute o projeto, você deve obter um resultado igual a imagem abaixo.

Complementando?
Para incluir as legendas basta adicionar logo após o gráfico o código abaixo:
<mx:Legend dataProvider="{grIndicador[0]}" bottom="10" left="10" right="10" height="25"/>

Fonte: Imasters
Crie Arquivos .ZIP com ASP.NET
Neste artigo vou mostrar como criar arquivos .ZIP e como descompactar utilizando o ASP.net.
Imagem de exemplo do exemplo deste artigo.
Um pouco de conhecimento antes de programarmos
Arquivos .zip é um formato muito conhecido. Em Matemática, um dos modos de se obter uma compressão de arquivos, é através de Transformada de Fourier. A compressão e compactação são importantÃssimas para conseguirmos informações em tempos menores de transmissão, de forma mais barata possÃvel.
Qual a diferença entre Compressão e Compactação?
A principal diferença entre os dois termos é que compactação não há perda de informação, enquanto que na compressão há perda. O Formato .MP3 é um exemplo de Compressão, pois há perda de informação, embora nossos ouvidos não notem muito. Mesmo entre os Mp3, temos aqueles com maior qualidade (menos perda) e os de menores qualidades (maior perda).
Entre os métodos mais conhecidos de compactação estão:
- Codificação por carreira
- Codificação por Shannon-Fano
- Codificação de Huffman (muito utilizado para compactar texto)
- Codificação de Lempel-Ziv-Welch (LZW)
- Codificação aritmética
Entre os métodos mais conhecidos de compressão estão:
- Redução do domÃnio
- Redução do espaço de quantização
- Codificação preditiva
- Codificação por sub-bandas
- Codificação por transformadas
- Quantização vetorial
Pré-requisitos
Este artigo foi montado nas configurações abaixo. Não foi testado em outros ambientes.
- Framework ASP.NET 2.0 com VB.net
- Visual Studio 2005.
Mãos a obra
Clique aqui para dar download no projeto de exemplo.
Primeiro, crie uma solução no seu VisualStudio. Adicione um novo projeto Web, e referencie a Biblioteca SharpZLib.
Caso você esteja usa utilizando a versão Express, crie um novo website, e coloque ICSharpCode.SharpZipLib.dll na pasta /bin.
Em seguida, vamos criar uma página chamada zip.ASPX.
Compactando Diretório Inteiro
Para compactar o diretório, você terá que informar o diretório de origem e o arquivo de destino.
''' <summary>
  ''' Evento do botão, gerar diretório
  ''' </summary>
  Protected Sub btnGerar_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnGerar.Click
    gerarZipDiretorio(txtOrigem.Text, txtDestino.Text)
    subInitDescompactarArquivos()
  End Sub
  ''' <summary>
  ''' Este método gera um zip, a partir de um diretório
  ''' </summary>
  ''' <param name="sDiretorioOrigem">
  ''' Diretório que será zipado
  ''' </param>
  ''' <param name="sDiretorioDestino">
  ''' Diretório que receberá o arquivo zipado
  ''' </param>
  ''' <remarks>
  ''' </remarks>
  Public Sub gerarZipDiretorio(ByVal sDiretorioOrigem As String, ByVal sDiretorioDestino As String)
    Dim sz As New FastZip()
    Dim sArquivoZip As String = String.Empty
    ' Aqui vou criar um nome do arquivo, com 6 caracteres randômicos.
    ' O Guid é um método do .net que gera string aleatórias únicas, baseada na hora e no
    ' endereço MAC na máquina gerada.
    sArquivoZip = "MeuZip" & Left(Guid.NewGuid.ToString, 6) & ".zip"
    ' Só um tratamento para garantir mais estabilidade
    If Right(sDiretorioOrigem, 1) <> "\" Then
      sDiretorioOrigem = sDiretorioOrigem & "\"
    End If
    ' Só um tratamento para garantir mais estabilidade
    If Right(sDiretorioDestino, 1) <> "\" Then
      sDiretorioDestino = sDiretorioDestino & "\"
    End If
    If Not Directory.Exists(sDiretorioDestino) Then
      lblErro.Text = "O Diretório de Destino informado não existe: <br />" & sDiretorioDestino
      Exit Sub
    End If
    If Not Directory.Exists(sDiretorioOrigem) Then
      lblErro.Text = "O Diretório de Origem informado não existe: <br />" & sDiretorioOrigem
      Exit Sub
    End If
    sz.CreateZip(sDiretorioDestino & sArquivoZip, sDiretorioOrigem & "" & "\", True, "", "")
    ' Aqui eu habilito o download do arquivo.
    ' Muito útil se você quiser salvar em diretórios protegidos
    ' Ou não acessÃvel pela raÃz do seu projeto web.
    HttpContext.Current.Response.TransmitFile(sDiretorioDestino & sArquivoZip)
    ' "Limpo" o objeto
    sz = Nothing
  End Sub
Obs.:
Você pode definir uma senha para seu .zip, utilizando a propriedade “password”.
Compactando Somente um Arquivo
Para compactar somente um arquivo, você terá que informar o arquivo a ser compactado, e o diretório de destino.
  ''' <summary>
  ''' Evento do botão gerar Arquivo
  ''' </summary>
  Protected Sub btnGerarArquivo_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnGerarArquivo.Click
    gerarZipArquivo(txtArquivoOrigem.Text, txtArquivoDestino.Text)
    subInitDescompactarArquivos()
  End Sub
  ''' <summary>
  ''' Este método gera um zip, a partir de um diretório
  ''' </summary>
  ''' <param name="sArquivoOrigem">
  ''' Arquivo que será zipado
  ''' </param>
  ''' <param name="sDiretorioDestino">
  ''' Diretório que receberá o arquivo zipado
  ''' </param>
  ''' <remarks>
  ''' </remarks>
  Public Sub gerarZipArquivo(ByVal sArquivoOrigem As String, ByVal sDiretorioDestino As String)
    Dim sz As New FastZip()
    Dim sArquivoZip As String = String.Empty
    ' Aqui vou criar um nome do arquivo, com 6 caracteres randômicos.
    ' O Guid é um método do .net que gera string aleatórias únicas, baseada na hora e no
    ' endereço MAC na máquina gerada.
    sArquivoZip = "MeuZip" & Left(Guid.NewGuid.ToString, 6) & ".zip"
    ' Só um tratamento para garantir mais estabilidade
    If Right(sDiretorioDestino, 1) <> "\" Then
      sDiretorioDestino = sDiretorioDestino & "\"
    End If
    If Not Directory.Exists(sDiretorioDestino) Then
      lblErroArquivo.Text = "O Diretório de Destino informado não existe: <br />" & sDiretorioDestino
      Exit Sub
    End If
    If Not File.Exists(sArquivoOrigem) Then
      lblErroArquivo.Text = "O Arquivo de Origem informado não existe: <br />" & sArquivoOrigem
      Exit Sub
    End If
    ' Crio um arquivo do tipo stream, aprontando para o meu zip de destino.
    Dim strmZipOutputStream As ZipOutputStream
    strmZipOutputStream = New ZipOutputStream(File.Create(sDiretorioDestino & sArquivoZip))
    ' Seto o nÃvel de compressão (0->Sem compressão / 9-> Compressão Máxima)
    strmZipOutputStream.SetLevel(9)
    ' Leio o arquivo de origem
    Dim strmFile As FileStream = File.OpenRead(sArquivoOrigem)
    Dim abyBuffer(strmFile.Length - 1) As Byte
    strmFile.Read(abyBuffer, 0, abyBuffer.Length)
    ' Aqui eu trato para pegar somente o arquivo, sem os diretórios
    ' O split é um método que separa a string, de acordo com um caractere, no meu caso "\"
    ' Cada indice da minha matriz é um diretório, e o ultimo é o arquivo
    Dim sAuxArquivo As String() = Split(sArquivoOrigem, "\")
    ' Crio uma variável, adicionando o meu Arquivo ao Zip
    ' Com ubound, eu pego o ultimo Ãndice da minha matriz, que é o nome do meu arquivo.
    Dim objZipEntry As ZipEntry = New ZipEntry(sAuxArquivo(UBound(sAuxArquivo)))
    ' Seto a data de criação
    objZipEntry.DateTime = DateTime.Now
    ' Informo o tamanho do stream. (Do meu arquivo a ser zipado)
    objZipEntry.Size = strmFile.Length
    ' Fecho meu stream para liberar memória
    strmFile.Close()
    ' Adiciono no objeto para gerar o zip.
    strmZipOutputStream.PutNextEntry(objZipEntry)
    strmZipOutputStream.Write(abyBuffer, 0, abyBuffer.Length)
    ' "Limpo" o objeto
    strmZipOutputStream.Finish()
    strmZipOutputStream.Close()
    ' Aqui eu habilito o download do arquivo.
    ' Muito útil se você quiser salvar em diretórios protegidos
    ' Ou não acessÃvel pela raÃz do seu projeto web.
    HttpContext.Current.Response.TransmitFile(sDiretorioDestino & sArquivoZip)
  End Sub
Descompactando um arquivo .zip
Para descompactar um arquivo .zip você terá que informar o arquivo, e o diretório de destino.
  Protected Sub btnDescompactar_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnDescompactar.Click
    descompactarZip(txtArquivoParaDescompactar.Text, txtDescompactarArquivos.Text)
  End Sub
  ''' <summary>
  ''' Sub que descompacta um arquivo .zip apra um diretório
  ''' </summary>
  ''' <param name="sArquivoZip">
  ''' Arquivo para ser descompactado
  ''' </param>
  ''' <param name="sDiretorioParaDescompactar">
  ''' Diretório para ser descompactado
  ''' </param>
  ''' <remarks></remarks>
  Private Sub descompactarZip(ByVal sArquivoZip As String, ByVal sDiretorioParaDescompactar As String)
    Dim oMeuZip As New FastZip
    ' Se o arquivo não existe eu aviso o usuário
    If Not File.Exists(sArquivoZip) Then
      lblErroDescompactar.Text = ("Arquivo zip não existe: " & sArquivoZip)
      Exit Sub
    End If
    ' Se o arquivo não for zip, eu aviso o usuário
    If LCase(Right(sArquivoZip, 3)) <> "zip" Then
      lblErroDescompactar.Text = ("Arquivo não é do formato .zip: " & sArquivoZip)
      Exit Sub
    End If
    ' Se o arquivo não for zip, eu aviso o usuário
    If Not Directory.Exists(sDiretorioParaDescompactar) Then
      lblErroDescompactar.Text = ("Diretório para descompactar os arquivos não existe: " & sDiretorioParaDescompactar)
      Exit Sub
    End If
    ' "Deszipo" o arquivo, sem nunca sobrescrever
    oMeuZip.ExtractZip(sArquivoZip, sDiretorioParaDescompactar, FastZip.Overwrite.Never)
    lblErroDescompactar.Text = "Arquivo Descompactado com sucesso!!!!!"
  End Sub
Para você testar!
Para que você possa testar, colocamos um formulário, e um código de inicialização da página.
Formulário:
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
  <title>Criar Arquivos Zip em Asp.Net</title>
  <style type="text/css">
  body, input{
  font-family: verdana;
  font-size: 10px;
  }
  </style>
</head>
<body>
  <form id="form1" runat="server">
    <div>
      <strong>Este exemplo utiliza componentes de terceiros. Verifique o termo de uso.
        .</strong>
      <br />
      <br />
      <fieldset>
        <legend>Criar Arquivo Zip do Diretório Inteiro </legend>
        <table style="border: none;">
          <tr>
            <td>
              Diretório de Origem:
            </td>
            <td>
              <asp:TextBox ID="txtOrigem" runat="server" Columns="60"></asp:TextBox>
            </td>
          </tr>
          <tr>
            <td>
              Diretório de Destino:
            </td>
            <td>
              <asp:TextBox ID="txtDestino" runat="server" Columns="60"></asp:TextBox>
            </td>
          </tr>
          <tr>
            <td colspan="2">
              <asp:Button runat="server" ID="btnGerar" Text="Gerar Zip do Diretório inteiro" />
              <asp:Label runat="server" ID="lblErro" Font-Bold="true" ForeColor="red"></asp:Label>
            </td>
          </tr>
        </table>
      </fieldset>
      <br />  <br />
      <fieldset>
        <legend>Criar Arquivo Zip de um único Arquivo </legend>
        <table style="border: none;">
          <tr>
            <td>
              Arquivo para ser "zipado":
            </td>
            <td>
              <asp:TextBox ID="txtArquivoOrigem" runat="server" Columns="60"></asp:TextBox>
            </td>
          </tr>
          <tr>
            <td>
              Diretório de Destino:
            </td>
            <td>
              <asp:TextBox ID="txtArquivoDestino" runat="server" Columns="60"></asp:TextBox>
            </td>
          </tr>
          <tr>
            <td colspan="2">
              <asp:Button runat="server" ID="btnGerarArquivo" Text="Gerar Zip de um único Arquivo" />
              <asp:Label runat="server" ID="lblErroArquivo" Font-Bold="true" ForeColor="red"></asp:Label>
            </td>
          </tr>
        </table>
      </fieldset>
    </div>
    <br />  <br />
    <fieldset>
      <legend>Descompactar Arquivo .ZIP </legend>
      <table style="border: none;">
        <tr>
          <td>
            Arquivo para ser "deszipado":
          </td>
          <td>
            <asp:TextBox ID="txtArquivoParaDescompactar" runat="server" Columns="60"></asp:TextBox>
          </td>
        </tr>
        <tr>
          <td>
            Diretório para arquivos serem descompactados :
          </td>
          <td>
            <asp:TextBox ID="txtDescompactarArquivos" runat="server" Columns="60"></asp:TextBox>
          </td>
        </tr>
        <tr>
        <td colspan="2">
        <asp:Button runat="server" ID="btnDescompactar" Text="Descompactar arquivo zip" />
        <asp:Label ID="lblErroDescompactar" runat="server" Font-Bold="true" ForeColor="red"></asp:Label>
        </td>
        </tr>
      </table>
    </fieldset>
  </form>
</body>
</html>
Inicialização da Página
  Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    If Not Page.IsPostBack Then
      ' Aqui eu dou um valor inicial, só para te ajudar a começar com um teste
      txtDestino.Text = Server.MapPath("") & "\Destino\"
      txtOrigem.Text = Server.MapPath("") & "\Origem\"
      ' Arquivo
      txtArquivoDestino.Text = Server.MapPath("") & "\Destino\"
      txtArquivoOrigem.Text = Server.MapPath("") & "\Origem\Figura.jpg"
      ' Descompactar
      txtDescompactarArquivos.Text = Server.MapPath("") & "\Descompactar\"
      subInitDescompactarArquivos()
    End If
  End Sub
  ''' <summary>
  ''' Sub só para demonstação, para você poder dezipar um arquivo, depois de enviá-lo
  ''' </summary>
  ''' <remarks></remarks>
  Protected Sub subInitDescompactarArquivos()
    Dim sArquivos As String()
    Dim sArquivo As String
    ' Seleciono todos os arquivos do tipo zip.
    sArquivos = Directory.GetFiles(txtArquivoDestino.Text, "*.zip")
    For Each sArquivo In sArquivos
      txtArquivoParaDescompactar.Text = sArquivo
      Exit For
    Next
  End Sub
Considerações finais
É possÃvel também trabalhar com arquivos .tar, Gzip e BZip2 de forma análoga.
Fonte: Imasters

