Introdução ao ACL do CakePHP

E ae blz?

Novamente, como sempre, igual todas vezes anteriores, mais um post meu saiu de uma conversa que tive no gtalk/msn com alguém, dessa vez foi uma sugestão do João que escreve aqui no technócil comigo, falar sobre o Access Control Lists do CakePHP.

Então vamo lá,

Eu comecei esse post planejando falar sobre ACL num post só, mas vi que seria impossível por que o post ia ficar imenso e no final dele você já teria esquecido o começo então resolvi separar o post em partes.

–Introdução ao ACL do CakePHP
–ACL na prática, controla os acesso tudo amigo!… (hehe o final é título provisório, to criativo hoje)

O objetivo deste post é só introduzir huhuhu! os programadores aos conceitos do ACL, até por que postar tudo deixaria o post grande pra c@#%&*#, etc, etc… que são na verdade o mais complicado de se entender, depois que os conceitos já estão, digamos, entendidos, a implementação é bem mais rápida…

O Access Control Lists, O mano ACL para os íntimos, é um componente que faz parte do core do framework CakePHP, e tem por finalidade oferecer uma forma poderosa de controle e níveis de acesso a determinadas áreas das aplicações.

Uma coisa muito importante que confunde muito quem está estudando o ACL pela primeira vez é, o ACL não faz autenticação ele só facilita a gerência dos níveis, usuários e áreas de acesso.

Resumindo, o que ele faz é dizer quem pode acessar o que, e só.

O ACL usa dois tipos de definições como convenção para facilitar o controle de acesso, são elas:

ACO = Access Control Object, algo que é acessado.

ARO = Access Request Object, quem ou o que acessa algo.

Fazendo uma analogia ao modelo que é geralmente usado pela grande maioria dos programadores, um exemplo de como seriam identificados os controles e níveis de acesso do blog usando ACL, você teria o seguinte cenário.

AROs – Tipos/Grupos de usuários, usuários
Tipos de Usuários:
–Admin
–Editors
–Guest

Usuários:
–Tobias
–João Vagner
–Editor
–Visitante

ACOs – Áreas protegidas
–Posts
–Páginas
–Links
–Plug-ins
–Ferramentas
–Usuários
–Configurações

O ACL tem uma estrutura do tipo árvore e que pode aceitar heranças de permissões de acesso.

Seguindo o exemplo acima poderia ter uma árvore de permissões da seguinte maneira.

Admins (permissões de acesso: todas as áreas)
--João Vagner (herda todas as permissões do grupo)
--Tobias (herda todas as permissões do grupo)

Editors ( permissões de acesso: ( posts (read,add,edit) )
--editor (herda permissões do grupo, usuários (edit:id = editor.id))

Guest (posts,pages,links(read))
--visitante(herda permissões)

WTF? É o que você que nunca mexeu com ACL deve estar no momento né? Relaxa vou explicar o que eu quis dizer com o texto em negrito acima.

Do ponto de vista do ACL tanto os grupos de usuário, quanto os usuários são coisas do mesmo tipo, são coisas que acessam coisas, e graças a metodologia de árvore essas coisas podem herdar permissões de acesso.

No caso do primeiro grupo, Admins, não há nada de especial ou misterioso, o grupo admin tem acesso a tudo e todos os usuários pertencentes a esse grupo herda suas permissões, moleza se você precisa de um controle de acesso simples assim você nem precisa de ACL.

Vamos ao segundo exemplo, esse sim tem algo de interessante e pra alguns pode ter sido meio confuso.

Editors ( permissões de acesso: ( posts (read,add,edit) )
Traduzindo: O grupo Editors tem acesso ao controle posts e tem permissões para efetuar read, add, edit.

O que são essas permissões de read, add, edit? São permissões que você define de acordo com a sua necessidade, eu usei essas por que são as mais básicas, quase um default para exemplos.

Continuando…
--editor (herda permissões do grupo, usuários (edit:id = editor.id))
Traduzindo: O usuário (ARO) editor herda as permissões do grupo editors e tem a permissão específica de edit a determinada id do controllers usuários, o que significa que ele pode editar as próprias informações de usuário, mas não pode editar os dados de outros usuários.

Guest (posts,pages,links(read))
--visitante(herda permissões)

E para todos os visitantes a permissão de ler posts, pages e links.

Como o objetivo desse post é fazer os conceitos serem entendidos não vou postar códigos eles ficam pro próximo post, bom feriado pra todos, e novamente, como sempre, igual a todas as vezes, dúvidas, sugestões e puxões de orelha os comentários tão ai pra isso.

flw ae :)

Conheça a função __autoload e esqueça que um dia precisou usar listas gigantes de includes

E ae gente, blz?

Bom o post de hoje é pequeno e rápido e com certeza incrívelmente útil, vou mostrar hoje uma técnica que estou usando pra facilitar minha vida na hora de desenvolver meus códigos, o assunto de hoje é o __autoload, uma funçãozinha que está me economizando preciosos minutos no desenvolvimento.

O funcionamento dele é básico, e funciona assim:

Quando você tenta instanciar uma classe o php verifica se essa classe já existe, se não existir ele tenta carregar ela de acordo com a função __autoload que estiver no script.

ex:

1
2
3
function __autoload($class_name) {
	require_once $class_name.'.php';
}

digamos que em algum momento do meu código eu tentei instanciar a classe Groups

1
$groups = new Groups;

se a classe Groups não existir até o momento o php vai tentar incluir o arquivo Groups.php (de acordo com a minha função __autoload) antes de disparar um erro. Ta mas ele sempre vai procurar só pelo nome da classe? depende… tudo depende de como você faz a sua função __autoload, veja o exemplo abaixo para entender.

1
2
3
function __autoload($class_name) {
	require_once 'my/path/to/classes/'.$class_name.'.php';
}

nesse exemplo acima o php vai procurar pela classe na path determinada na função antes de disparar o erro.

Bom é isso, só pra terminar vou dar uma dica que eu estou usando aqui, que é simplesmente adicionar as paths de onde as classes estão ao include_path.

1
2
3
4
5
6
7
8
9
<?php
 
set_include_path(get_include_path() . PATH_SEPARATOR . './libs/');
 
function __autoload($class_name) {
	require_once $class_name.'.php';
}
 
?>

Vou explicar o código:

3
set_include_path(get_include_path() . PATH_SEPARATOR . './libs/');

Adiciona ao include_path do php a pasta ./libs/

5
6
7
function __autoload($class_name) {
	require_once $class_name.'.php';
}

Define a função __autoload que irá procurar pelas classes quando forem instanciadas.

Ufa… cabou, é isso ai gente, como sempre dúvidas, sugestões e puxões de orelha nos comentários por favor :D.

abraço e até a próxima,
ps. esse foi o post mais rápido que eu já postei, da idéia de postar até o fim da revisão do texto demorou 26 min oO.

Dica Rapida: Pegando Twittadas com PHP

Ola a todos,

Vou começar uma série de posts rapidos com dicas legais e uteis pro dia-a-dia relacionadadas a PHP.

Quase todos usam Twitter, e ja sabemos o o Twitter tem uma API para integração, porem nao e necessario usar uma API para algo basico, como pegar os Ultimos posts de alguem via RSS. Ja que RSS e um formato XML.

Abaixo um codigo simples e rapido:

1
2
3
4
5
6
7
8
9
10
11
12
<?php
$rss = 'http://twitter.com/statuses/user_timeline/14627317.rss'; 
$abre = simplexml_load_file($rss);
$i = 0 ; 
$limite=3;
foreach ($abre->channel->item as $itens ) {
$post = utf8_decode($itens->title);
echo $post .'<hr />';
if($i==$limite) { break; }
$i++;
 }
?>

$rss
Indica o caminho completo do RSS a ser lido.

$abre
Utiliza simplexml_load_file para ler o xml e converter em um objeto/p

$i
Define o inicio do loop para que possamos frear o loop no nosso limite de twittadas./p

$limite=3
Definimos um limite de posts, no caso como nosso loop comeca em em 0, definindo 3, o limite de posts seria 4: 0,1,2,3

foreach ($abre–>channel->item as $itens ) {
Aqui criamos um loop do item do XML e o chamamos de $itens para melhor identificação dentro do loop.  Aqui ele herda os itens de channel->item, como title, e outros

$post = utf8_decode($itens->title);
Aqui usamos o UTF-8 para decodificar as mensagens evitando erros de charset e podemos interpretar para o ISO.

echo $post .’ < hr / >‘;
Aqui imprimos o Post na tela e adicionamos a tag


para separar os posts, criando uma linha de separação.

if($i==$limite) { break; }
Aqui verificamos se o nosso loop chegou ao nosso limite definido acima, se chegar coloca um fim no loop do channel->item

Por fim e isso, basta usar em seus blogs, e onde mais desejar ;)

OOP no PHP: Overloading, utilizando os métodos mágicos do PHP

E aeeeeew blz? Bom gente voltando do período de preguiça bagarai, vício em jogos online e outras vagabundagens ociosidade vamos dar continuidade a série de artigos sobre OOP no PHP. O assunto de hoje é bem interessante, no post de hoje vamos ver como usar um dos métodos mágicos do php.

Neste artigo vou falar do método mágico __call(),  que funciona da seguinte maneira:

Quando uma classe tem o método __call() o php roda esse método sempre que qualquer método da classe for chamado, mesmo se o método que foi chamado não existir um método inexistente ou inacessível for chamado (obrigado Edgar pelo puxão de orelha), isso abre espaço para algumas coisas interessantes.

Vamos a um exemplo do funcionamento de __call():

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php
class ExemploCall {  
  function __call($m, $a)
  {
    print "Método chamado: $m\n";
    print "Parametros: \n";
    var_dump($a);
    return $this->x;
  }
}
$call = new ExemploCall();
$call->test(1,2,'teste');
 
//Mostra na tela
/*
Método chamado: test 
Parametros: 
array(3) { 
  [0]=>  int(1) 
  [1]=>  int(2) 
  [2]=>  string(5) "teste" 
} 
*/
?>

O exemplo acima simplesmente exibe na tela o método chamado e os parametros enviados, mas vendo isso a pergunta que surge na cabeça é, pra que ou onde eu vou usar o método __call()?

A resposta pra essa pergunta vai da sua criatividade mas eu vou postar aqui uma forma de uso que o cakephp usava há algum tempo atrás.

Funcionava da seguinte forma, havia um método padrão chamado find que era chamado e fazia consultas ao banco de acordo com os parametros passados, porém, (aqui que vem a mágica) ele também podia ser chamado como findByNomeDoCampo o que em alguns momentos facilitava bastante a vida do programador, vamos fazer algo parecido com isso.

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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
<?php
 
/**
  Só vou postar o código relevante aos métodos mágicos, mas supõe-se que
  deste ponto em diante você já tem incluido no arquivo toda a rotina de 
  conexão com o banco de dados, etc, etc, etc...  
**/
 
class Model {
 
  public function __construct() 
  { //O conteúdo deste método vai variar de acordo com sua classe
  }
 
  public function __call($method, $params)
  {
    // Verifica se o método chamado existe nessa classe
    if ( method_exists($this,$method) )
    {
      //Caso exista chama o método
      return call_user_method($method, $this, $params);
    } 
    else 
    {
      //Caso não exista, chama um método especial que fará a nossa mágica
      $this->parseMethods($method,$params);
    }
  }
 
  private function parseMethods($method,$params)
  {
    //Verifica se o método segue o padrão adotado
    if ( eregi('findBy',$method) === false ) 
    {      
      //Caso não siga dispara um erro dizendo que o método é inválido/não encontrado
      trigger_error('Método inválido ou inexistente',E_USER_ERROR); 
      die;
    }
    else
    {
      //Caso seja um método padronizado (findByAlgo) recupera o nome do campo e converte tudo para minúsculo
      $fieldName = strtolower(str_ireplace('findBy','',$method));      
 
      //Formata os parametros para serem passados ao método find padrão
      $options = $params['1'];
      $options['conditions'] = array($fieldName=>$params['0']);
 
      //Chama o método find original
      $this->find($options);            
    }
  }
 
 
  public function find($options) 
  {    
    var_dump($options);
    //Aqui você faria a consulta usando as informações recebidas
  }
 
}
 
//Instancia a classe
$model = new Model();
 
//Define parametros a serem passados
$options = array (
   'fields' => array ('*')
  ,'order'  => array ('nome ASC')
);
 
//Chama o método mágico
// Onde o primeiro parametro é o valor que o campo passado no nome do método deve ter.
$model->findByBlog('Technócio',$options);
 
/**
O que chega no método options é:
array(3) { 
    ["fields"] =>  array(1) { 
        [0]=>  string(1) "*" 
    } 
    ["order"] =>  array(1) { 
        [0]=>  string(8) "nome ASC" 
    } 
    ["conditions"] =>  array(1) { 
        ["blog"]=>  string(9) "Technócio" 
    } 
} 
**/
?>

O código ta bem comentado e bem simples também, embora não tenha me aprofundado muito no assunto acho que deu pra ter uma noção dessa possibilidade e do que pode ser feito com isso.

Como sempre, para dúvidas, sugestões e puxões de orelha, utilizem os comentários. Até a próxima (que dessa vez não vai ser tão demorada assim).

I Encontro | PHPSP

É com muito prazer que a IW² e a coordenação do grupo PHPSP anunciam o primeiro encontro do PHP-SP. O intuito do encontro é ser simples, objetivo e funcional: para que o networking e a troca de conhecimento possa ser ainda mais efetivos e positivos.

Esse primeiro encontro do grupo tem o objetivo e foco totalmente voltado para a tecnologia Zend Framework, decidido através de votação com direito a duas palestras totalmente direcionadas ao assunto.

Uma “pequena” surpresa: Reunimos (por enquanto) 4 ZCEs, simulado da php|architect para o exame de certificação. O simulado é bem próximo do exame de certificação real da Zend, e onde os ZCEs farão o simulado inteiro ao vivo: comentando questão por questão, citando as pegadinhas e os conhecimentos necessários para passar na certificação.

Quer tirar sua certificação Zend ? Essa palestra é para você!
Quer aprofundar seus conhecimentos sobre PHP ? É para você também!

Nosso número para participação do evento é bem limitado e só poderão entrar as pessoas que confirmaram a presença! Mas lembre-se, não esqueça de levar 1kg de alimento não perecível para ajudarmos instituições de caridades escolhidas por votação em nossa lista.

Programação

  • 10:00h ~ 13:45h – Simulado da Certificação Zend
  • 13:45h ~ 15:00h – Almoço
  • 15:15h ~ 17:00h – Palestra Zend Framework

Local:

Burti Mooca ( Rua Dias Leme 130 – Moóca – São Paulo )

Valor:

1Kg de alimento não-perecível (ainda estamos definindo uma instituição a ser ajudada; se você quiser dar uma segestão, mande um comentário).

Ao vivo!

Você vai poder acompanhar a transmissão ao vivo do evento ou ler posteriormente o resumo das palestras e fazer download dos arquivos aqui no 15seg.com

Preparativos

Conseguimos algumas fotos dos preparativos…

Material para o encontro Material para o encontro
Material para o encontro Material para o encontro
Material para o encontro Material para o encontro
Material para o encontro Material para o encontro

Leitura de XML – Parte 2 SimpleXML

Olá Pessoal,

Primeiramente, post de dia 24 de Dezembro, desejos a todos um Feliz Natal, que estejam todos ai junto a amigos e familiares curtindo uma data especial.

Bom, demorei um pouco, mas chegou, a segunta parte de Leitura de XML usando SimpleXML, dessa vez vou usar alguns modelos, ao invez de trabalhar com o nosso Feed de RSS, vamos trabalhar com valores de cambio e pesquisa de CEP. Tudo simples e em poucas linhas.

Primeiramente precisamos de algum XML que seja atualizado, com os valores que temos que trabalhar. Para isso existe esse endereço: http://www.republicavirtual.com.br/cotacao/exemplos.php

Não posso garantir 100% de uptime do link, pois não sei se algo vai mudar ok? Mas iremos trabalhar em cima dos retornos desse xml, ok?

Simple XML

O objetivo é fornecer acesso aos documentos XML usando propriedades de objetos e iterators, não é uma extensão complicada (são poucos métodos) mas é bastante flexível.

Exemplo Básico

Importando o XML da URL:

1
$file = simplexml_load_file('http://cotacao.republicavirtual.com.br/web_cotacao.php?formato=xml');

Iniciando o trabalho

Aqui vamos pegar o valor do dolar comercial para compras:

1
2
3
4
// importando o arquivo
$file = simplexml_load_file('http://cotacao.republicavirtual.com.br/web_cotacao.php?formato=xml');
// pegando a tag dolar_commercial_compra
echo $file->dolar_comercial_compra;

As tags que podemos trabalhar podem ser encontrada nesse XML

1
2
3
4
5
6
7
8
9
10
<webservicecotacao>
	<dolar_comercial_compra>2,1260</dolar_comercial_compra>
	<dolar_comercial_venda>2,1280</dolar_comercial_venda>
	<dolar_paralelo_compra>2,2200</dolar_paralelo_compra>
	<dolar_paralelo_venda>2,3000</dolar_paralelo_venda>
	<euro_dolar_compra>1,2410</euro_dolar_compra>
	<euro_dolar_venda>1,2410</euro_dolar_venda>
	<euro_real_compra>2,6384</euro_real_compra>
	<euro_real_venda>2,6408</euro_real_venda>
</webservicecotacao>

Viram como é simples trabalhar com o SimpleXML? Agora vamos trabalhar para achar endereços de CEP ;) O XML que iremos trabalhar emcima é desse modelo:

Trabalhando com CEP

Código:

1
2
3
4
5
6
7
8
9
10
<?xml version="1.0" encoding="iso-8859-1" ?>
<webservicecep>
<resultado>1</resultado>
<resultado_txt>sucesso - cep completo</resultado_txt>
<uf>SP</uf>
<cidade>São Paulo</cidade>
<bairro>Santana</bairro>
<tipo_logradouro>Rua</tipo_logradouro>
<logradouro>Duarte de Azevedo</logradouro>
</webservicecep>

A URL que iremos importar as consultas é: http://cep.republicavirtual.com.br/web_cep.php?cep=02036021&formato=xml

Vamos ao Código:

1
2
3
4
5
6
7
$file = simplexml_load_file('http://cep.republicavirtual.com.br/web_cep.php?cep=02036021&formato=xml');
 
echo "UF: " .$file->uf;
echo "<br />Cidade: " .$file->cidade;
echo "<br />Bairro: " .$file->bairro;
echo "<br />Tipo de Logradouro: " .$file->tipo_logradouro;
echo "<br />Endereço: " .$file->logradouro;

Não recomendo que essa aplicação rode atravez da url de pesquisa, a base de dados pode ser baixada nesse endereço: Download

É isso, viram como é simples integrar uma pesquisa de CEP pra completar formulários de cadastros e tudo mais? Agora é com vocês ;)

OOP no PHP: Heranças e Interfaces, extendendo e implementando classes

E ae blz?

Bom gente depois de um alguns dias atrasado devido a problemas pessoais aqui vai o segundo post da série OOP no PHP, nossos assuntos agora são Heranças e Interfaces, e aproveitando o assunto eu preparei uma classe de acesso ao banco de dados que ilustra perfeitamente o nosso assunto de hoje e também usa as definições do post anterior.

Vamos começar com a teoria:

extends – Essa palavra chave indica que uma classe extende outra classe, ou seja, herda todos os métodos e atributos da classe pai.

Exemplos simples:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
 
class Pai {
	public function pai() {
		echo “Função da classe pai”;
	}
}
 
class Filha extends Pai {
	private function $filha;
 
	public function chamaPai(){
		$this->pai();
	}
 
	public function responde() {
		echo 'Sou uma classe filha';
	}
}
 
?>

No exemplo acima estão disponívels na classe filha todos os métodos/atributos públicos e protegidos (quando existerem) da classe pai.

implements – Essa aqui é um pouco diferente, ela define que uma determinada classe implemente uma interface, que nada mais é uma que uma definição de nomes e parametros de cada método da classe, porém, a real utilidade das interfaces é mais conceitual no mundo OOP e na maioria das vezes é deixada de lado.

vamos a um exemplo:

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
<?php
 
interface iFilha {
	public function chamaPai();
	public function responde();
}
 
class Pai {
	public function pai() {
		echo “Função da classe pai”;
	}
}
 
class Filha extends Pai implements iFilha {
	private function $filha;
 
	public function chamaPai(){
		$this->pai();
	}
 
	public function responde() {
		echo 'Sou uma classe filha';
	}
}
 
?>

Algumas considerações interessantes sobre interfaces:

  • Somente métodos públicos aparecem nas interfaces;
  • Uma classe pode implementar mais de uma interface;
  • Uma classe não pode implementar duas interfaces com métodos de nomes iguais;
  • Interfaces podem ser herdadas assim como classes, basta usar extends.

Bom acho que deu pra entender como funcionam essas coisas, então vamos pra um exemplo de uso nessa classe de acesso ao banco que eu fiz pra ajudar o nosso entendimento.

config.php

1
2
3
4
5
6
7
8
9
10
11
<?php
 
class Config {
	const DB_HOST 	= 'localhost';
	const DB_USER 	= 'root';
	const DB_PASS 	= 'root';
	const DB_SCHEMA = 'technocil';
	const DB_ENCODING = 'UTF8';
}
 
?>

dbo_mysql.php

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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
<?php
 
require 'config.php';
 
interface iDBOMysql {
 
	public function __construct();
 
	public function connect();
 
	public function insert($table,$fields);
 
	public function update($table,$fields);
 
	public function delete($table,$conditions);
 
	public function select($table,$fields='*',$conditions=null,$order=null,$limit=null);
 
}
 
class DBOMysql extends Config implements iDBOMysql {
 
	private $connection;
	private $result;
 
	/**
	 * Construtor chama os métodos necessários quando a classe é instanciada
	 */
	public function __construct() {
		$this->connect();
	}
 
	/**
	 * Conecta com o banco de dados utilizando os dados das constantes de configuração
	 */
	public function connect() {
		$this->connection = mysql_connect(parent::DB_HOST,parent::DB_USER,parent::DB_PASS) or die (mysql_error());
		if (mysql_select_db(parent::DB_SCHEMA, $this->connection)) {
			$this->setEnconding();
		}
	}
 
	private function setEnconding() {
		$this->query('SET NAMES '' . parent::DB_ENCODING.''');		
	}
 
	private function query($sql) {
		return mysql_query($sql,$this->connection);
	}
 
	/**
	 * Executa uma query de inserção no banco de dados
	 *
	 * @param string $table nome da tabela
	 * @param array $fields array com os campos e valores a serem inseridos
	 */
	public function insert($table,$fields) {
 
		$columns = $values = array();		
		foreach ($fields as $column => $value) {
			$columns[] = mysql_real_escape_string($column);
			$values[] = mysql_real_escape_string($value);
		}
 
		$sql  = 'INSERT INTO '.mysql_real_escape_string($table).' ';
		$sql .= '('.join(',',$columns).') ';
		$sql .= 'VALUES (''.join("','",$values).'')';
 
		return $this->query($sql);
 
	}
 
	/**
	 * Executa uma query de atualização no banco de dados
	 *
	 * @param string $table nome da tabela
	 * @param array $fields array com os campos e valores a serem inseridos
	 */
	public function update($table,$fields,$conditions=null) {
 
		$columns = $values = array();		
		foreach ($fields as $column => $value) {
			$itens[] = mysql_real_escape_string($column).'=''.mysql_real_escape_string($value).''';
		}
 
		$sql  = 'UPDATE '.mysql_real_escape_string($table).' ';
		$sql .= 'SET '.join(',',$itens).' ';
 
		if ($conditions != null)
			$sql .= 'WHERE '.mysql_real_escape_string($conditions);
 
		return $this->query($sql);	
 
	}
 
	/**
	 * Executa uma query para excluir registros do banco
	 *
	 * @param string $table nome da table
	 * @param string $conditions condições de exclusão (opcional)
	 */
	public function delete($table,$conditions) {
 
		$sql  = 'DELETE FROM '.mysql_real_escape_string($table).' ';
		if ($conditions != null)
			$sql .= 'WHERE '.mysql_real_escape_string($conditions);
 
		return $this->query($sql);
 
	}
 
	/**
	 * Executa uma query para selecionar registros no banco de dados
	 *
	 * @param string $table 
	 * @param array $fields 
	 * @param string $conditions 
	 * @param string $order
	 * @param string $limit
	 */
	public function select($table,$fields='*',$conditions=null,$order=null,$limit=null) {
 
		$sql  = 'SELECT ';
		$sql .= (is_array($fields)) ? join(',',$fields) : $fields;
		$sql .= ' FROM '.mysql_real_escape_string($table).' ';
 
		if ($conditions != null)
			$sql .= 'WHERE '.mysql_real_escape_string($conditions);
 
		if ($order != null)
			$sql .= 'ORDER BY '.mysql_real_escape_string($order);
 
		if ($limit != null)
			$sql .= mysql_real_escape_string($limit);
 
		$results = $this->query($sql);
 
		$fetch = array();
		while ( $loop = mysql_fetch_assoc($results) ) {
			$fetch[] = $loop;
		}
 
		return $fetch;
 
	}
}
 
?>

Só uma rápida explicação:
A classe Config é uma classe que contem as constantes de configuração de acesso ao banco, a classe DBOMysql é a classe que implementa a interface iDBOMysql e extend a classe Config, vocês podem notar também o uso de public em private nos atributos, essa classe mostra o uso extends e implements, só gostaria de lembrar que como a classe os métodos private da classe não aparecem na interface, e que nesse caso a interface não é algo essencial.

Bom gente por enquanto é isso, quero me desculpar pelo atraso do post, a última semana foi meio corrida e o fim de semana foi de comemoração por que terminei a faculdade.

Abraços e até a próxima, onde nossos assuntos vão ficar cada vez mais interessantes.

OOP no PHP: Visibilidade, definições de public, protected, private e static

E ae blz?

Bom inaugurando a minha participação aqui no blog resolvi começar com uma série de artigos sobre OOP e PHP, no primeiro post eu vou explicar o que significam as palavrinhas public, protected, private e static, o que significam e a função de cada uma delas em nossas classes.

Só pra constar essa série inicial terá 5 posts com os seguintes assuntos.

  • Visibilidade, definições de public, protected, private e static
  • Heranças e Interfaces, extendendo e implementando classes
  • Reaproveitamento, Sobrescrevendo métodos
  • Overloading, utilizando os métodos mágicos do PHP
  • Improviso, simulando a sobrecarga de métodos no PHP

Bom já que estamos com tudo resolvido vamos começar a brincadeira.

As definições de escopo são bem simples e não há necessidade de se extender falando delas.

public é a liberal das definições de escopo, todo método ou atributo de uma classe definido como
public pode ser acessado de qualquer lugar.

protected é um pouco mais contida só pode ser acessada de dentro da classe e de suas classes filhas.

private como o nome já diz é totalmente restrita e só pode ser acessada de dentro da classe.

Exemplo abaixo:

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
<?php
 
class Exemplo {
 
  public $publicInfo = 'Sou uma informação pública';
  protected $protectedInfo = 'Sou uma informação protegida';
  private $privateInfo = 'Sou uma informação restrita';
 
  public function getPublicInfo() {
    echo $this->publicInfo;
  }
 
  protected function getProtectedInfo() {
    echo $this->protectedInfo;
  }
 
  private function getPrivateInfo() {
    echo $this->privateInfo;
  }
 
}
 
$exemplo = new Exemplo;
 
//Imprime Sou uma informação pública
$exemplo->getPublicInfo();
 
//Retorna Fatal error: Call to protected method Exemplo::getProtectedInfo() from context
$exemplo->getProtectedInfo();
 
//Retorna Fatal error: Call to private method Exemplo::getPrivateInfo() from context
$exemplo->getPrivateInfo();
 
?>

Tudo bem aparentemente, então vamos pra função de static.

static permite que algum método ou atributo de uma classe seja chamado sem a necessidade de instanciar a classe. O método/atributo é chamado da seguinte forma:

NomeDaClasse::NomeDoMetodo() ou
NomeDaClasse::$NomeDoAtributo

Exemplo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
 
class ExemploStatic {
	public static $atributo = 'Eu tenho alguma informação';
 
	public static function fazAlgumaCoisa() {
		echo 'Eu faço alguma coisa';
	}
}
 
//Imprime Eu tenho alguma informação
echo ExemploStatic::$atributo;
 
//Imprime Eu faço alguma coisa
ExemploStatic::fazAlgumaCoisa();
 
?>

É por hora acho que já ta de bom tamanho, você pode encontrar mais informações sobre public, private e protected e também sobre a static na documentação oficial do php.

Ainda ficou com alguma dúvida? sim? bom os comentários tão aqui pra isso, mas se você não ficou com dúvidas e quer dar um puxão de orelha no menino aqui, os comentários também server pra isso.

Um abraço e até o próximo post.

Leitura de XML – Parte 1 DOM XML

Já precisaram ler algum XML, de algum lugar, trabalhar com esses valores? Se ainda não precisaram, podem ter a absoluta convicção que esse dia chegará.

Alguns aplicativos ja usam o XML como transmissão de informações, ou recepção de informações. Importar ou exportar um arquivo XML é simples, fácil e rápido, basta manter um padrão para ler dentro de suas tags ou escrever dentro das mesmas.

Alguns sistemas, blogs, entre outros dispostivos, ja estão trabalhando totalmente ou parcialmente com XML, cada um usando formatações diferentes, porém a estrutura do arquivo sempre o mesmo com a marcação de tags, exemplo de um XML comum de RSS do nosso proprio blog TECHNÓCIL:

Nosso XML:

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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
<?xml version="1.0" encoding="UTF-8"?>
 
<rss version="2.0" 
 
    xmlns:content="http://purl.org/rss/1.0/modules/content/" 
 
    xmlns:wfw="http://wellformedweb.org/CommentAPI/" 
 
    xmlns:dc="http://purl.org/dc/elements/1.1/" 
 
    xmlns:atom="http://www.w3.org/2005/Atom" 
 
    > 
 
<channel>
 
    <title>technocil.com</title> 
 
    <atom:link href="http://technocil.com/feed/" rel="self" type="application/rss+xml" /> 
 
    <link>http://technocil.com</link> 
 
    <description></description> 
 
    <pubDate>Tue, 09 Dec 2008 14:30:28 +0000</pubDate> 
 
    <generator>http://wordpress.org/?v=2.6.5</generator> 
 
    <language>en</language> 
 
            <item> 
 
        <title>Primeiro post, Apresentação&#8230;</title> 
 
        <link>http://technocil.com/2008/12/09/primeiro-post-apresentacao/</link> 
 
        <comments>http://technocil.com/2008/12/09/primeiro-post-apresentacao/#comments</comments> 
 
        <pubDate>Tue, 09 Dec 2008 14:29:10 +0000</pubDate> 
 
        <dc:creator>Tobias</dc:creator> 
 
        <category><![CDATA[Geral]]></category> 
 
        <category><![CDATA[Apresentacao]]></category> 
 
        <category><![CDATA[Technócil]]></category> 
 
        <guid isPermaLink="false">http://technocil.com/?p=121</guid> 
 
        <description><![CDATA[nossa descrição do post [...]]]></description> 
 
            <content:encoded><![CDATA[<p>Todo Conteudo do post</p> 
 
<p>Segundo paragrafo</p>]]></content:encoded> 
 
            <wfw:commentRss>http://technocil.com/2008/12/09/primeiro-post-apresentacao/feed/</wfw:commentRss> 
 
        </item> 
 
    </channel> 
 
</rss>

Um tanto quanto grande nosso XML né? Porém ele é ótimo para o exemplo devido aos niveis de title, e description, que irá nos exemplos abaixo.

Agora imaginem como ler ou obter os dados desse nosso RSS (XML). Para isso existem várias maneiras, algumas são usando algumas funções do PHP como a file_get_contents. Exemplo:

1
2
3
4
5
6
7
<?php 
 
$conteudo = file_get_contents('http://technocil.com/feed/');
 
echo $conteudo;
 
?>

Dependendo do seu navegador, o que será impresso é RSS(XML) do nosso blog, ou abrindo o código fonte do que for impresso, verá todo o XML impresso. No meu caso que uso o Opera, precisarei abrir o código fonte para ver o XML Impresso lá. Agora depois trabalhar com esses dados podem ser por expressão regular, e por ai vai, é um trabalhão dessa maneira. O XML não é dinamico, não pode ser interpretado pelo servidor, pode somente ser lido. Para escrever um XML com valores dinamicos sim, se usa usa PHP, e definindo no header o tipo de documento XML, porém ainda não chegamos ao ponto de escrever nenhum XML.

Então para fugir do trabalho duro e chato qual a maneira mais fácil e rápida de trabalhar com XML e seus valores?

São as mais conhecidas duas, usando uma extensão do php chamada DOM XML, que foi revisada no PHP 4.3.0 para trabalhar corretamente com o Padrão DOM, e segunda opção é a SimpleXML.

Instalação do DOM XML

A instalação é simples, basta descomentar a linha do php.ini que possui a extensão domxml.dll ou .so:

extension=php_domxml.dll

No meu caso, como uso o XAMPP 1.6.7, eu comentei a linha, pois a mesma apresentava um erro ao tentar utilizar, e eu apenas comentei e ela voltou a funcionar, no site do PHP Consta alguns avisos de versões, dependendo da sua versão do php, elas são válidas ou não:

Nota: Esta extensão foi movida para o repositório » PECL e não é mais distribuida em conjunto com o PHP a partir do PHP 5.0.0.

Nota: Esta extensão não está mais marcada como experimental. Ele será, contudo, nunca liberada com PHP 5, e irá somente ser distribuida com PHP 4. Se você precisa de suporte a DOM XML com PHP 5, você pode usar a extensão DOM. Esta extensão domxml não é compatível com a extensão DOM.

Alguns servidores web, porém tem dificuldade em trabalhar com essa biblioteca, um exemplo é a Locaweb (não vo divulgar o nome do cliente), que sofreu para que pudessem colocar esse componente tão simples no servidor. Mas isso vai de cliente a cliente. Eu aproveitando o gancho vou divulgar a IW² onde possui SVN (controle de versão), SSH e bibliotecas desses e outros usos liberadas, que hospeda aqui o TECHNOCIL.

Vamos aos códigos do DOM XML:

1
2
3
4
//aqui iniciamos o trabalho com o DOM, definindo o cabeçalho como versão do XML 1.0, e trabalhando com o charset em UTF-8;
$doc = new DOMDocument('1.0?', 'UTF-8?'); 
// aqui fazemos o load de todo o conteúdo do XML 
$doc->load('http://technocil.com/feed/');

Primeira fase completa, ja pegamos todo o conteudo do XML, ja iniciamos a extensão do DOM, e ja podemos usar os seus componentes:

1
2
3
//exibe o titulo : technocil.com; pegando da tag title na raiz do XML:     <title>technocil.com</title>
$titulo        =    $doc->getElementsByTagName("title")->item(0)->nodeValue;
echo $titulo ;

Caso eu queira o titulo do post eu tenho que entrar dentro dos niveis do XML:

1
2
3
// observe o item(1); Estamos trabalhando com niveis, parecidos com array, onde temos [0], [1], ['titulo'];
$tituloPost        =    $doc->getElementsByTagName("title")->item(1)->nodeValue; 
echo $tituloPost ;

Agora vamos pegar a descrição do Post:

1
2
3
// observe que estamos ainda usando o item(1), ainda estamos em um segundo nivel das marcações
$DescricaoPost        =    $doc->getElementsByTagName("description")->item(1)->nodeValue; 
echo $DescricaoPost ;

Para ler esse conteudo dinamicamente, pode se trabalhar com foreach, listando nos ->item($i) um valor de listagem contando quantos posts possuem no XML. Agora é só brincarem ;)

Na parte dois, posto um exemplo de como pegar e trabalhar com os dados de Frete dos Correios, usando o XML de resposta das consultas por URL, e na parte 3, como trabalhar com o SimpleXML, no qual eu considero mais trabalhoso e chato.

Até mais!