Boa noite a todos,
Hoje vou explicar sobre um assunto que já é bastante citado pela Web, a programação Orientada a Objetos no PHP. As últimas versões do PHP vieram com muitos recursos para permitir o desenvolvimento de códigos baseados em objetos (classes, interfaces, etc.), junto a tudo isso vieram:
- Organização de arquitetura de uma aplicação PHP;
- Abstração de código;
- Reutilização do código;
- Redução de linhas de código repetidas;
Para poder explicar um pouco como funciona esse "mundo" no PHP, vou apresentar um pequeno exemplo de como podemos "ou utilizamos" a orientação a objetos em nossos trabalhos diários.
Basicamente o nosso exemplo será uma pequena aplicação para persistir objetos, no caso as operações basicas (CRUD). Começamos pela nossa superclasse comum para o modelo de negócio do nosso sistema:
A classe Bean contém as características básicas para um objeto do sistema.
<?php
abstract class Bean
{
protected $id = 0;
protected $tablename;
function Bean($tablename)
{
if(!$tablename)
{
die('Por favor informe o nome da tabela do objeto.');
}
$this->set_tablename($tablename);
}
public function get_id () { return $this->id; }
public function get_tablename () { return $this->tablename; }
public function set_id ($id) { $this->id = $id; }
public function set_tablename ($tablename) { $this->tablename = $tablename; }
}
?>
A seguir temos a classe Usuario, ou melhor chamarmos do nosso Objeto Usuario. O mesmo estende as características da superclasse Bean, assim garante um comportamento padrão para todos os objetos do sistema.
<?php
require_once (dirname(__FILE__)."/Bean.class.php");
class Usuario extends Bean
{
private $nome;
private $senha;
private $login;
// getters e setters
public function get_nome () { return $this->nome; }
public function get_senha () { return $this->senha; }
public function get_login () { return $this->login; }
public function set_nome ($nome){ $this->nome = $nome;}
public function set_login ($login){ $this->login = $login;}
public function set_senha ($senha){ $this->senha = $senha;}
}
?>
Basicamente todas os outros objetos do sistema seguiriam este padrão de utilização, as necessidades podem mudar de acordo com o projeto que você esteja desenvolvendo.
Agora vamos imaginar uma peça que iremos fazer para persistir os nossos objetos de maneira generica por exemplo, para isso temos que pensar em algumas coisas, como:
- Ele irá ser 100% funcional para todos os casos;
- Que tipos de regras terei que seguir para utiliza-lo;
- Tipos de resposta;
- Performance;
- Escalabilidade;
- Viabilidade se comparado ao uso de algum framework;
- Etc;
Eu sempre sigo um meio que me previne de alterações inesperadas, como assim? Quando desenvolvo a camada de negócio, sempre faço uma classe que contenha uma implementação genérica que sirva aos elementos básicos da aplicação tais como categorias, tipos, marcadores, etc.
<?php
require_once (dirname(__FILE__)."/Bean.class.php");
interface IObjectManager
{
public function save (Bean $object, $tablename, $return_mode = "OBJECT");
public function delete(Bean $object, $return_mode = "OBJECT");
public function get (Bean $object);
public function get_list (Bean $object, $params);
}
?>
<?php
class MySQL
{
private $conn = null;
private $link = null;
private $result = null;
private $error = null;
function MySQL()
{
if(!$this->conn)
{
$this->conn = mysql_connect("localhost", "root", "123");
$this->link = mysql_select_db("sigae", $this->conn);
}
}
function __destruct()
{
if($this->has_connection())
{
$this->close_connection();
}
}
protected function has_connection ()
{
return $this->conn ? true : false;
}
protected function execute_query ($query)
{
$this->result = mysql_query($query, $this->conn) or $this->error = mysql_error($this->conn);
}
protected function get_affected_rows ()
{
return mysql_affected_rows($this->conn);
}
protected function get_error_message ()
{
return $this->error;
}
protected function close_connection ()
{
return mysql_close ($this->conn);
}
}
?>
Vamos ficar atentos ao seguinte item interessante e muito bacana que o PHP nos disponibiliza, o método mágico "__destruct()", ou seja, este sempre será executado quando uma classe destruída da memória ou do seu ciclo de execução na aplicação. Neste nosso tutorial eu preferi apenas destruir a conexão com a base de dados.
<?php
require_once (dirname(__FILE__)."/MySQL.class.php");
require_once (dirname(__FILE__)."/IObjectManager.class.php");
class ObjectManager extends MySQL implements IObjectManager
{
function ObjectManager()
{
}
public function save (Bean $object, $tablename, $return_mode = "OBJECT")
{
return $object;
}
public function delete (Bean $object, $return_mode = "OBJECT")
{
$ob = $this->get($object);
if($ob)
{
$query = "DELETE FROM ".$object->get_tablename()." WHERE id = '".$object->get_id()."'";
$this->execute_query($query);
return $ob;
}
else
{
return null;
}
}
public function get (Bean $object)
{
}
public function get_list(Bean $object, $params)
{
}
}
?>
<?php
require_once (dirname(__FILE__)."/MySQL.class.php");
require_once (dirname(__FILE__)."/IObjectManager.class.php");
class UsuarioManager extends MySQL implements IObjectManager
{
function UsuarioManager()
{
}
public function login_usuario ($login, $senha)
{
$query = "SELECT u.*
FROM usuario u WHERE u.login = '$login' AND u.senha = PASSWORD('$senha')";
$this->execute_query($query);
return $this->get_result();
}
public function save (Bean $object, $tablename, $return_mode = "OBJECT")
{
// não necessário
}
public function delete (Bean $object, $return_mode = "OBJECT")
{
// não necessário
}
public function get (Bean $object)
{
// não necessário
}
public function get_list(Bean $object, $params)
{
// não necessário
}
}
?>
<?php
require_once (dirname(__FILE__)."/MySQL.class.php");
require_once (dirname(__FILE__)."/IObjectManager.class.php");
class UsuarioManagerImpl extends ObjectManager
{
public function login_usuario ($login, $senha)
{
$query = "SELECT u.*
FROM usuario u WHERE u.login = '$login' AND u.senha = PASSWORD('$senha')";
$this->execute_query($query);
return $this->get_result();
}
}
?>
Baixar o arquivo ZIP do tutorial




