DGmike

DGmike

Calma! não entre em pânico! Amanhã (talvez) tem novo post…

  • Alice Andrade
  • Rafael Zamana
  • Home
  • Guia Rápido jQuery
  • Códigos prontos
    • PHP: Função __auloload()
    • Classe sqlsimples e sql – PHP
    • Bancos, bancos e mais bancos…
  • PagSeguro
  • Artigos
    • JavaScript (parte 1)
  • Quem?

PDO e classe de resultados

Posted in icephp, php, sql by DGmike
Oct 22 2009
TrackBack Address.

Estava fazendo alguns testes com PDO e SQLite e descobri uma coisa muito interessante sobre o PDO: classe de resultados. O que isso quer dizer, que quando você faz um fetchObject você pode usar sua própria classe com seus próprios métodos.

Atenção! Este post é totalmente NERD e destinado para programadores com algum conhecimento em PHP e banco de dados. Caso este não seja seu perfil aconselho a desistir enquanto é tempo.

Caixa, guarde o que é seu

O código começou mais ou menos assim, eu queria desenvolver um model específico para o ICEPHP, e com o advento do PDO decidi usá-lo como base. Então precisei de alguns definitions: diretório onde se encontra o arquivo (script) e o separador de pastas que em linux é barra e no windows é contra-barra. Também criei duas tabelas no banco de dados, post e categoria:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
define('DS', DIRECTORY_SEPARATOR);
define('ICE_DIR', dirname(__FILE__));
 
$bd = new PDO('sqlite:'.ICE_DIR.DS.'banco.db');
# A conexão do PDO não é linda?!

$bd->query("
    CREATE TABLE IF NOT EXISTS categoria (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        nome VARCHAR(40),
        slug VARCHAR(40)
    );
");
$bd->query("
    CREATE TABLE IF NOT EXISTS post (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        titulo VARCHAR(40),
        slug VARCHAR(40),
        post TEXT,
        data TIMESTAMP
    );
");

Após isso fiz um select no banco de dados e se não me retornasse resultados, inseri um dado no banco de dados:

1
2
3
4
5
6
7
8
9
10
11
12
$c=$bd->query("SELECT COUNT(*) as c FROM post;");
 
if (!$c->fetchObject()->c) {
    $bd->query("
        INSERT INTO post (titulo, slug, post, data) VALUES (
            'Apenas um teste',
            'apenas-um-teste',
            'Este post é apenas um teste do novo Framework: ICEPHP',
            CURRENT_DATE
        );
    ");
}

Com isso eu consigo usar o resultado de forma linda (orientado a objetos):

1
2
3
4
5
$c=$bd->query("SELECT * FROM post;");
$r = $c->fetchObject();
echo $r->titulo;
 
// Isto retorna "Apenas um teste"

Lendo a documentação sobre o fetchObject do PDO vi que é possivel passar como parâmetro uma string com o nome da Classe que você deseja que seja utilizado para o resultado, lembrando que (!), o padrão é o stdClass. Entao passei minha classe resultado como exemplo e o que descobri. Coisas lindas de se fazer. Eis a classe Resultado:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
class Resultado
{
    var $_data = array();
    var $_updated = false;
 
    function __toString()
    {
        return "O resultado é: ".$this->titulo . ' ('.date('d-m-Y h:i:s', $this->data).")\n";
    }
 
    function __get($k)
    {
        return $this->_data[$k];
    }
 
    function __set($k, $v)
    {
        if (isset($this->_data[$k]) AND $this->_data[$k] != $v) {
            $this->_updated = true;
        }
        $this->_data[$k] = $v;
    }
 
    function salvaPost()
    {
        global $bd;
 
        $sql = "UPDATE post SET ";
        foreach ($this->_data as $k=>$v) {
            if ($k!='id' || $k != 'data') {
              $sql .= "\n  $k = '$v',";
            }
        }
        $sql = substr($sql, 0, -1);
        $sql .= "\n WHERE id = ".$this->id;
 
        $bd->query($sql);
    }
 
    function __destruct()
    {
        if ($this->_updated) {
            $this->salvaPost();
        }
    }
}

Veja, apenas usei um método de verdade, todos os outros usei os métodos mágicos do PHP (__toString, __get, __set, __destruct). Recomendo que leia sobre estes métodos e use-os, eles podem salvar sua vida. Whatever, com essa classe Resultado é possivel fazer o que eu sempre quis fazer, um objeto de resultado de banco de dados que atualiza o banco sem usar o estilo seta parametros e depois salva. Veja como é feito na maioria dos ORMs por aí:

1
2
3
$r=$post->get(1);
$r->titulo = 'Titulo Alterado';
$r->save();

Pense comigo, se você atribuiu um valor, você quer que ele seja salvo, correto? Então não ficaria mais fácil se forsse assim?

1
2
$r=$post->get(1);
$r->titulo = 'Titulo Alterado';

Sim!!! Às vezes você atribui um valor que não deseja salvar, faz isso apenas para configurar os dados e etc, mas pense, quantas vezes você faz isso? Além disso, óbvio que é possivel fazer tudo o que deseja gastando um pouco mais de massa cinzenta, mas a proposta não é essa no momento.

Usando a classe Resultado é possivel fazer o update quase que “on the fly”. Na verdade, para o programador parece que é instantâneo, mas não é. O update se dá no destruct do objeto, normalmente quando o script finaliza, mas pode ser quando damos um novo fetchObject nessa variável. Se ele não for alterado ele, obviamente, não salva as alterações no banco de dados. Veja como fica o exemplo do que estou falando.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$c=$bd->query("SELECT * FROM post;");
# Pegando o objeto e jogando-o na classe de resultados
$r = $c->fetchObject('Resultado');
 
# Imprimindo, devido ao método __toString aparece:
# O resultado é: Apenas um teste (31-12-1969 09:33:29)
print ($r);
 
# Alterando o resultado
$r->titulo = 'Teste';
 
# Imprimindo mais uma vez, aparece
# O resultado é: Teste (31-12-1969 09:33:29)
# mas isto está em 'cache'
print ($r);
 
# Quando o objeto é destruído, ao finalizar o script
# ele faz o update necessário

Testei isso no foreach e também funcionou, então é fazer updates de objetos em escala, mas não exagere, o ideal é fazer isso no sql. Veja como fica com o foreach:

1
2
3
4
5
$c=$bd->query("SELECT * FROM post;");
 
while ($x = $c->fetchObject('Resultado')) {
    $x->data = time();
}

Isso me deixa com várias ideias para criar o ORM do ICEPHP. Mas fica a dica para vocês desenvolverem seus códigos, experimente criar um método FORM que já cria um formulário html para você facilitar sua vida. :D

1 Comment »
Tagged as: banco de dados, classe, framework, icephp, pdo, php, sqlite

Cálculo de Frete em Ajax

Posted in javascript by DGmike
Sep 12 2008
TrackBack Address.

O ruhanbidart publicou no viva o linux um script em javascript[bb] que resolve muitos problemas, principalente para lojas virtuais. Esse script faz uma requisição no site dos correios e usa a função callback, que você pode reescrevê-la como desejar, manipulando o resultado como melhor lhe convir.

Então você pode criar sua função callback:

function trataFrete(frete) {
alert('O valor total é R$' + frete.preco_postal);
}

E rodar a função do script:

Correios.calcular(trataFrete, null, '33000-000', '33000-001', 5);

Onde, os parâmetros são:

  1. A referência (sem aspas) à função de callback
  2. Código do tipo de entrega que será calculada. Daí, temos:
    • 40010 (SEDEX) (Padrão)
    • 40290 (SEDEX Hoje)
    • 40215 (SEDEX 10)
    • 40045 (SEDEX a Cobrar)
    • 81019 (e-SEDEX)
    • 44105 (MALOTE)
  3. Cep de origem no formato NNNNN-NNN
  4. Cep de destino no formato NNNNN-NNN
  5. Peso da encomeda

Essa é a configuração básica, você ainda pode escolher entre mão própria, valor declarado e optar em adicionar o serviço de aviso de recebimento. O retorno para o callback é um belo json[bb] neste formato:

{
'servico': 40010,
'servico_nome': SEDEX,
'uf_origem': 'MG',
'local_origem': 'Capital',
'cep_origem': '33030645',
'uf_destino': 'RJ',
'local_destino': 'Interior',
'cep_destino': '25770970',
'peso': 10,
'mao_propria': 0,
'aviso_recebimento': 0,
'valor_declarado': 0,
'tarifa_valor_declarado': 0,
'preco_postal': 73.7
}

O código da biblioteca pode ser encontrado no próprio site do viva o linux.

5 Comments »
Tagged as: ajax, cálculo, classe, correios, frete, função, json, sedex

Classe de tabelas em PHP – Parte 2

Posted in Programação, php, tableless, xHTML by DGmike
Apr 19 2008
TrackBack Address.

Um tempo atrás comecei a fazer um tutorial sobre criar tabelas com o auxilio de uma classe em php[bb] que gera uma tabela semantica[bb] (o que é dificil) e de forma simples. Antes de continuarmos a classe propriamente dita, irei explicar um pouco sobre expressões regulares[bb].

As expressões regulares auxiliam muito na hora de fazer uma busca sobre qualquer coisa em um bloco de texto, como por exemplo os links de um bloco html[bb] ou os emails contidos em uma conversa ou mesmo o ip contido em uma frase. Tudo o que é necessário é saber o padrão necessário do que você procura.

Vamos pegar um exemplo bem básico, um bloco de texto e vamos pegar alguns dados contidos nele.

IP é um acrónimo para a expressão inglesa “Internet Protocol” (ou Protocolo de Internet[bb]), que é um protocolo usado entre duas ou mais máquinas em rede para encaminhamento dos dados.

Os dados numa rede IP são enviados em blocos referidos como pacotes ou datagramas (os termos são basicamente sinónimos no IP, sendo usados para os dados em diferentes locais nas camadas IP). Em particular, no IP nenhuma definição é necessária antes do host tentar enviar pacotes para um host com o qual não comunicou previamente.

Estes são exemplos de IPs: 189.78.131.168 , 189.78.131.168 , 10.27.12.11 , 192.168.0.1 , 127.0.0.1

Retirado da Wikipedia

Percebam que existe um padrão na numeração dos IPs: Quatro sequências de até três números separados por pontos. Nas expressões regulares, podemos fazer buscas por digitos usando a expressão \d que significa digito, então para produrarmos um digito usamos \d. Também podemos definir uma quantidades de vezes que esse caracter pode aparecer, no caso, pode aparecer de uma a três vezes. Logo, nossa busca fica assim: \d{1,3}

O ponto também é uma expressão regular, que indica qualquer coisa. Sim! Qualquer coisa, ele procura por uma letra, número, espaço, pontuação, <CR> (Carriage Return, ou tecla enter), então para “desconvertermos” essa expressão regular, usamos uma barra invertida antes. Logo nossa busca por IP é: \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3} ou simplesmente (\d{1,3}\.){3}\d{1,3} que indica uma busca de três sequencias de \d{1,3}\. e uma de \d{1,3}

Expressão Regular em busca de IPs de um texto

Como vocês podem constatar na imagem, a expressão regular funcionou perfeitamente. Eu uso essa extensão do Firefox (Regular Expressions Tester) para de auxiliar no dia-a-dia, já que uso expressões regulares muitas vezes por dia.

Outra coisa interessante em expressões regulares é que podemos definir uma lista de palavras ou expressões que queremos que apareça em nossa sequência. Fazemos isso através de parênteses e “pipes[bb]” (ou barrinha em pé). Eis um exemplo prático, queremos procurar a palavra menino e menina. Basta fazermos a seguinte sentença menin(o|a)

[Nota] A busca anterior também poderia ser dada por menin[oa] uma diferença básica entre parânteses e colchetes é que em parênteses podemos fazer uma busca por outras expressões ou palavras, já que nos colchetes apenas por caracteres específicos. Logo, cas(a|inha|arão) irá procurar pelas três palavras, o que não é possivel fazer com os colchetes.

Vamos pensar em entradas de usuário, ou seja, frases ou listas simples (lembre-se que o nosso objetivo é a classe de criação de tabelas, logo as entradas são pequenas). Então, queremos procurar uma determinada expressão no inicio da entrada do usuário[bb]. Algo como dois pontos e uma palavra e depois dois pontos.

Explico: Digamos que queremos que o usuário entre com os seguintes dados, sequencialmente:

  • Nome
  • Sobrenome
  • :centro: Idade
  • :tel: Telefone
  • :tel: Celular
  • CPF
  • Filiação (Pai)
  • Filiação (Mãe)

Perceba que o usuário quer colocar um atributo na entrada que alinhe ou ajuste as celulas para uma determinada classe. Podemos resolver este problema usando a mágica do circunflexo (^). Quando colocado no inicio da expressão regular, ele indica o inicio da entrada. Então, nossa expressão regular irá iniciar com ^:

Assim como os digitos (\d) também existe o \w que indica um caractere alfa numérico, ou seja letras de A a Z (maiusculas e minusculas) e números de zero a nove. E também podemos definir que deve existir um ou mais desta expressão regular na oração. (Lembram do {n,m} onde n e m são os numeros limites de caracteres?) Com o mais, podemos definir que deve existir um ou mais elementos da expressão regular anterior. Assim, nossa expressão regular fica assim: ^:\w+: Com isto, pegamos o que queremos, se não existir, ele não pegará nada.

Bom, a nossa expressão regular está quase no fim. Como você é esperto, vou deixar a expressao regular final e deixarei que você pense como ela foi criada com base no que foi dito anteriormente:

^(:((\.|#)\w+|(r|c)\d+))+:

Com esta expressão regular, podemos esperar que o usuário entre com as seguintes condições e mais suas subcondições possiveis:

  • :.classe:
  • :#id:
  • :c12:
  • :r1:
  • :.classe:#id:
  • :.classe:r12:
  • :#id:c21:
  • :.qualquerClasse:#qualquerId:c21:r18

Tendo isto em mente, podemos tratar a entrada do usuário, permitindo saber que classe e/ou id ele vai querer colocar na determinada célula, e qual o numero de colspan e rowspan ele vai querer. Onde colspan é junção de colunas e rowspan é junção de linhas, como você pode ver aqui, aqui e aqui.

Digo e repito, estude expressões regulares, vale a pena! Como você pode ver para fazermos um monte de validações em nossa entrada usamos apenas 26 caracteres. Faremos o tratamento dos mesmos na próxima edição, mas adianto que usaremos as funções preg_match e preg_replace.

No Comments yet »
Tagged as: acrónimo, bloco de texto, busca, célula, classe, colspan, digito, entrada, expressões regulares, html, id, Internet Protocol, ip, links, padrão, php, Protocolo de Internet, rede, Regular Expressions, rowspan, Semântica, simples, tabelas, Tutorial, usuário, wikipedia

Categorias

  • Amigos  (16)
  • cases  (4)
  • Cotidiano  (71)
  • CSS  (19)
  • Design  (1)
  • Dia-a-dia  (30)
  • Diversão  (18)
  • eventos  (10)
  • extensions  (11)
  • flash  (3)
  • Games  (1)
  • html  (5)
  • icephp  (4)
  • Ilustração  (6)
  • Imagem  (8)
  • Inspiração  (5)
  • javascript  (35)
    • jQuery  (7)
    • yui  (2)
  • Não categorizado  (26)
  • Navegadores  (17)
    • Chrome  (4)
    • Firefox  (16)
    • Internet Explorer  (5)
  • pagseguro  (10)
  • php  (42)
    • PHP Conference  (3)
  • plugin  (3)
  • Programação  (43)
  • python  (5)
  • Semântica  (16)
  • sql  (9)
  • tableless  (18)
  • Tecnologia  (47)
  • Trabalho  (27)
  • Tutorial  (24)
  • Vetorial  (5)
  • video  (7)
  • video-tutorial  (5)
  • Windows  (4)
  • wordpress  (2)
  • xHTML  (23)

Tags

ajax artigo banco de dados biblioteca blog browser classe CSS data Design Dia-a-dia dinheiro evento eventos Firefox framework google html icephp internet Internet Explorer javascript jQuery loja mysql online opera pagseguro palestra php plugin Programação python retorno automático simples site solução sql string tableless Tecnologia twitter visie web wordpress

Arquivo

SlideSare

Últimos Posts

  • [QuickPOST] Vagas de emprego
  • Dados de teste
  • Aprendendo com o técnico: quanto cobrar em um projeto web
  • Frete com PagSeguro: simples!
  • Palestra PagSeguro na Impacta

Amigos

  • Alice Andrade
  • Rafael Zamana
Powered by WordPress | “Blend” from Spectacu.la WP Themes Club