Download - extjs
1
Tópicos Avançados em Computação
Lins-SP, Agosto de 2012
Prof. Dr. Wagner J. DizeróProf. Dr. Wagner J. Dizeró[email protected]@unilins.edu.br
Apresentação da Disciplina
� EMENTA� Tópicos relacionados com inovações tecnologias decorrentes de pesquisas de vanguarda e da evolução apurada na área. O estado da Arte da Tecnologia.
� CRITÉRIOS DE APROVEITAMENTO:� Provas: peso 8.0 (oito)� Trabalhos: peso 2.0 (dois)
2
2
BibliografiaLivro Texto:
1. PHP 4: A Bíblia; Converse, Tim et al; Ed. Campus; 1ª edição; 2001; 5 exemplares.
2. Use a Cabeça: PHP e MySQL; Beighley, Linn; Ed. Alta Books; 1ª edição; 2010; 10 exemplares.
3. Ajax (ASYNCHRONOUS JAVASCRIPT AND XML); Soares, Walace; Ed. Érica; 1ª edição; 2006; 10 exemplares.
Complementar:
4. Profissional PHP: Programando; Castagneto, Jesus et al; Ed. Makron Books; 1ª edição; 2001; 1 exemplar.
5. PHP e MySQL: Desenvolvimento Web; Welling, Luke et al; Ed. Campus; 1ª edição; 2001; 1 exemplar.
6. Programando em PHP: Conceitos e Aplicações; Soares, Walace; Ed. Érica; 1ª edição; 2000; 5 exemplares.
7. Fundamentos de PHP; Meloni, Julie C.; Ed. Ciência Moderna; 1ª edição; 2000; 5 exemplares.
8. Guia de Consulta Rápida: Integrando PHP com MySQL; Stoco, Lucio M.; Ed. Novatec; 1ª edição; 2000; 5 exemplares.
3
Roteiro das Aulas
� Instalação e Configurações Básicas
� Introdução à Linguagem PHP
� Exemplos de Programas
� Conexão com Banco de Dados
� Estudos de Casos
4
3
Instalação e Configurações Básicas
� Softwares Necessários:� PHP (http://www.php.org/)� Apache (http://www.apache.org/)� MySQL (http://www.mysql.org/)
� EasyPHP (http://www.easyphp.org/)� EasyPHP é um sistema indicado para os usuários que não têm
instalado no sistema nenhum dos programas necessários para programar em PHP (Apache, PHP e MySQL)
� Notepad++ (http://notepad-plus-plus.org/ )
5
Interface de instalação EasyPHP
1. Tela de boas vindas ...2. Termos de uso da licença ...3. Informação sobre o uso ...4. Pasta para instação ...5. Nome da atalho no menu ...6. Pronto para instalação ...7. Instalação Completa!
Seqüência para instalação:
6
4
Para carregar o EasyPHP(C:\Arquivos de programas\EasyPHP-5.3.3\EasyPHP-5.3.3.exe)
Menu para iniciar o EasyPHP
Ícone do programa
Interface do EasyPHP
7
Endereço para acesso via browser
http://localhost/
http://127.0.0.1/ou
ATENÇÃO: Dependendo do versão, é necessário indicar a porta. Ex.: http://127.0.0.1:8888/ 8
5
Pasta Base� Pasta Base é o local onde os programas PHP deverão ser salvos.
� É nesse local que o Apache irá buscar os scripts para serem interpretados.
� Pela instalação padrão, a pasta base será:
C:\Arquivos de programas\EasyPHP-5.3.3\www
� É possível redefinir a pasta base editando o arquivo
httpd.conf, através da diretiva: DocumentRoot
� Nesse arquivo também é possível configurar o nome do arquivo default a ser carregado:
DirectoryIndex index.php index.html index.htm
9
EasyPHP home
http://localhost/home
A partir da página principal do EasyPHP é possível:
- Criar um “Alias” (apelido)indicando onde os scripts estarão gravados, como uma alternativa para a pasta base padrão.
- Ver informações sobre as configurações do PHP
- Acessar o PhpMyAdminpara administrar bases de dados no MySQL.
- Ler os termos de licençade todos os softwares oferecidos no pacote.
10
6
Introdução à Linguagem PHP
� Personal Home Page;
� Criação de Websites dinâmicos;
� Usa scripts embutidos dentro de páginas Html;
� Combinação de linguagem de programação e servidor de aplicações;
� É interpretado e não compilado (Apache);
� Código executado no servidor;
� Baseado na linguagem C;
� É case sensitive;
� Compatível com várias plataformas;
� Suporte para vários Banco de Dados
11
Esquema do Funcionamento
base de dados
página html
servidor
usuário página PHP
Internet
12
7
Primeiro Script
<!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>Aprendendo PHP</title>
</head>
<body>
<?php
$texto = "Primeiro Script";
echo $texto;
?>
</body>
</html>
13
Detalhes do Primeiro Exemplo
� Esse código precisar ser salvo em um arquivo com a extensão .PHP na pasta base definida no servidor Apache.
� Para acessá-lo, use: http://<ip>:<porta>/<alias>/<arquivo.php>
Por exemplo: http://127.0.0.1:8888/php/exemplo1.php
� No exemplo, é criada uma variável chamada $texto e atribuído o valor “Primeiro Script”, que posteriormente será exibido pelo browser.
� Toda variável em PHP é iniciada por $.
� Não há necessidade de declarar o tipo de variável.
� Quando a página é carregada, o script PHP é interpretado pelo Apache e substituído pelo resultado gerado puramente em Html.
� Isso pode ser verificado a partir do browser no menu: Exibir / Código fonte
14
8
Utilizando Formulários em HTML<html>
<head><title>Formulário em Html</title></head>
<body>
<form>
Digite uma frase:
<input type="text" name="frase">
<input type="submit" value="Enviar">
</form>
<hr><br>
<?php
if (!empty($_REQUEST["frase"])) {
$frase = $_REQUEST["frase"];
echo "Você digitou: <b>" .$frase. "</b>";
}
?>
</body>
</html>
15
Detalhes do Segundo Exemplo� empty retorna se a variável passada no parâmetro vale null ou “”.
� null indica variável não declarada e “” indica que variável tem valor vazio.
� $_REQUEST retorna o valor contido num campo do formulário.
� É necessário que a propriedade NAME do INPUT do formulário HMTL tenha o mesmo nome do parâmetro usado em $_REQUEST.
� $_REQUEST requisita valores enviados pelos métodos GET e POST.
� Para especificar apenas um dos métodos, utilize $_GET e $_POST.
� A instrução if é usada para garantir que nada seja apresentado quando a página for carregada pela primeira vez.
� É possível atribuir o valor do INPUT direto para uma variável do PHP.
� É preciso configurar register_globals = On no arquivo PHP.INI e reiniciar o servidor Apache.
� Por questões de segurança, esta opção está desabilitada a partir do PHP 6.
16
9
Tipos de Campos num Formulário<form>
Caixa de texto: <input type=text name=text_name><br><br>
Check Box: <input type=checkbox name=checkbox_name><br><br>
Radio:<br> Valor 1<input type=radio name=radio_name value=valor1 checked><br>
Valor 2<input type=radio name=radio_name value=valor2><br><br>
Select:<br><select name=select_name>
<option value=opcao1>Opção 1</option>
<option value=opcao2>Opção 2</option>
<option value=opcao3>Opção 3</option>
</select><br><br>
Area de texto:<br> <textarea name=textarea_name></textarea><br>
<input type=submit value="Enviar">
</form> <br><hr><br>
<?php
@$text_name = $_REQUEST["text_name"];
@$checkbox_name = $_REQUEST["checkbox_name"];
@$radio_name = $_REQUEST["radio_name"];
@$select_name = $_REQUEST["select_name"];
@$textarea_name = $_REQUEST["textarea_name"];
echo "Text: " .$text_name. "<br>";
echo "CheckBox: " .$checkbox_name. "<br>";
echo "Radio: " .$radio_name. "<br>";
echo "Select: " .$select_name. "<br>";
echo "Textarea:<br>" .nl2br($textarea_name). "<br>";
?>
O @ serve para omitir a mensagem de aviso (warning) quando a variável não existir 17
Desvio Condicional - if<?php
if(!empty($_GET["sexo"])) {
$sexo = $_GET["sexo"];
if ($sexo == "M")
echo "Sexo masculino";
else if($sexo == "F")
echo "Sexo feminino";
}
?>
<br><br>
<form method="GET" action="">
<input type="radio" name="sexo" value="M">Masculino<br>
<input type="radio" name="sexo" value="F">Feminino<br><br>
<input type="submit" value="Enviar">
</form>
Se uma condição if possuir 2 ou mais comando é preciso colocá-los entre chaves. { e } representam, respectivamente, begin e end.
18
10
Laço de Repetição - for<html>
<head><title>Tabuada</title></head>
<body>
<?php$n = 5;for($i=1; $i<=10; $i++) {
$r = $n * $i;echo $n." x " .$i. " = " .$r. "<br>";
}?>
</body>
</html>
Altere o exemplo para que a escolha da tabuada a ser exibida seja feita através de um formulário.
19
Laço de Repetição - while
<?php
$inicio = microtime();
$i=1;
while ($i<=1000) {
echo "escrevendo linha ".$i."<br>";
$i++;
}
$final = microtime();
$tempo = $final - $inicio;
echo "<BR>Página gerada em " .$tempo. " segundos.";
?>
20
11
Inclusão de outros scripts� A função include permite que o conteúdo de outro arquivo seja incluído dentro do arquivo atual.
<!–- data.php --><html><body>
<?php$data = date("d/m/Y");echo "Hoje é " .$data. "<br>";
?></body></html>
<!-- welcome.php --><html><body>
<?phpecho "Seja bem-vindo!!!<br>";include("data.php");
?></body></html>
21
Uso de Vetor (array)
<?php
$nome = array("Joao","Carlos","Marcos");
$nome[] = "Edson";
$idade[0] = 20; $idade[1] = 30; $idade[2] = 27; $idade[3] = 19;
//$idade = array(20,30,27,19);
for($a = 0; $a < count($nome); $a++){
echo "A idade de " .$nome[$a]. " é " .$idade[$a]. " anos<br>";
}
?>
� Um array inicia na posição 0 (zero).
� A função count retorna a quantidade de elementos de um array.
22
12
Uso de Sessão
<!-- page1.php -->
<?php
session_start();
echo "Pagina #1";
$_SESSION["x"] = "PHP";
echo "<br><a href=\"page2.php\">page 2</a>";
?>
<!-- page2.php -->
<?php
session_start();
echo "Pagina #2";
echo "<br>Valor da variável de sessão x: " .$_SESSION["x"];
?>
� O uso de sessão permite a criação de variáveis acessíveis por todo o sistema enquanto uma sessão estiver aberta.
� As variáveis de sessão são independentes para cada usuário conectado.
23
Exercício - Calculadora
� Elaborar uma calculadora simples com as 4 operações básicas. O usuário deve informar 2 números e o operador (+ - * / )
24
13
Exercício – Calculadora com login
� Modificar a calculadora de forma que somente usuários que conheçam a senha possam utilizá-la.
� Utilizar 3 arquivos:� calc_login.php – formulário para fazer login� calc_logout.php – finalizar o uso� calc_senha – calculadora que solicita o login
27
Exercícios1. Apresentar os números pares entre 1 e 100.
2. Apresentar os anos bissextos entre um intervalo informado pelo usuário.
3. Apresentar os 10 primeiros termos da série de Fibonacci.
4. Solicitar um valor e verificar se é um número primo.
5. Criar um programa para ler um número de 1 a 12 e apresentar o respectivo mês por extenso.
6. Criar um programa para ler uma data em formato dd/mm/yyyy. Por exemplo: 21/03/2012 -> 21 de março de 2012.
7. Criar um programa para ler um número entre 1 e 100 e apresentá-lo por extenso.
8. Criar um gerador automático de curriculum. O usuário deve informar: nome, dados pessoais, objetivos, experiência profissional, formação acadêmica e conhecimentos gerais. O usuário também deverá escolher a cor do texto e do fundo do site. O programa deve gerar um curriculum em formato .html.
32
14
Trabalho – Lanchonete(individual)
� Elaborar uma página em PHP para montar um lanche e calcular o valor a ser cobrado do cliente.
44
Utilizando Banco de Dados
PASSOS:
1. Abrir uma conexão
2. Executar uma instrução SQL
3. Processar o resultado
4. Fechar a conexão
� Essencialmente, um sistema comercial só tem real utilidade se conseguir armazenar e recuperar informações através de uma base de dados.
� Além dos comandos da linguagem PHP, é de extrema importância conhecer a linguagem SQL.
45
15
Principais funções para MySQL
� mysql_connectconecta ao BD, indicando: IP, usuário e senha
� mysql_select_dbseleciona o BD a ser utilizado
� mysql_queryexecuta uma consulta SQL
� mysql_fetch_arrayretorna um registro contido na consulta
� mysql_resultretorna um campo contido na consulta
� mysql_num_rowsretorna a quantidade de registros localizados
� mysql_closefecha a conexão com o BD
46
Verificando a conexão com o BD
<?php
@$link = mysql_connect("127.0.0.1", "root", "");
if (!$link) {
die("Falha ao conectar: " . mysql_error());
}
else {
echo "Conexão bem sucedida";
mysql_close($link);
}
?>
IP USUÁRIO SENHA
47
16
Uso de PHP com outros SGBD´s
� Basicamente, para usar PHP com outros bancos, é preciso configurar o arquivo:
C:\wamp\Apache2\bin\PHP.INI
Depois, retire o comentário (;) da extensão a ser utilizada. Por exemplo, para Interbase:
;extension=php_interbase.dll
� Na programação, troque os prefixos mysql_ das funções por ibase_ para utilizar o Interbase.
� Nem todas funções disponíveis para MySQL funcionam para os demais bancos.
48
Banco de Dados
Tabela CONTATOCREATE TABLE IF NOT EXISTS tb_contato(
cod_cont integer not null auto_increment,
nome varchar(50),
endereco varchar(60),
cidade varchar(40),
data_nasc date,
fone varchar(15),
PRIMARY KEY(cod_cont)
);
Inclusão de dadosINSERT INTO tb_contato(nome,endereco,cidade,fone,data_nasc)
VALUES('Jonatas','Rua da Glória,12','Lins','3533-1234','1972-03-20');
INSERT INTO tb_contato(nome,endereco,cidade,fone,data_nasc)VALUES('Raquel','R. 7 Setembro,55','Pongaí','3523-0022','1973-05-15');
INSERT INTO tb_contato(nome,endereco,cidade,fone,data_nasc)VALUES('Marcos','Av.Saudade,275','Lins','3532-3344','1980-12-25');
INSERT INTO tb_contato(nome,endereco,cidade,fone,data_nasc)VALUES('Ana','R. das Flores,99','Lins','3523-9999','1984-01-05');
COMMIT;
Banco de DadosCREATE DATABASE IF NOT EXISTS db_aula;USE db_aula;
49
17
Listar registros do BD<?php
$link = mysql_connect("127.0.0.1","root","");
mysql_select_db("db_aula");
$sql = "SELECT cod_cont, nome, endereco, cidade, fone, data_nasc
FROM tb_contato";
$resultado = mysql_query($sql);
while($registro = mysql_fetch_array($resultado)){
echo $registro["cod_cont"] . " | " .
$registro["nome"] . " | " .
$registro["endereco"] . " | " .
$registro["cidade"] . " | " .
$registro["fone"] . " | " .
$registro["data_nasc"] . "<br>";
}
mysql_close($link);
?>
50
Exercícios1. Alterar o programa anterior para que a listagem seja exibida em
formato de tabela.
2. Fazer com que a relação de registros cadastrados seja exibida num relatório zebrado.
3. Permitir que usuário escolha o campo de deseja para ordenação dos registros.
4. Adicionar um campo para que o usuário digite parte do nome a ser consultado.
5. Apresentar, ao final da listagem, a quantidade total de registros da agenda.
6. Apresentar os dados com paginação, mostrando 10 registros de cada vez.
7. Apresentar os registros utilizando uma tableless (tabela feita com folha de estilo)
51
18
Estudo de Caso:Agenda Eletrônica
� Objetivo:� Desenvolver uma agenda eletrônica.
� Requisitos:� O módulo de agenda deve ser um CRUD, ou seja, deve permitir
consultar, cadastrar, alterar e excluir registros de pessoas.� Para cada registro, deve-se armazenar: codigo, nome, endereço,
cidade, telefone e data de nascimento.� Todas as funcionalidades da agenda devem ser acessadas através de
um menu de opções.
Lista de Eventos
No Evento Descrição Ator
01 Listar Contatos Listar a relação de contatos da agenda Administrador
02
Cadastrar Contato Cadastrar dados pessoais de um contato Administrador
03
Alterar Contato Alterar dados de um contato Administrador
04
Excluir Contato Excluir fisicamente os registros Administrador
53
19
Menu
<!-- index.php -->
<?php include "menu.php"; ?>
<!-- menu.php -->
<a href="listar.php">Listar</a> |
<a href="inserir.php">Inserir</a> |
<a href="alterar.php">Alterar</a> |
<a href="excluir.php">Excluir</a>
<hr>
54
Listar registros do BD<!-- listar.php -->
<?php
include "menu.php";
$link = mysql_connect("127.0.0.1","root","");
mysql_select_db("db_aula");
$sql = "SELECT cod_cont, nome, endereco, cidade, fone, data_nasc
FROM tb_contato";
$rs = mysql_query($sql);
while($r = mysql_fetch_array($rs)){
echo $r["cod_cont"] . " | " .
$r["nome"] . " | " .
$r["endereco"] . " | " .
$r["cidade"] . " | " .
$r["fone"] . " | " .
$r["data_nasc"] . "<br>";
}
mysql_close($link);
?>
55
20
Inserir novos registros no BD
<!–- inserir.php -->
<?php include "menu.php"; ?>
<form method="GET" action="inserir2.php">
Nome: <input type="text" name="nome"> <br>
Endereço: <input type="text" name="endereco"> <br>
Cidade: <input type="text" name="cidade"> <br>
Telefone: <input type="text" name="fone"> <br>
Data Nasc.: <input type="text" name="data_nasc"><br>
<br><input type="submit" value="Gravar">
</form>
Faremos a inclusão de dados em 2 passos:1. Formulário para digitar os dados2. Programa para obter os dados do formulário e gravar no banco de dados
56
<!–- inserir2.php -->
<?php
include "menu.php";
// recebe os parâmetros do formulário
@$nome = $_GET["nome"];
@$endereco = $_GET["endereco"];
@$cidade = $_GET["cidade"];
@$fone = $_GET["fone"];
@$data_nasc = $_GET["data_nasc"];
$data_nasc = implode('-',array_reverse(explode('/',$data_nasc)));
//conecta e insere no banco de dados
$link = mysql_connect("127.0.0.1","root","");
mysql_select_db("db_aula");
$sql = "INSERT INTO tb_contato(nome,endereco,cidade,fone,data_nasc)
VALUES('$nome','$endereco','$cidade','$fone','$data_nasc')";
//echo $sql."<br>";
$status = mysql_query($sql);
if($status == 1)
echo "Sucesso ao inserir registro!";
else if ($status == 0 )
echo "Erro ao inserir!";
mysql_close($link);
?>
Inserir (Cont. 2/2)
57
21
Alterar dados no BD
<!–- alterar.php -->
<?php
include "menu.php";
$link = mysql_connect("127.0.0.1","root","");
mysql_select_db("db_aula");
$sql = "SELECT cod_cont, nome FROM tb_contato";
$rs = mysql_query($sql);
while($r=mysql_fetch_array($rs)){
echo "<a href=alterar2.php?cod_cont=".$r["cod_cont"].">"
.$r["nome"]."</a><br>";
}
mysql_close($link);
?>
58
Alterar (Cont. 2/3)<!-- alterar2.php -->
<?php
include "menu.php";
$cod_cont = $_GET["cod_cont"];
$link = mysql_connect("127.0.0.1","root","");
mysql_select_db("db_aula");
$sql = "SELECT * FROM tb_contato WHERE cod_cont=".$cod_cont;
$rs = mysql_query($sql);
$r = mysql_fetch_array($rs);
$r[5] = implode('/',array_reverse(explode('-',$r[5])));
mysql_close($link);
?>
<form method="GET" action="alterar3.php">
Código:<input type="text" name="cod_cont" value="<?php echo $r[0]; ?>" readonly><br>
Nome: <input type="text" name="nome" value="<?php echo $r[1]; ?>"><br>
Endereço: <input type="text" name="endereco" value="<?php echo $r[2]; ?>"><br>
Cidade: <input type="text" name="cidade" value="<?php echo $r[3]; ?>"><br>
Telefone: <input type="text" name="fone" value="<?php echo $r[4]; ?>"><br>
Data Nasc.: <input type="text" name="data_nasc" value="<?php echo $r[5]; ?>"><br>
<br><input type="submit" value="Atualizar">
</form>
59
22
Alterar (Cont. 3/3)<!–- alterar3.php -->
<?php
include "menu.php";
@$cod_cont = $_GET["cod_cont"];
@$nome = $_GET["nome"];
@$endereco = $_GET["endereco"];
@$cidade = $_GET["cidade"];
@$fone = $_GET["fone"];
@$data_nasc = $_GET["data_nasc"];
$data_nasc = implode('-',array_reverse(explode('/',$data_nasc)));
$link = mysql_connect("127.0.0.1","root","");
mysql_select_db("db_aula");
$sql = "UPDATE tb_contato
SET nome='$nome',
endereco='$endereco',
cidade='$cidade',
fone='$fone',
data_nasc='$data_nasc'
WHERE cod_cont=$cod_cont";
$status = mysql_query($sql);
if ($status==0) echo "Erro ao atualizar.<br>";
else if ($status==1) echo "Atualizado com sucesso.<br>";
mysql_close($link);
?>
60
Excluir registros do BD<!–- excluir.php -->
<?php
include "menu.php";
$link = mysql_connect("127.0.0.1","root","");
mysql_select_db("db_aula");
if (!empty($_GET["cod_cont"])) {
$codigos = implode(", ", $_GET["cod_cont"]);
$sql = "DELETE FROM tb_contato WHERE cod_cont IN (".$codigos.")";
$status = mysql_query($sql);
if ($status==0) echo "Erro ao excluir.<br>";
}
?>
<form method="GET" action="">
<?php
$sql = "SELECT cod_cont, nome FROM tb_contato";
$rs = mysql_query($sql);
while($r=mysql_fetch_array($rs)){
echo "<input type=checkbox name=cod_cont[] value=".$r["cod_cont"].">"
.$r["nome"]."<br>";
}
mysql_close($link);
?>
<br><input type="submit" value="Excluir"></form>
61
23
Controle de Acesso
� Da forma que fizemos, nosso CRUD está funcionando. Contudo, qualquer pessoa que conheça o endereço da Agenda Eletrônica será capaz de acessar o sistema.
Tabela USUARIO
CREATE TABLE IF NOT EXISTS tb_usuario(
cod_usu integer not null auto_increment,
usuario varchar(30) UNIQUE not null,
senha varchar(30) not null,
PRIMARY KEY(cod_usu)
);
INSERT INTO tb_usuario(usuario, senha) VALUES('admin','master');
Commit;
62
login.php (1/2)<?php
session_start();
@$usuario = $_POST['usuario'];
@$senha = $_POST['senha'];
if(!empty($usuario) AND !empty($senha)) {
$link = mysql_connect("127.0.0.1", "root", "");
mysql_select_db("db_aula");
$sql = "SELECT cod_usu
FROM tb_usuario
WHERE usuario = '$usuario' AND senha = '$senha'";
$rs = mysql_query($sql);
if(!empty($rs) AND mysql_num_rows($rs)==1) {
$r = mysql_fetch_array($rs);
$_SESSION['cod_usu'] = $r['cod_usu'];
}
mysql_close($link);
}
63
24
login.php (2/2)if(!empty($_SESSION['cod_usu'])) { ?>
<script>location='menu.php';</script> <?php
exit;
}
else { ?>
<form method="POST" action="">
Usuário: <input type="text" name="usuario"><br>
Senha: <input type="password" name="senha"><br>
<input type="submit" value="Entrar">
</form> <?php
}
?>
64
logout.php
<?php
session_start();
$_SESSION['login'] = null;
?>
<script>location='menu.php';</script>
65
25
menu.php
<?php
session_start();
if(empty($_SESSION['cod_usu'])) { ?>
<script>location='login.php';</script> <?php
exit;
}
?>
<a href="listar.php">Listar</a> |
<a href="inserir.php">Inserir</a> |
<a href="alterar.php">Alterar</a> |
<a href="excluir.php">Excluir</a> |
<a href="logout.php">Logout</a>
<hr>
66
Agenda Eletrônica – versão 2.0
Organização dos arquivos:
conexao.php - conexão com o BD para todos os arquivos
grid.php - tela principal para gerenciamento
form.php - formulário para inserir e alterar
salvar.php - responsável por inserir e atualizar no DB
excluir.php - responsável pela exclusão de registros
index.php - arquivo inicial que direciona para o grid
67
26
conexao.php
<!-- conexao.php -->
<?php
$link = mysql_connect("127.0.0.1","root","");
mysql_select_db("db_aula");
?>
68
grid.php (1/3)<?php
include "conexao.php";
@$filtro = trim(addslashes($_GET['filtro']));
$sql = "SELECT cod_cont, nome, endereco, cidade, fone
DATE_FORMAT(data_nasc,'%d/%m/%Y') data
FROM tb_contato
WHERE nome LIKE '$filtro%'";
$rs = mysql_query($sql);
echo '<table border=1>
<th bgcolor=#EEEEEE>Gerenciar Contatos</th><tr><td>
<table border=0>
<tr>
<td width= "20"> </td>
<td width= "20"> </td>
<td width= "40"><b>ID</td>
<td width="200"><b>Nome</td>
<td width="220"><b>Endereço</td>
<td width="120"><b>Cidade</td>
<td width="110"><b>Cidade</td>
<td width= "80"><b>Data Nasc.<td>
</tr>';
69
27
grid.php (2/3)if(empty($rs) OR mysql_num_rows($rs)==0) {
echo '<tr><td colspan=8 align=center>Nenhum contato encontrado</td></tr>';
}
else {
while($r = mysql_fetch_array($rs)){
echo "<tr>
<td><a href=\"excluir.php?codigo=".$r['cod_cont']."\"
onClick=\"return confirm('Confirma a exclusão?');\">
<img src=\"./img/excluir.png\" border=0 alt=excluir></a>
</td>
<td><a href=\"form.php?codigo=".$r['cod_cont']."\">
<img src=\"./img/alterar.png\" border=0 alt=alterar></a>
</td>
<td>".$r['cod_cont']."</td>
<td>".$r['nome']."</td>
<td>".$r['endereco']."</td>
<td>".$r['cidade']."</td>
<td>".$r['data']."</td>
</tr>";
}
}
70
grid.php (3/3)echo "</table></td></tr>";
echo "<tr><td><table width=100% border=0><tr><td>
<input type=button value=Novo onClick=\"location='form.php';\"></td>
<form><td align=right>Pesquisar por: <input name=filtro>
<input type=submit value=Buscar></td></form></tr></table>";
echo "</td></tr></table>";
mysql_close($link);
?>
71
28
salvar.php (1/2)<?php
include "conexao.php";
@$codigo = $_GET["cod_cont"];
@$nome = $_GET["nome"];
@$endereco = $_GET["endereco"];
@$cidade = $_GET["cidade"];
@$fone = $_GET["fone"];
@$data_nasc = $_GET["data_nasc"];
if(!empty($data_nasc))
$data_nasc = implode('-',array_reverse(explode('/',$data_nasc)));
if(empty($codigo)) {
$sql = "INSERT INTO tb_contato(nome, endereco, cidade, fone, data_nasc)
VALUES('$nome', '$endereco', '$cidade', '$fone', '$data_nasc')";
}
else {
$sql = "UPDATE tb_contato
SET nome = '$nome',
endereco = '$endereco',
cidade = '$cidade',
fone = '$fone',
data_nasc = '$data_nasc'
WHERE cod_cont = $codigo";
}
72
salvar.php (2/2)//echo $sql."<br>";
$status = mysql_query($sql);
if($status==1)
$msg = "Sucesso ao salvar registro";
else
$msg = "Erro ao salvar registro";
mysql_close($link);
?>
<script>
alert('<?php echo $msg; ?>');
location = 'grid.php';
</script>
73
29
excluir.php (2/2)
<?php
include "conexao.php";
$codigo = $_GET["codigo"];
$sql = "DELETE FROM tb_contato WHERE cod_cont = $codigo";
$status = mysql_query($sql);
if($status==1) $msg = "Sucesso ao excluir registro";
else $msg = "Erro ao excluir registro";
mysql_close($link);
?>
<script>
alert('<?php echo $msg; ?>');
location = 'grid.php';
</script>
74
index.php
<?php include "grid.php"; ?>
75
30
Trabalho: Cadastro de Cidades(individual)
� Objetivo:� Criar um módulo para cadastro de cidades.
� Requisitos:� Criar um CRUD para gerenciar cidades.� De cada cidade deve-se armazenar o nome e o estado.� Os estados deverão estar previamente cadastrados numa tabela.
Banco de DadosTabela tb_estadoCREATE TABLE IF NOT EXISTS tb_estado(sigla char(2) not null,nome varchar(40),PRIMARY KEY(sigla)
);
Tabela tb_cidadeCREATE TABLE IF NOT EXISTS tb_cidade(id integer not null auto_increment,sigla char(2),nome varchar(40),PRIMARY KEY(id),FOREIGN KEY(sigla) REFERENCES tb_estado
);
Inclusão de estadosINSERT INTO tb_estado VALUES ('SP', 'São Paulo');INSERT INTO tb_estado VALUES ('RJ', 'Rio de Janeiro');INSERT INTO tb_estado VALUES ('MG', 'Minas Gerais');INSERT INTO tb_estado VALUES ('ES', 'Espírito Santo');INSERT INTO tb_estado VALUES ('RS', 'Rio Grande do Sul');INSERT INTO tb_estado VALUES ('SC', 'Santa Catarina');INSERT INTO tb_estado VALUES ('PR', 'Paraná');...
COMMIT;
77
31
Telas do módulo de cidades
Organização dos arquivos:conexao.php - conexão com o BD para todos os arquivosgrid.php - tela principal para gerenciamentoform.php - formulário para inserir e alterarexcluir.php - responsável pela exclusão de registrossalvar.php - responsável por inserir e atualizar no DBindex.php - arquivo inicial que direciona para o grid
78
grid.php (1/2)<!-- grid.php -->
<table border=1>
<th bgcolor=#EEEEEE>Gerenciar Cidades</th>
<tr><td>
<table border=0>
<tr><td width=20> </td><td width=20> </td>
<td width= 40><b>ID</td>
<td width=300><b>Cidade</td>
<td width= 50><b>Estado</td></tr>
<?php
include "conexao.php";
@$filtro = trim(addslashes($_GET['filtro']));
$sql = "SELECT a.id, a.nome, b.nome estado
FROM tb_cidade a LEFT JOIN tb_estado b ON a.sigla = b.sigla
WHERE a.nome LIKE '$filtro%'
ORDER BY a.nome";
$rs = mysql_query($sql);
if(empty($rs) OR mysql_num_rows($rs)==0) {
echo "<tr><td colspan=5 align=center>Nenhum registro localizado</td></tr>";
}
else {
79
32
grid.php (2/2)while($r = mysql_fetch_array($rs)){
echo "<tr>
<td><a href=\"excluir.php?id=".$r['id']."\"
onClick=\"return confirm('Confirma a exclusão?');\">
<img src=\"./img/excluir.png\" border=0 alt=excluir></a></td>
<td><a href=\"form.php?id=".$r['id']."\">
<img src=\"./img/alterar.png\" border=0 alt=alterar></a></td>
<td>".$r['id']."</td>
<td>".$r['nome']."</td>
<td>".$r['estado']."</td>
</tr>";
}
}
mysql_close($link);
?>
</table></td></tr>
<tr><td>
<table width="100%" border=0><tr>
<td><input type=button value=Novo onClick="location='form.php';"></td><form>
<td align=right>Pesquisar por: <input name=filtro>
<input type=submit value=Buscar></td></form></tr>
</table>
</td></tr>
</table>
80
form.php (1/2)<!-- form.php -->
<?php
$r = array();
@$r['id'] = $_GET['id'];
$r['nome'] = null;
$r['sigla'] = "SP";
include "conexao.php";
if(!empty($r['id'])) {
$sql = "SELECT id,nome,sigla
FROM tb_cidade
WHERE id=".$r['id'];
$rs = mysql_query($sql);
$r = mysql_fetch_array($rs);
}
?>
<table border=1>
<th bgcolor=#EEEEEE>Formulário de Cidades</th>
<tr><form action="salvar.php"><td>
<table border=0>
<tr><td>Código:</td><td>
<input type=text name=id value="<?php echo $r['id']; ?>" readonly></td></tr>
<tr><td>Cidade:</td><td>
<input type=text name=nome value="<?php echo $r['nome']; ?>"></td></tr>
81
33
form.php (2/2)<tr><td>Estado:</td><td>
<select name="sigla">
<?php
$sql2 = "SELECT sigla, nome FROM tb_estado ORDER BY nome";
$rs2 = mysql_query($sql2);
while($r2 = mysql_fetch_array($rs2)) { ?>
<option value="<?php echo $r2['sigla']; ?>"
<?php if($r['sigla']==$r2['sigla']) echo " SELECTED"; ?>>
<?php echo $r2['nome']; ?></option> <?php
} ?>
</select>
</td></tr>
</table>
</td></tr>
<tr><td>
<table width=100% border=0>
<tr><td><input type=button value=Cancelar onClick="location='grid.php';"></td>
<td align=right><input type=submit value=Salvar></td></form></tr>
</table>
</td></tr>
</table>
<?php mysql_close($link); ?>
82
salvar.php<!-- salvar.php -->
<?php
include "conexao.php";
@$id = $_GET["id"];
@$nome = $_GET["nome"];
@$sigla = $_GET["sigla"];
if(empty($id)) {
$sql = "INSERT INTO tb_cidade(nome,sigla)
VALUES('$nome','$sigla')";
}
else {
$sql = "UPDATE tb_cidade
SET nome='$nome', sigla='$sigla'
WHERE id=$id";
}
//echo $sql."<br>";
$status = mysql_query($sql);
if($status==1) $msg = "Sucesso ao salvar registro";
else $msg = "Erro ao salvar registro";
mysql_close($link);
?>
<script>
alert('<?php echo $msg; ?>');
location = 'grid.php';
</script>
83
34
excluir.php
<!-- excluir.php -->
<?php
include "conexao.php";
$id = $_GET["id"];
$sql = "DELETE FROM tb_cidade WHERE id = $id";
$status = mysql_query($sql);
if($status==1) $msg = "Sucesso ao excluir registro";
else $msg = "Erro ao excluir registro";
mysql_close($link);
?>
<script>
alert('<?php echo $msg; ?>');
location = 'grid.php';
</script>
84
Conceitos sobre Orientação a Objetos� Um objeto é qualquer coisa (concreta ou abstrata) que pode ser
representada por atributos e operações.
� Uma classe é uma abstração de um objeto.
� O objeto é uma instância de uma classe.
� Atributo é sinônimo de campo e armazena informações sobre as características do objeto.
� Um método, ou operação, é uma rotina que é executada por um objeto ao receber uma mensagem. Métodos são análogos à funções ou procedimentos da programação estruturada.
� O envio de mensagens (chamada de métodos) pode alterar o estado de um objeto.
� A herança permite o reuso de código de forma hierárquica.
� Polimorfismo permite criar diferentes métodos usando um mesmo nome. O método certo a ser invocado irá depender do contexto.
� Encapsulamento é uma forma de proteger informações de um objeto, trabalhando como uma caixa preta.
� Associação descreve a ligação entre instâncias de objetos.
� Agregação e Composição são tipos especiais de associações.
85
35
Criação da Classe Pessoa em PHP<!-- pessoa.class.php -->
<?php
class PESSOA {
private $pes_nome;
private $pes_sexo;
private $pes_nasc;
public function setar($nome,$sexo,$nasc) {
$this->pes_nome = $nome;
$this->pes_sexo = $sexo;
$this->pes_nasc = $nasc;
}
public function obterNome() {
return $this->pes_nome;
}
public function obterSexo() {
return $this->pes_sexo;
}
public function obterNascimento() {
return $this->pes_nasc;
}
}
?>
86
Instâncias da Classe Pessoa<!-- pessoa.php -->
<?php include "pessoa.class.php"; ?>
<html>
<head><title>Main :: Classe PESSOA</title></head>
<body>
<?php
$uma_pessoa = new PESSOA;
$outra_pessoa = new PESSOA;
$uma_pessoa->setar("João da Silva","M","25/07/1982");
$outra_pessoa->setar("José de Sousa","M","15/05/1978");
echo "<br>Dados da primeira pessoa:";
echo "<br>Nome: " .$uma_pessoa->obterNome();
echo "<br>Sexo: ";
echo $uma_pessoa->obterSexo()=="M"?"Masculino":"Feminino";
echo "<br>Data Nasc.: " .$uma_pessoa->obterNascimento() . "<br>";
echo "<br>Dados da segunda pessoa:";
echo "<br>Nome: " .$outra_pessoa->obterNome();
echo "<br>Sexo: ";
echo $outra_pessoa->obterSexo()=="M"?"Masculino":"Feminino";
echo "<br>Data Nasc.: " .$outra_pessoa->obterNascimento() . "<br>";
?>
</body>
</html>
87
36
Herança em PHP<!-- pessoa.class.php -->
<?php
class PESSOA {
private $pes_nome;
private $pes_sexo;
private $pes_nasc;
public function setar($nome,$sexo,$nasc){
$this->pes_nome = $nome;
$this->pes_sexo = $sexo;
$this->pes_nasc = $nasc;
}
public function obterNome() {
return $this->pes_nome;
}
public function obterSexo() {
return $this->pes_sexo;
}
public function obterNascimento() {
return $this->pes_nasc;
}
}
<!-- funcionario.class.php -->
include "pessoa.class.php";
class FUNCIONARIO extends PESSOA {
private $fun_cargo;
private $fun_salario;
public function setar($nome,$sexo,$nasc,
$cargo,$salario) {
PESSOA::setar($nome, $sexo, $nasc);
$this->fun_cargo = $cargo;
$this->fun_salario = $salario;
}
function obterCargo() {
return $this->fun_cargo;
}
function obterSalario() {
return $this->fun_salario;
}
function reajustarSalario($aumento) {
$this->fun_salario += $aumento;
}
}
?>
88
Instâncias da Classe Funcionario<!-- funcionario.php -->
<?php include "funcionario.class.php"; ?>
<html>
<head>
<title>Main :: Classe FUNCIONARIO</title>
</head>
<body>
<?php
$um_func = new FUNCIONARIO;
$um_func->setar("Carlos Garcia","M","22/02/1975","Gerente",3500.00);
$um_func->reajustarSalario(500.00);
echo "<br>Dados do Funcionario:";
echo "<br>Nome: " .$um_func->obterNome();
echo "<br>Sexo: ";
echo $um_func->obterSexo()=="M"?"Masculino":"Feminino";
echo "<br>Data Nasc.: " .$um_func->obterNascimento() . "<br>";
echo "Cargo: ". $um_func->obterCargo();
echo "Salário: R$ ". number_format($um_func->obterSalario(),2);
?>
</body>
</html>
89
37
Construtores e Destrutores<!-- construtores.php -->
<?php
class myClass {
function __construct() {
echo "Primeira classe construída <br />";
}
function operacoes() {
echo "Realizando Operações <br />";
}
function __destruct() {
echo "Primeira classe destruída <br />";
}
}
$obj = new myClass();
$obj->operacoes();
?>
Saída: Primeira classe construída
Realizando Operações
Primeira classe destruída
90
Base para criar um CRUD (1/2)<?php
class crud {
function __construct() {
@$action = $_GET['action'];
if($action=='grid')
$this->grid();
else if($action=='form')
$this->form();
else if($action=='save')
$this->save();
else if($action=='delete')
$this->delete();
else
$this->grid();
}
private function grid() {
echo "grid";
}
private function form() {
echo "form";
}
91
38
Base para criar um CRUD (2/2)
private function save() {
echo "save";
}
private function delete() {
echo "delete";
}
}
?>
<a href="?action=grid">GRID</a> |
<a href="?action=form">FORM</a> |
<a href="?action=save">SAVE</a> |
<a href="?action=delete">DELETE</a>
<hr>
<?php new crud(); ?>
92
Classe genérica para database
� Essa classe permitirá:� Melhor organização do código.� Reuso de código.� Estender e/ou melhorar funções do PHP.� Tornar mais transparente o uso do BD.� Permitir a troca do SGBD com facilidade.
93
39
database.php (1/3)<?php
class database {
private $link;
private $database;
private $ip = "127.0.0.1";
private $user = "root";
private $pass = "";
private $db = "db_aula";
function __construct($flag=false){
if($flag==true){
$this->connect();
}
}
function __destruct() {
$this->close();
}
protected function connect(){
$this->link = mysql_connect($this->ip, $this->user, $this->pass);
$this->database = mysql_select_db($this->db);
}
94
database.php (2/3)protected function close(){
$this->database = null;
if(!empty($this->link)) @mysql_close($this->link);
}
protected function query($sql){
return mysql_query($sql);
}
protected function execute($sql){
$sql = utf8_decode($sql);
return $this->query($sql) ? 1 : 0;
}
protected function affected_rows(){
return mysql_affected_rows();
}
protected function insert_id(){
return mysql_insert_id();
}
protected function num_rows($rs){
return empty($rs) ? 0 : mysql_num_rows($rs);
}
95
40
database.php (3/3)protected function result($sql,$index=0) {
$rs = $this->query($sql);
return ($this->num_rows($rs)>0) ? mysql_result($rs,$index) : null;
}
protected function fetch_array($rs){
return empty($rs) ? null : mysql_fetch_array($rs);
}
protected function select_id($sql){
$rs = $this->query($sql);
return $this->fetch_array($rs);
}
protected function select_all($sql){
$dados = array();
$rs = $this->query($sql);
while($r = $this->fetch_array($rs)){
$dados[] = $r;
}
return $dados;
}
} // fim da classe database
?>
96
Criando um CRUD completo
� Agora iremos juntar o uso da classe genérica para banco de dados com a estrutura geral para a criação de CRUD proposta anteriormente.
� Com isso, todas as funcionalidades de um módulo ficarão num mesmo arquivo e o método construtor se encarregará de definir qual ação deverá ser tomada.
97
41
Banco de Dados
Tabela PRODUTO
CREATE TABLE IF NOT EXISTS tb_produto (
cod_prod int(11) NOT NULL AUTO_INCREMENT,
descricao varchar(60) NOT NULL,
preco decimal(8,2) NOT NULL,
PRIMARY KEY (cod_prod)
);
98
Layout das Telas
99
42
produto.php (1/7)
<?php
require_once "database.php";
class produto extends database {
function __construct() {
@$this->action = $_GET['action'];
if($this->action=='grid')
$this->grid();
else if($this->action=='form')
$this->form();
else if($this->action=='save')
$this->save();
else if($this->action=='delete')
$this->delete();
else
$this->grid();
}
100
produto.php (2/7)private function grid() {
$sql = "SELECT cod_prod, descricao, preco
FROM tb_produto
ORDER BY cod_prod";
$this->connect();
$dados = $this->select_all($sql); ?>
<table border="1">
<th bgcolor=#EEEEEE>Gerenciar Agenda</th>
<tr><td>
<table border="0">
<tr>
<td> </td><td> </td>
<td width= "80"><b>Código</b></td>
<td width="200"><b>Descrição</b></td>
<td width="120" align="right"><b>Preço</b></td>
</tr> <?php
if(empty($dados)) {?>
<tr><td>Nenhum registro localizado.</td></tr> <?php
} else {
$tam = count($dados);
for($i=0; $i<$tam; $i++) {
101
43
produto.php (3/7)$r = $dados[$i];
$r['preco'] = "R$ ".number_format($r['preco'],2,',','.'); ?>
<tr>
<td><a href="?action=delete&cod_prod=
<?php echo $r['cod_prod']; ?>">
<img src="./img/excluir.png" border="0"></a></td>
<td><a href="?action=form&cod_prod=
<?php echo $r['cod_prod']; ?>">
<img src="./img/alterar.png" border="0"></a></td>
<td align="center"><?php echo $r['cod_prod']; ?></td>
<td><?php echo $r['descricao']; ?></td>
<td align="right"><?php echo $r['preco']; ?></td>
</tr> <?php
}
} ?>
</table>
</td></tr>
<tr><td colspan="5" align="left">
<input type=button value=Novo onClick="location='?action=form';">
</td></tr></table><?php
}
102
produto.php (4/7)private function form() {
@$r['cod_prod'] = $_GET['cod_prod'];
$r['descricao'] = null;
$r['preco'] = null;
if(!empty($r['cod_prod'])) {
$this->connect();
$sql = "SELECT * FROM tb_produto
WHERE cod_prod = ".$r['cod_prod'];
$r = $this->select_id($sql);
} ?>
<table border=1>
<th bgcolor=#EEEEEE>Formulário de Produtos</th>
<tr>
<td>
<table border="0">
<form method="POST" action="?action=save">
<tr>
<td>Código:</td>
<td><input type="text" name="cod_prod" READONLY
value="<?php echo $r['cod_prod']; ?>"></td>
</tr>
103
44
produto.php (5/7)<tr>
<td>Descrição:</td>
<td><input type="text" name="descricao"
value="<?php echo $r['descricao']; ?>"></td>
</tr>
<tr>
<td>Preço:</td>
<td><input type="text" name="preco"
value="<?php echo $r['preco']; ?>"></td>
</tr>
<tr>
<td><input type="submit" value="Salvar"></td>
<td align="right"><input type="button" value="Cancelar"
onClick="location='?action=grid';"></td>
</tr>
</form>
</table>
</td>
</tr>
</table> <?php
}
104
produto.php (6/7)private function save() {
$p = (object) $_POST;
$p->preco = str_replace(",", ".", $p->preco);
if(empty($p->cod_prod)) {
$sql = "INSERT INTO tb_produto(descricao, preco)
VALUES('".$p->descricao."',".$p->preco.")";
}
else {
$sql = "UPDATE tb_produto
SET descricao = '".$p->descricao."', preco=".$p->preco."
WHERE cod_prod = ".$p->cod_prod;
}
$this->connect();
$status = $this->execute($sql);
if($status==1)
$msg = "Sucesso ao gravar registro.";
else
$msg = "Erro ao gravar registro."; ?>
<script>
alert('<?php echo $msg; ?>');
location="?action=grid";
</script> <?php
}
105
45
produto.php (7/7)
private function delete() {
$cod_prod = $_GET['cod_prod'];
$sql = "DELETE FROM tb_produto
WHERE cod_prod = ".$cod_prod;
$this->connect();
$status = $this->execute($sql);
$msg = ($status==1)
? "Sucesso ao excluir registro."
: "Erro ao excluir registro."; ?>
<script>
alert('<?php echo $msg; ?>');
location="?action=grid";
</script> <?php
}
}
$p = new produto();
?>
106
Exercícios
1. Modificar o módulo de produto de forma que seja possível fazer upload de fotos dos produtos. As fotos podem ficar armazenadas dentro do banco de dados (maior segurança) ou numa pasta externa (maior agilidade), vinculando-se o nome do arquivo à PK do registro.
107
46
Mudanças no construtor ...
function __construct() {
@$this->action = $_GET['action'];
if($this->action=='grid')
$this->grid();
else if($this->action=='form')
$this->form();
else if($this->action=='save')
$this->save();
else if($this->action=='delete')
$this->delete();
else if($this->action=='file')
$this->file();
else if($this->action=='upload')
$this->upload();
else
$this->grid();
}action ‘photo’ será o formulário para envio da foto.action ‘upload’ receberá o arquivo postado e gravará no servidor.
108
Mudanças no grid ...private function grid() {
...
<tr>
<td> </td>
<td> </td>
<td> </td>
...
<tr>
<td><a href="?action=delete&cod_prod=
<?php echo $r['cod_prod']; ?>">
<img src="./img/excluir.png" border="0"></a></td>
<td><a href="?action=form&cod_prod=
<?php echo $r['cod_prod']; ?>">
<img src="./img/alterar.png" border="0"></a></td>
<td><a href="?action=file&cod_prod=
<?php echo $r['cod_prod']; ?>">
<img src="./img/upload.png" border="0"></a></td>
...
}
Adicionar uma coluna para opção de upload de foto. 109
47
Exercícios
2. Criar um módulo de controle de acesso para que somente usuários autorizados possam acessar o módulo de produtos. O módulo deve ser criado baseado em programação orientada a objetos.
114
Exercícios
3. Criar um módulo para uma vitrine virtual, na qual qualquer o visitante possa consultar os produtos. Deve existir um campo para consulta por descrição e o resultado deve ser exibido com paginação.
115
48
Exercícios
4. Criar um módulo para carrinho de compras nos moldes de uma loja virtual. O usuário poderá adicionar seus produtos nesse carrinho.
116
Programação em 3 Camadas
� A programação em 3 Camadas - MVC (Model, View e Controller) – é uma técnica que consiste em separar a programação em três partes responsáveis por:
� Exibir as informações (view)
� Controlar as regras de negócio (controller)
� Acessar o banco de dados (model)
117
49
MVC - Funcionamento
Visão (View)
Controle (Controller)
Dados (Model)
1. A camada de Visão solicita as informações para a camada de Controle
3
41
2
2. A camada de Controle aplica as regras de negócio e aciona a camada de Dados.
3. A camada de Dados acessa o Banco de Dados e retorna o resultado obtido para a camada de Controle.
4. A camada de Controle repassa os dados prontos para a camada de Visão, que finalmente exibe na tela.
118
MVC – Principais Vantagens� Organização
� Separação lógica das funcionalidades
� Manutenção� O código fica mais organizado
� Produtividade� É possível ter mais de um programador trabalhando simultaneamente num mesmo módulo
� Reuso de código� É possível substituir uma camada sem fazer modificações nas demais.
� É possível ter mais de uma camada de visão compartilhando as camadas de controle e de dados.
119
50
Banco de Dados
Tabela CLIENTECREATE TABLE IF NOT EXISTS tb_cliente(
cod_cli integer not null auto_increment,
nome varchar(80),
fone varchar(20),
PRIMARY KEY(cod_cli)
);
Inclusão de dadosINSERT INTO tb_cliente(nome,fone) VALUES
('Enzo', '(14) 3333-3333'),
('Renan', '(19) 4444-4444'),
('Igor', '(19) 5555-5555'),
('Gustavo', '(48) 9999-9999'),
('Hiago', '(19) 2222-2222');
COMMIT;
Banco de DadosCREATE DATABASE IF NOT EXISTS db_aula;USE db_aula;
120
MVC para listagem simples (1/2)<?php
class cliente {
function __construct() {
$this->view();
}
public function view() {
$dados = $this->controller();
if(empty($dados)) { echo "Nenhum registro localizado!"; }
else {
$qtde = count($dados);
for($i=0; $i<$qtde; $i++) {
$r = $dados[$i];
echo $r["cod_cli"] . " | " .
$r["nome"] . " | " .
$r["fone"] . "<br />";
}
}
echo '<hr /><form>Pesquisar por: <input name="filtro">
<input type="submit" value="Buscar"></form>';
}
121
51
MVC para listagem simples (2/2)public function controller() {
@$filtro = addslashes(trim($_GET['filtro']));
return $this->model($filtro);
}
public function model($filtro) {
$link = mysql_connect("127.0.0.1", "root", "");
mysql_select_db("db_aula");
$sql = "SELECT cod_cli, nome, fone FROM tb_cliente
WHERE nome LIKE '$filtro%'";
$rs = mysql_query($sql);
$dados = Array();
if(!empty($rs) AND mysql_num_rows($rs)>0) {
while($r = mysql_fetch_array($rs)) {
$dados[] = $r;
}
}
return $dados;
}
}
$c = new cliente();
?>
122
Duas visões compartilhando as camadas de controle e de dados
� Vamos modificar a classe de clientes criando duas versões de listagem da camada de visão: web e mobile. As camadas de controle e de dados devem ser compartilhadas pelas 2 visões.� index.php (detectar o dispositivo utilizado)
123
52
Aparência de cada visão:
viewMobile viewWeb
Normalmente, a versão Web não tem a opção para selecionar a versão Mobile
124
index.php
<script>
(screen.width<700)
? location="cliente.php?versao=mobile"
: location="cliente.php?versao=web";
</script>
Verifica se a resolução e redireciona para a versão correta.
125
53
cliente.php (1/3)<link rel="stylesheet" type="text/css" href="cliente.css" />
<?php
class cliente {
function __construct() {
@$versao = $_GET['versao'];
$versao=="mobile" ? $this->viewMobile() : $this->viewWeb();
}
public function viewWeb() {
$dados = $this->controller();
if(empty($dados)) { echo "Nenhum registro localizado!"; }
else {
$qtde = count($dados);
for($i=0; $i<$qtde; $i++) {
$r = $dados[$i];
echo '<div class="cliente_web">#'.$r["cod_cli"]."<br />".
$r["nome"]."<br />".$r["fone"].'</div>';
}
}
126
cliente.php (2/3)echo '<form style="clear:both; text-align=center;">Pesquisar por:
<input name="filtro"><input type="submit" value="Buscar">
</form>';
echo '<div class="versao_web">
<span class="disable">Web | </span>
<a href="?versao=mobile">Mobile</a>
</div>';
}
public function viewMobile() {
$dados = $this->controller();
if(empty($dados)) { echo "Nenhum registro localizado!"; }
else {
$qtde = count($dados);
for($i=0; $i<$qtde; $i++) {
$r = $dados[$i];
echo '<div class="cliente_mobile">'.
$r["nome"] . '<br />' . $r["fone"] . '</div>';
}
}
127
54
cliente.php (3/3)echo '<form>Pesquisar: <input name="filtro">
<input type="submit" value="Buscar"></form>';
echo '<div class="versao_mobile"><a href="?versao=web">Web</a>
<span class="disable"> | Mobile</span>';
}
public function controller() {
...
}
public function model($filtro) {
...
}
}
$c = new cliente();
?>
128
cliente.cssbody {
font-family: verdana, arial;
color: #0033AA;
}
a {
text-decoration: none;
color: #0033AA;
}
.cliente_mobile {
border-top: solid 1px #0033AA;
border-left: solid 1px #0033AA;
margin-bottom: 10px;
padding: 3px;
width: 300px;
}
.versao_mobile {
border-top: solid 1px #0033AA;
width: 300px;
text-align: center;
}
.cliente_web {
float: left;
border: solid 1px #0033AA;
margin: 5px;
padding: 7px;
width: 150px;
height: 80px;
text-align: center;
background-color: #C6E2FF;
}
.versao_web {
border-top: solid 1px #0033AA;
width: 100%;
text-align: center;
}
.disable {
color: #999999;
}
129
55
MVC separado em 3 classes
� Agora iremos refazer o mesmo programa, mas separando as camadas em 3 classes (separadas em 3 arquivos)
� Vantagens:� Cada camada torna-se independente, podendo-se substituir/atualizar apenas a camada desejada.
� Permite que mais de um programador possa trabalhar simultaneamente num mesmo módulo, cada um manipulando um arquivo.
� É possível ter mais de uma camada de visão� Por exemplo, uma view pode apresentar a listagem para PC e outra view pode ser criada para dispositivos móveis.
130
cliente.view.php<?php
include "cliente.controller.php";
class clienteView {
public function listar() {
$c = new clienteController();
$dados = $c->listar();
if(empty($dados)) {
echo "Nenhum registro localizado!";
}
else {
$qtde = count($dados);
for($i=0; $i<$qtde; $i++) {
$r = $dados[$i];
echo $r["cod_cli"]." | ".$r["nome"]." | ".$r["fone"]."<br />";
}
}
echo '<hr /><form>Pesquisar por: <input name="filtro">
<input type="submit" value="Buscar"></form>';
}
}
$v = new clienteView();
$v->listar();
?>
131
56
cliente.controller.php
<?php
include "cliente.model.php";
class clienteController {
public function listar() {
@$filtro = addslashes(trim($_GET['filtro']));
$m = new clienteModel();
return $m->listar($filtro);
}
}
?>
132
cliente.model.php
<?php
class clienteModel {
public function listar($filtro) {
$link = mysql_connect("127.0.0.1", "root", "");
mysql_select_db("db_aula");
$sql = "SELECT cod_cli, nome, fone
FROM tb_cliente
WHERE nome LIKE '$filtro%'";
$rs = mysql_query($sql);
$dados = Array();
if(!empty($rs) AND mysql_num_rows($rs)>0) {
while($r = mysql_fetch_array($rs)) {
$dados[] = $r;
}
}
return $dados;
}
}
?>
133
57
Independência entre as Camadas
� Cada camada cumpre sua função de forma independente� As camadas de controle e de dados não sabem com os dados são apresentados.
� As camadas de visão e de controle não sabe qual banco de dados está sendo usado.
� As camadas de visão e de dados não sabem como os dados são validados.
� A atualização de uma camada é independente� Se desejar trocar o banco de dados MySQL por Oracle, basta substituir o arquivo cliente.model.php.
� Se desejar criar uma versão para celular, basta criar um novo arquivo clienteMobile.view.php.
� Para cada classe é criado um método “listar”, cada um cumprindo seu papel na respectiva camada.
134
Exercícios
1. Usando MVC, criar uma listagem de livros com os campos: cod_livro, titulo, autor e ano (de publicação).
2. Acrescentar a capa do livro na exibição da listagem.
3. Criar uma segunda visão para apresentar a listagem em dispositivos móveis.
4. Substituir a camada de dados para que seja utilizado outro SGBD no lugar do MySQL.
135
58
EXTJS
� Framework para RIA (Rich Internet Applications)
� Biblioteca JavaScript cross-browser
� Camada de Visão (MVC)
� Suporta diversas linguagens (integração via JSON)
� Utiliza JS, XML, JSON, CSS e AJAX
� Interfaces baseadas em janelas e grids
� Licença GPL ou licença comercial (U$ 329,00)
136
Carregando o ExtJS:
� ext-all.csscontém os estilos que fazem a ligação do HTML gerado pelo ExtJS com a “Skin”, a qual contém inúmeras linhas de estilos e ligações com imagens.
� ext-all.jscontém o código de todos os componentes visuais e não visuais da biblioteca.
<link rel="stylesheet" type="text/css" href="./extjs/resources/css/ext-all.css">
<script type="text/javascript" src="./extjs/ext-all.js"></script>
137
59
Banco de DadosCREATE DATABASE IF NOT EXISTS db_aula;
USE db_aula;
CREATE TABLE IF NOT EXISTS tb_empresas (
codigo integer not null auto_increment primary key,
empresa varchar(50),
valor decimal(8,2),
variacao decimal(6,2),
data date,
ativo integer,
check(ativo in(0,1))
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_swedish_ci AUTO_INCREMENT=11;
INSERT INTO tb_empresas(codigo,empresa,valor,variacao,data,ativo) VALUES
( 1, '3m Co' , 71.72, 0.03, '2011-09-10', 1),
( 2, 'Alcoa Inc' , 29.01, 1.47, '2011-09-09', 1),
( 3, 'Altria Group Inc' , 83.81, 0.34, '2011-09-08', 0),
( 4, 'American Express Company' , 52.55, 0.02, '2011-09-07', 1),
( 5, 'American International Group, Inc.' , 64.13, 0.49, '2011-09-06', 1),
( 6, 'AT&T Inc.' , 31.61, -1.54, '2011-09-05', 1),
( 7, 'Boeing Co.' , 75.43, 0.71, '2011-09-04', 1),
( 8, 'Caterpillar Inc.' , 67.27, 1.39, '2011-09-03', 1),
( 9, 'Citigroup, Inc.' , 49.37, 0.04, '2011-09-02', 1),
(10, 'E.I. du Pont de Nemours and Company', 40.48, 1.28, '2011-09-01', 1);
COMMIT;
138
Criando a janela do grid<!doctype html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="./ext-4.1.1a/resources/css/ext-all.css" />
<script src="./ext-4.1.1a/ext-all.js"></script>
</head>
<body>
<script>
Ext.onReady(function(){
var winGrid = Ext.create('widget.window', {
title: 'Empresas',
maximizable: true,
closable: true,
closeAction: 'hide',
width: 500,
minWidth: 300,
height: 300
});
winGrid.show();
});
</script>
</body>
</html>
Ext.onReady indica que já está pronto.Ext.create é usado para instanciar objetos.show() é o método para janela.
139
60
Criando o grid (1/3)<!doctype html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="./ext-4.1.1a/resources/css/ext-all.css" />
<script src="./ext-4.1.1a/ext-all.js"></script>
</head>
<body>
<script>
Ext.onReady(function(){
Ext.define('Empresa', {
extend: 'Ext.data.Model',
fields: [
{name: 'codigo', type: 'int'},
{name: 'empresa', type: 'string'},
{name: 'valor', type: 'float'},
{name: 'variacao', type: 'float'},
{name: 'data', type: 'date', dateFormat: 'Y-m-d'},
{name: 'ativo', type: 'boolean'}
]
});
140
Criando o grid (2/3)var store = Ext.create('Ext.data.Store', {
model: 'Empresa',
autoLoad: true,
proxy: {
type: 'ajax',
url: 'listagem_simples.php',
reader: {
type: 'json',
root: 'dados'
}
}
});
var grid = Ext.create('Ext.grid.Panel', {
border: false,
store: store,
columns: [
{ text: 'Código', width: 60, dataIndex: 'codigo' },
{ text: 'Empresa', flex: 1, dataIndex: 'empresa' },
{ text: 'Valor', width: 75, dataIndex: 'valor' },
{ text: 'Variação', width: 75, dataIndex: 'variacao' },
{ text: 'Data', width: 85, dataIndex: 'data' },
{ text: 'Situação', width: 60, dataIndex: 'ativo' }
]
});
typ indica que a requisição usará ajax.url indica o programa que irá processar a chamada.json é o formato dos dados.root indica que a raiz do retorno chama-se dados.
141
61
Criando o grid (3/3)
var winGrid = Ext.create('widget.window', {
title: 'Empresas',
layout: 'fit',
maximizable: true,
collapsible: true,
closable: true,
closeAction: 'hide',
width: 500,
minWidth: 300,
height: 300,
items: grid
}).show();
});
</script>
</body>
</html>
142
listagem_simples.php
<?php
$link = mysql_connect("127.0.0.1", "root", "");
$db = mysql_select_db("db_aula");
$sql = "SELECT codigo, empresa, valor, variacao, data, ativo
FROM tb_empresas";
$rs = mysql_query($sql);
$dados = array();
while($obj = mysql_fetch_object($rs)){
$obj->empresa = utf8_encode($obj->empresa);
$dados[] = $obj;
}
mysql_close($link);
echo json_encode(array("dados" => $dados));
?>
143
62
Formatando os campos do grid
144
Renderizando os campos (1/3)
columns:
[{
text: 'Código',
width: 60,
dataIndex: 'codigo',
align: 'right'
},{
text: 'Empresa',
flex: 1,
dataIndex: 'empresa',
renderer: Ext.util.Format.uppercase
},{
text: 'Valor',
width: 75,
dataIndex: 'valor',
align: 'right',
renderer: function(val) {
return 'R$ ' + Ext.util.Format.number(val);
}
},{
Vamos atualizar as colunas do grid, adicionando as formatações dos campos.
145
63
Renderizando os campos (2/3)
text: 'Variação',
width: 75,
dataIndex: 'variacao',
align: 'center',
renderer: function(val) {
if (val >= 0) {
return '<span style="color:green;">' + val + '%</span>';
} else {
return '<span style="color:red;">' + val + '%</span>';
}
}
},{
text: 'Data',
width: 85,
dataIndex: 'data',
align: 'center',
renderer: Ext.util.Format.dateRenderer('d/m/Y')
},{
146
Renderizando os campos (3/3)
text: 'Situação',
width: 60,
dataIndex: 'ativo',
align: 'center',
renderer: function(val){
icone = (val==1) ? './img/ativo.gif' : './img/inativo.gif';
return '<img src="' + icone + '" style="width:12px; height12px;">';
}
}]
147
64
Ordenação
148
Grid com ordenação
var store = Ext.create('Ext.data.Store', {
model: 'Empresa',
autoLoad: true,
remoteSort: true,
sorters: [{
property: 'codigo',
direction: 'ASC'
}],
proxy: {
type: 'ajax',
url: 'listagem_ordenacao.php',
reader: {
type: 'json',
root: 'dados'
}
}
});property indica o campo padrão para ordenardirection indica se será crescente (ASC) ou decrescente (DESC).
149
65
listagem_ordenacao.php<?php
@$sort = $_REQUEST['sort'];
if(empty($sort)) {
$sort->property = 'codigo';
$sort->direction = 'ASC';
} else {
$sorters = json_decode(stripslashes($sort));
$sort = $sorters[0];
}
$link = mysql_connect("127.0.0.1", "root", "");
$db = mysql_select_db("db_aula");
$sql = "SELECT codigo, empresa, valor, variacao, data, ativo
FROM tb_empresas
ORDER BY $sort->property $sort->direction";
$rs = mysql_query($sql);
$dados = array();
while($obj = mysql_fetch_object($rs)){
$obj->empresa = utf8_encode($obj->empresa);
$dados[] = $obj;
}
mysql_close($link);
echo json_encode(array("dados" => $dados));
?>
150
Paginação
151
66
Grid com paginaçãovar store = Ext.create('Ext.data.Store', {
model: 'Empresa',
autoLoad: true,
pageSize: 5,
proxy: {
type: 'ajax',
url: 'listagem_paginacao.php',
reader: {
totalProperty: 'total',
type: 'json',
root: 'dados'
}
}
});
var grid = Ext.create('Ext.grid.Panel', {
bbar: Ext.create('Ext.PagingToolbar', {
store: store,
displayInfo: true,
displayMsg: 'Exibindo {0} - {1} de {2}',
beforePageText : 'Página',
afterPageText : 'de {0}',
emptyMsg: "Nenhum registro localizado"
}),
...
});
pageSize indica a quantidade de registros por página.totalProperty indica o campo que retorná o total de registros da tabela.bbar é a barra de ferramentas inferior.
152
listagem_paginacao.php<?php
$limit = $_REQUEST['limit'];
$start = $_REQUEST['start'];
$link = mysql_connect("127.0.0.1", "root", "");
$db = mysql_select_db("db_aula");
$sql = "SELECT COUNT(*) FROM tb_empresas";
$rs = mysql_query($sql);
$total = mysql_result($rs,0);
$sql = "SELECT codigo, empresa, valor, variacao, data, ativo
FROM tb_empresas
LIMIT $start, $limit";
$rs = mysql_query($sql);
$dados = array();
while($obj = mysql_fetch_object($rs)){
$obj->empresa = utf8_encode($obj->empresa);
$dados[] = $obj;
}
mysql_close($link);
echo json_encode(array("dados" => $dados, "total" => $total));
?>
153
67
Consulta com filtro
154
Grid com filtro<head>
<style>.filter{background-image: url('./img/filter.gif')}</style>
...
var grid = Ext.create('Ext.grid.Panel', {
tbar: Ext.create('Ext.toolbar.Toolbar', {
items:
[ '->', 'Pesquisar por: ', {
id: 'filtro',
xtype: 'textfield',
width: 100
},{
text:'Filtrar',
iconCls: 'filter',
handler:function() {
store.reload({
params: { 'filtro': Ext.getCmp('filtro').getValue() }
})
}
}]
}),
...
});
reload recarrega o store.handler ação a ser executada ao clicar no botão.params indica os parâmetros passados ao store.
155
68
listagem_filtro.php
<?php
@$filtro = trim(addslashes($_REQUEST['filtro']));
$link = mysql_connect("127.0.0.1", "root", "");
$db = mysql_select_db("db_aula");
$sql = "SELECT codigo, empresa, valor, variacao, data, ativo
FROM tb_empresas
WHERE empresa LIKE '$filtro%'";
$rs = mysql_query($sql);
$dados = array();
while($obj = mysql_fetch_object($rs)){
$obj->empresa = utf8_encode($obj->empresa);
$dados[] = $obj;
}
mysql_close($link);
echo json_encode(array("dados" => $dados));
?>
156
Exercício
� Criar um grid para apresentar as empresas que permita ordenar, paginar e filtrar simultaneamente.� Basicamente, iremos juntar todos os recursos vistos até aqui num único programa.
157
69
Formulário
� Muitas formatações e validações de campos em formulários são realizadas automaticamente pelo EXTJS.
158
formulario.php (1/6)<!doctype html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="./ext-4.1.1a/resources/css/ext-all.css" />
<script src="./ext-4.1.1a/ext-all.js"></script>
<script src="./ext-4.1.1a/locale/ext-lang-pt_BR.js"></script>
<style>
.save{background-image: url('./img/save.png')}
.cancel{background-image: url('./img/cancel.png')}
</style>
</head>
<body>
<script>
Ext.onReady(function(){
var form = Ext.create('Ext.form.Panel', {
frame:true,
bodyStyle:'padding:5px 5px 0',
baseCls: 'x-plain',
locale para definir o idioma das mensagens padrões do EXTJS.Ext.form.Panel é o componente para criação de formulários.
159
70
formulario.php (2/6)fieldDefaults: {
allowBlank: false,
labelAlign: 'left',
labelWidth: 80,
width: 200,
labelSeparator: ':',
anchor: '100%',
msgTarget: 'side'
},
items: [{
name: 'codigo',
allowBlank: true,
hidden: true
},{
name: 'empresa',
xtype: 'textfield',
fieldLabel: 'Empresa',
emptyText:'Digite o nome da empresa',
maxLength: 50,
maxLengthText: 'A empresa deve ter no máximo 50 caracteres.'
},{
fieldDefaults valor padrão para os campos do formulário.allowBlank indica se o campo pode ser vazio.msgTarget exibe as mensagens de erro na lateral.hidden indica campo ocultoxtype define o tipo de campo
160
formulario.php (3/6)name: 'valor',
xtype: 'numberfield',
hideTrigger: true,
fieldLabel: 'Valor'
},{
name: 'variacao',
xtype: 'numberfield',
value: 0,
minValue: -100,
maxValue: 100,
allowDecimals: true,
decimalPrecision: 2,
step: 0.01,
fieldLabel: 'Variação'
},{
name: 'data',
xtype: 'datefield',
fieldLabel: 'Data'
},{
161
71
formulario.php (4/6)name: 'ativo',
xtype: 'checkbox',
inputValue: 1,
checked: true,
fieldLabel: 'Situação'
}]
});
var winForm = Ext.create('widget.window', {
title: 'Formulário',
layout: 'fit',
resizable: false,
modal: true,
closable: true,
closeAction: 'hide',
width: 350,
border: false,
items: form,
buttonAlign:'center',
162
formulario.php (5/6)buttons: [{
text: 'Salvar',
iconCls: 'save',
scale: 'medium',
handler: function() {
if(form.getForm().isValid()) {
winForm.el.mask('Salvando...', 'x-mask-loading');
form.getForm().submit({
url: 'insert.php',
method: 'POST',
success: function(form, action){
Ext.Msg.alert('SUCESSO', 'Registro salvo com sucesso!');
winForm.el.unmask();
form.reset();
},
failure: function(form, action){
winForm.el.unmask();
Ext.Msg.alert('ERRO', 'Falha ao salvar registro');
}
});
}
}
163
72
formulario.php (6/6)},{
text: 'Cancelar',
iconCls: 'cancel',
scale: 'medium',
handler: function() {
form.reset();
}
}]
}).show();
});
</script>
</body>
</html>
164
insert.php<?php
@$empresa = trim(addslashes($_REQUEST['empresa']));
@$valor = $_REQUEST['valor'];
@$variacao = $_REQUEST['variacao'];
@$data = $_REQUEST['data'];
@$ativo = empty($_REQUEST['ativo']) ? 0 : 1;
if(!empty($data)) $data = "'".implode('-',array_reverse(explode('/',$data)))."'";
$link = mysql_connect("127.0.0.1", "root", "");
$db = mysql_select_db("db_aula");
$sql = "INSERT INTO tb_empresas(empresa, valor, variacao, data, ativo)
VALUES('$empresa', $valor, $variacao, $data, $ativo)";
$status = mysql_query($sql);
mysql_close($link);
$msg = ($status==1)
? 'Sucesso ao inserir registro'
: 'Erro ao inserir registro';
echo json_encode(array('success'=>$status, 'msg'=> utf8_encode($msg)));
?>
165
73
Criando um CRUD
� Agora iremos juntar o grid e o formulário, de forma que poderemos fazer as 4 operações (select, insert, update, delete)
166
crud.php (1/9)
<!doctype html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="./ext-4.1.1a/resources/css/ext-all.css" />
<script src="./ext-4.1.1a/ext-all.js"></script>
<script src="./ext-4.1.1a/locale/ext-lang-pt_BR.js"></script>
<style>
.insert{background-image: url('./img/insert.png')}
.update{background-image: url('./img/update.png')}
.delete{background-image: url('./img/delete.png')}
.save {background-image: url('./img/save.png' )}
.cancel{background-image: url('./img/cancel.png')}
</style>
</head>
<body>
<script>
167
74
crud.php (2/9)Ext.onReady(function(){
Ext.define('Empresa', {
extend: 'Ext.data.Model',
fields: [
{name: 'codigo', type: 'int'},
{name: 'empresa', type: 'string'},
{name: 'valor', type: 'float'},
{name: 'variacao', type: 'float'},
{name: 'data', type: 'date', dateFormat: 'Y-m-d'},
{name: 'ativo', type: 'boolean'}
]
});
var store = Ext.create('Ext.data.Store', {
model: 'Empresa',
autoLoad: true,
proxy: {
type: 'ajax',
url: 'select.php',
reader: { type: 'json', root: 'dados' }
}
});
168
crud.php (3/9)var grid = Ext.create('Ext.grid.Panel', {
border: false,
store: store,
columns: [
{ text: 'Código', width: 60, dataIndex: 'codigo' },
{ text: 'Empresa', flex: 1, dataIndex: 'empresa' },
{ text: 'Valor', width: 75, dataIndex: 'valor' },
{ text: 'Variação', width: 75, dataIndex: 'variacao' },
{ text: 'Data', width: 85, dataIndex: 'data' },
{ text: 'Situação', width: 60, dataIndex: 'ativo' }
],
tbar: Ext.create('Ext.toolbar.Toolbar', {
items: [{
text: 'Incluir',
iconCls: 'insert',
handler: function() {
winForm.action = 'insert';
winForm.setTitle('Form [Inserindo]');
winForm.show();
form.getForm().reset();
}
},{
169
75
crud.php (4/9)text: 'Alterar',
iconCls: 'update',
handler: function() {
if(grid.getSelectionModel().hasSelection()){
var record = grid.getSelectionModel().getSelection();
form.getForm().loadRecord(record[0]);
winForm.action = 'update';
winForm.setTitle('Form [Alterando]');
winForm.show();
}else{
Ext.Msg.alert('AVISO','Selecione o registro para alterar.');
}
}
},{
text: 'Apagar',
iconCls: 'delete',
handler: function() {
if(grid.getSelectionModel().hasSelection()){
var record = grid.getSelectionModel().getSelection();
Ext.Msg.confirm(
'Atenção',
'Confirma a exclusão do registro selecionado?',
function(btn){
if(btn == 'yes'){
170
crud.php (5/9)Ext.Ajax.request({
url: 'delete.php',
params: {codigo: record[0].data.codigo},
success: function(r){
var obj = Ext.decode(r.responseText);
if(obj.success){ store.load(); }
else{ Ext.Msg.alert('ERRO',obj.msg); }
},
failure: function(){
Ext.Msg.alert('Erro no servidor.')
}
});
}
});
}else{
Ext.Msg.alert('AVISO','Selecione o registro para apagar.');
}
}
}]
})
});
171
76
crud.php (6/9)var winGrid = Ext.create('widget.window', {
title: 'Empresas',
layout: 'fit',
maximizable: true,
closable: true,
closeAction: 'hide',
width: 500,
minWidth: 300,
height: 300,
items: grid
}).show();
var form = Ext.create('Ext.form.Panel', {
frame:true,
bodyStyle:'padding:5px 5px 0',
baseCls: 'x-plain',
fieldDefaults: {
allowBlank: false,
labelAlign: 'left',
labelWidth: 80,
width: 200,
labelSeparator: ':',
anchor: '100%',
msgTarget: 'side'
},
172
crud.php (7/9)items: [
{ name:'codigo', xtype:'numberfield', allowBlank:true, hidden:true },
{ name:'empresa', xtype:'textfield', fieldLabel:'Empresa' },
{ name:'valor', xtype:'numberfield', hideTrigger:true, fieldLabel:'Valor'},
{ name: 'variacao', xtype: 'numberfield', fieldLabel: 'Variação' },
{ name:'data', xtype:'datefield', fieldLabel:'Data' },
{ name:'ativo', xtype:'checkbox', fieldLabel:'Situação', checked:true } ]
});
var winForm = Ext.create('widget.window', {
title: 'Formulário',
layout: 'fit',
resizable: false,
modal: true,
closable: true,
closeAction: 'hide',
width: 350,
border: false,
items: form,
buttonAlign:'center',
173
77
crud.php (8/9)buttons: [{
text: 'Salvar',
iconCls: 'save',
scale: 'medium',
handler: function() {
if(form.getForm().isValid()) {
winForm.el.mask('Salvando...', 'x-mask-loading');
form.getForm().submit({
url: winForm.action + '.php',
method: 'POST',
success: function(form, action){
Ext.Msg.alert('SUCESSO', action.result.msg);
winForm.el.unmask();
form.reset();
winForm.hide();
store.reload();
},
failure: function(form, action){
winForm.el.unmask();
Ext.Msg.alert('ERRO', action.result.msg);
}
});
}
}
174
crud.php (9/9)
},{
text: 'Cancelar',
iconCls: 'cancel',
scale: 'medium',
handler: function() {
winForm.hide();
}
}]
});
});
</script>
</body>
</html>
175
78
select.php<?php
$link = mysql_connect("127.0.0.1", "root", "");
$db = mysql_select_db("db_aula");
$sql = "SELECT codigo, empresa, valor, variacao, data, ativo
FROM tb_empresas";
$rs = mysql_query($sql);
$dados = array();
if(!empty($rs) && mysql_num_rows($rs)>0) {
while($obj = mysql_fetch_object($rs)){
$obj->empresa = utf8_encode($obj->empresa);
$dados[] = $obj;
}
}
mysql_close($link);
echo json_encode(array("dados" => $dados));
?>
176
insert.php<?php
@$empresa = trim(addslashes($_REQUEST['empresa']));
@$valor = $_REQUEST['valor'];
@$variacao = $_REQUEST['variacao'];
@$data = $_REQUEST['data'];
@$ativo = empty($_REQUEST['ativo']) ? 0 : 1;
if(!empty($data)) $data = "'".implode('-',array_reverse(explode('/',$data)))."'";
$link = mysql_connect("127.0.0.1", "root", "");
$db = mysql_select_db("db_aula");
$sql = "INSERT INTO tb_empresas(empresa, valor, variacao, data, ativo)
VALUES('$empresa', $valor, $variacao, $data, $ativo)";
$status = mysql_query($sql);
mysql_close($link);
$msg = ($status==1)
? 'Sucesso ao inserir registro' : 'Erro ao inserir registro';
echo json_encode(array('success'=>$status, 'msg'=> utf8_encode($msg)));
?>
177
79
update.php<?php
@$codigo = $_REQUEST['codigo'];
@$empresa = trim(addslashes($_REQUEST['empresa']));
@$valor = $_REQUEST['valor'];
@$variacao = $_REQUEST['variacao'];
@$data = $_REQUEST['data'];
@$ativo = empty($_REQUEST['ativo']) ? 0 : 1;
if(!empty($data)) $data = "'".implode('-',array_reverse(explode('/',$data)))."'";
$link = mysql_connect("127.0.0.1", "root", "");
$db = mysql_select_db("db_aula");
$sql = "UPDATE tb_empresas
SET empresa='$empresa',valor=$valor,variacao=$variacao,data=$data,ativo=$ativo
WHERE codigo = $codigo";
$status = mysql_query($sql);
mysql_close($link);
$msg = ($status==1)
? 'Sucesso ao inserir registro' : 'Erro ao inserir registro';
echo json_encode(array('success'=>$status, 'msg'=> utf8_encode($msg)));
?>
178
delete.php
<?php
@$codigo = $_REQUEST['codigo'];
$link = mysql_connect("127.0.0.1", "root", "");
$db = mysql_select_db("db_aula");
$sql = "DELETE FROM tb_empresas WHERE codigo = $codigo";
$status = mysql_query($sql);
mysql_close($link);
$msg = ($status==1)
? 'Sucesso ao apagar registro' : 'Erro ao apagar registro';
echo json_encode(array('success'=>$status, 'msg'=> utf8_encode($msg)));
?>
179
80
Melhorando o código PHP
� Agora, iremos voltar a trabalhar com POO no PHP. Para isso, iremos criar uma classe empresa que fará as 4 operações do CRUD.
� O acionamento das funcionalidades será feito através do método construtor, que deverá receber a ação a ser executada.
180
Ajustes no EXTJS// SELECT
var store = Ext.create('Ext.data.Store', {
model: 'Empresa',
autoLoad: true,
proxy: {
type: 'ajax',
url: 'empresa.php',
extraParams: { action: 'select' },
...
// INSERT e UPDATE
form.getForm().submit({
url: 'empresa.php',
params: { action: winForm.action },
...
// DELETE
Ext.Ajax.request({
url: 'empresa.php',
params: {codigo: record[0].data.codigo, action: 'delete'},
...
181
81
empresa.php (1/5)<?php
class empresa {
function __construct() {
mysql_connect("127.0.0.1", "root", "");
mysql_select_db("db_aula");
@$action = $_REQUEST['action'];
if($action=='select')
$this->select();
else if($action=='insert')
$this->insert();
else if($action=='update')
$this->update();
else if($action=='delete')
$this->delete();
}
function __destruct() {
mysql_close();
}
182
empresa.php (2/5)
private function select() {
$sql = "SELECT codigo, empresa, valor, variacao, data, ativo
FROM tb_empresas";
$rs = mysql_query($sql);
$dados = array();
if(!empty($rs) AND mysql_num_rows($rs)>0) {
while($obj = mysql_fetch_object($rs)){
$obj->empresa = utf8_encode($obj->empresa);
$dados[] = $obj;
}
}
echo json_encode(array("dados" => $dados));
}
183
82
empresa.php (3/5)
private function insert() {
@$empresa = trim(addslashes($_REQUEST['empresa']));
@$valor = $_REQUEST['valor'];
@$variacao = $_REQUEST['variacao'];
@$data = $_REQUEST['data'];
@$ativo = empty($_REQUEST['ativo']) ? 0 : 1;
if(!empty($data)) $data = "'".implode('-',array_reverse(explode('/',$data)))."'";
$sql = "INSERT INTO tb_empresas(empresa, valor, variacao, data, ativo)
VALUES('$empresa', $valor, $variacao, $data, $ativo)";
$status = mysql_query($sql);
$msg = ($status==1)
? 'Sucesso ao inserir registro' : 'Erro ao inserir registro';
echo json_encode(array('success'=>$status, 'msg'=> utf8_encode($msg)));
}
184
empresa.php (4/5)private function update() {
@$codigo = $_REQUEST['codigo'];
@$empresa = trim(addslashes($_REQUEST['empresa']));
@$valor = $_REQUEST['valor'];
@$variacao = $_REQUEST['variacao'];
@$data = $_REQUEST['data'];
@$ativo = empty($_REQUEST['ativo']) ? 0 : 1;
if(!empty($data)) $data = "'".implode('-',array_reverse(explode('/',$data)))."'";
$sql = "UPDATE tb_empresas
SET empresa='$empresa',
valor=$valor,
variacao=$variacao,
data=$data,
ativo=$ativo
WHERE codigo = $codigo";
$status = mysql_query($sql);
$msg = ($status==1)
? 'Sucesso ao atualizar registro' : 'Erro ao atualizar registro';
echo json_encode(array('success'=>$status, 'msg'=> utf8_encode($msg)));
}
185
83
empresa.php (5/5)
private function delete() {
@$codigo = $_REQUEST['codigo'];
$sql = "DELETE FROM tb_empresas WHERE codigo = $codigo";
$status = mysql_query($sql);
$msg = ($status==1)
? 'Sucesso ao apagar registro' : 'Erro ao apagar registro';
echo json_encode(array('success'=>$status,
'msg'=> utf8_encode($msg)));
}
}
new empresa();
?>
186
Modelo MVC + POO herança
� Esta proposta unifica as vantagens de cada padrão, gerando um modelo organizado, robusto e de alta produtividade.
classmoduleView
classmoduleController
classmoduleModel
classcoreView
classcoreController
classcoreModel
187
84
Exemplo MVC + POO herança
empresaView.js
empresaController.php
empresaModel.php
coreView.js
coreController.php
coreModel.php
188
Criando as 3 classes do CORE
� As 3 classes a seguir servirão de base para todos os grids a serem criados.� coreView.js� coreController.php� coreModel.php
189
85
coreView.js (1/4)
Ext.require([
'Ext.grid.*',
'Ext.data.*',
'Ext.form.*'
]);
Ext.define('Ext.grid.coreView', {
extend: 'Ext.util.Observable',
constructor: function(){
this.callParent();
Ext.QuickTips.init();
Ext.BLANK_IMAGE_URL = '../img/s.gif';
this.initStore();
this.initGrid();
},
190
coreView.js (2/4)initStore: function() {
Ext.define('Ext.grid.Model', {
extend: 'Ext.data.Model',
fields: this.fields
});
this.store = Ext.create('Ext.data.Store', {
model: 'Ext.grid.Model',
autoLoad: true,
proxy: {
type: 'ajax',
url: this.url,
actionMethods: 'POST',
extraParams: { action: 'select' },
reader: {
type: 'json',
root: 'dados'
}
}
});
},
191
86
coreView.js (3/4)initGrid: function() {
this.tbar = Ext.create('Ext.toolbar.Toolbar', {
items: [
'->', 'Pesquisar por: ', {
id: this.filterId,
xtype: 'textfield',
width: 100,
scope: this
},{
text:'Filtrar',
iconCls: 'filter',
handler: this.filter,
scope: this
}]
});
this.grid = Ext.create('Ext.grid.Panel', {
border: false,
store: this.store,
columns: this.columns
});
192
coreView.js (4/4)this.winGrid = Ext.create('widget.window', {
title: this.title,
items: this.grid,
layout: 'fit',
maximizable: true,
closable: true,
closeAction: 'hide',
width: this.width ? this.width : 500,
height: this.height ? this.height : 300,
minWidth: 300,
minHeight: 200,
tbar: this.tbar
});
},
filter: function() {
this.store.reload({
params: { filter: Ext.getCmp(''+this.filterId+'').getValue() }
})
}
});
193
87
coreController.php<?php
class coreController {
function getString($field) {
return @trim(addslashes($_REQUEST[$field]));
}
}
?>
194
coreModel.php (1/2)<?php
class coreModel {
private $ip = "127.0.0.1";
private $user = "root";
private $pwd = "";
private $db = "db_aula";
function __construct() {
@mysql_connect($this->ip, $this->user, $this->pwd);
@mysql_select_db($this->db);
}
function __destruct() {
@mysql_close();
}
public function query($sql) {
return mysql_query($sql);
}
195
88
coreModel.php (2/2)public function num_rows($rs) {
$r = mysql_num_rows($rs);
return $r;
}
public function fetch_object($rs) {
return mysql_fetch_object($rs);
}
public function select_all($sql) {
$rs = $this->query($sql);
$total = empty($rs) ? 0 : $this->num_rows($rs);
$dados = null;
if(!empty($rs) AND ($total>0)) {
while($r = $this->fetch_object($rs)) {
$dados[] = array_map('utf8_encode',(array) $r);
}
}
return $dados;
}
}
?>
196
Criando o grid para empresas
� Agora que já temos nossas 3 classes bases, iremos efetivamente criar o grid.
� Ficará muito claro a diminuição de código e o aumento de produtividade.
� Todos os demais módulos irão compartilhar das classes bases (CORE).
197
89
empresaView.js (1/3)Ext.define('Ext.grid.empresaView', {
extend: 'Ext.grid.coreView',
url: './empresaController.php',
title: 'Gerenciar Empresas',
filterId: 'filterEmpresa',
fields: [
{name: 'codigo', type: 'int'},
{name: 'empresa', type: 'string'},
{name: 'valor', type: 'float'},
{name: 'variacao', type: 'float'},
{name: 'data', type: 'date', dateFormat: 'Y-m-d'},
{name: 'ativo', type: 'bool'}
],
columns: [{
text: 'Código',
width: 60,
align: 'right',
dataIndex: 'codigo'
},{
text: 'Empresa',
198
empresaView.js (2/3)flex: 1,
dataIndex: 'empresa',
renderer: Ext.util.Format.uppercase
},{
text: 'Valor',
width: 75,
align: 'right',
dataIndex: 'valor',
renderer: function(val) {
return 'R$ ' + Ext.util.Format.number(val);
}
},{
text: 'Variação',
width: 75,
align: 'center',
dataIndex: 'variacao',
renderer: function(val) {
if (val >= 0) {
return '<span style="color:green;">' + val + '%</span>';
} else {
199
90
empresaView.js (3/3)return '<span style="color:red;">' + val + '%</span>';
}
}
},{
text: 'Data',
width: 85,
dataIndex: 'data',
align: 'center',
renderer: Ext.util.Format.dateRenderer('d/m/Y')
},{
text: 'Situação',
width: 60,
dataIndex: 'ativo',
align: 'center',
renderer: function(val){
classe = (val==1) ? 'active' : 'inactive';
return '<div class='+classe+'></div>';
}
}]
});
200
empresaController.php<?php
require_once('coreController.php');
require_once('empresaModel.php');
class empresaController extends coreController {
function __construct() {
@$action = $_REQUEST['action'];
if($action=='select')
$this->select();
}
private function select() {
$filter = $this->getString('filter');
$m = new empresaModel();
$dados = $m->select($filter);
echo json_encode(array('dados' => $dados));
}
}
new empresaController();
?>
201
91
empresaModel.php<?php
require_once('coreModel.php');
class empresaModel extends coreModel {
function __construct() {
parent::__construct();
}
public function select($filter) {
$sql = "SELECT codigo, empresa, valor, variacao, data, ativo
FROM tb_empresas
WHERE empresa LIKE '$filter%'";
return $this->select_all($sql);
}
}
?>
202
Criando o arquivo index.html<!doctype html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="../ext-4.1.1a/resources/css/ext-all.css" />
<script src="../ext-4.1.1a/ext-all.js"></script>
<link rel="stylesheet" href="./css/icones.css" />
</head>
<body>
<script>
Ext.Loader.setConfig({enabled:true});
Ext.Loader.setPath('Ext.grid','.');
Ext.onReady(function(){
var objEmpresa = new Ext.create("Ext.grid.empresaView");
objEmpresa.winGrid.show();
});
</script>
</body>
</html>
203
92
Trabalho: Troca de Mensagens(individual ou em dupla)
� Elaborar um sistema para troca de mensagens on-line entre usuários. Para ter acesso ao sistema, o usuário deverá realizar login. Qualquer usuário poderá se cadastrar. O sistema deve permitir o envio de mensagens sempre direcionadas a um outro usuário. O usuário poderá visualizar tanto suas mensagens enviadas, quando as suas mensagens recebidas.
204
Troca de Mensagens (cont.)
205
93
Troca de Mensagens (cont.)
CREATE DATABASE IF NOT EXISTS db_aula;
USE db_aula;
CREATE TABLE IF NOT EXISTS tb_usuario(
id integer not null primary key auto_increment,
nome varchar(40) not null UNIQUE,
senha varchar(40) not null
);
CREATE TABLE IF NOT EXISTS tb_mensagem(
id integer not null primary key auto_increment,
remetente integer not null,
destinatario integer not null,
mensagem varchar(140),
data_hora datetime,
foreign key(remetente) references tb_usuario(id),
foreign key(destinatario) references tb_usuario(id)
);
206
Trabalho (1/4)
� Elaborar um módulo de controle de acesso, no qual seja necessário informar o nome e a senha para ter acesso ao sistema. Novos usuários também poderão se cadastrar, mas não se deve aceitar nome de usuário repetido.
207
94
Trabalho (2/4)
� Ao entrar no sistema, deve-se exibir 2 abas para mensagens recebidas e enviadas. Na aba “Enviadas”, deve-se exibir todas as mensagens postadas pelo usuário ordenando pelas mensagens mais recentes.
208
Trabalho (3/4)
� O botão “Nova” deve abrir um formulário para envio de uma nova mensagem. O campo “para” do formulário deve ser carregado com um combo com todos os usuários cadastrados, exceto o próprio usuário conectado.
209
95
Trabalho (4/4)
� Na aba “Recebidas”, deve-se listar todas as mensagens recebidas, ordenadas pelas mais recentes. O botão “Atualizar” deve verificar novas mensagens. E a opção “Atualização automática” deverá atualizar a tela a cada 5 minutos.
210
BibliografiaLivro Texto:
1. PHP 4: A Bíblia; Converse, Tim et al; Ed. Campus; 1ª edição; 2001; 5 exemplares.
2. Use a Cabeça: PHP e MySQL; Beighley, Linn; Ed. Alta Books; 1ª edição; 2010; 10 exemplares.
3. Ajax (ASYNCHRONOUS JAVASCRIPT AND XML); Soares, Walace; Ed. Érica; 1ª edição; 2006; 10 exemplares.
Complementar:
4. Profissional PHP: Programando; Castagneto, Jesus et al; Ed. Makron Books; 1ª edição; 2001; 1 exemplar.
5. PHP e MySQL: Desenvolvimento Web; Welling, Luke et al; Ed. Campus; 1ª edição; 2001; 1 exemplar.
6. Programando em PHP: Conceitos e Aplicações; Soares, Walace; Ed. Érica; 1ª edição; 2000; 5 exemplares.
7. Fundamentos de PHP; Meloni, Julie C.; Ed. Ciência Moderna; 1ª edição; 2000; 5 exemplares.
8. Guia de Consulta Rápida: Integrando PHP com MySQL; Stoco, Lucio M.; Ed. Novatec; 1ª edição; 2000; 5 exemplares.
211