Aloha!
O papo agora é sobre a sobrecarga do PHP, mais precisamente 2 deles que são: __get() e __set().
Eu particularmente já os conhecia, mas somente essa semana resolvi fazer uns testes e ver suas utilidades e limitações.
Bom, chega de papo e vamos ao source:
Controller.php
-
<?php
-
-
-
final class Controller {
-
-
-
$ProdutoModelo['Id'] = $Produto[0];
-
$ProdutoModelo['Nome'] = $Produto[1];
-
$ProdutoModelo['Idade'] = $Produto[2];
-
-
$modelo = new Modelo($ProdutoModelo);
-
//$modelo->Id = 2; // Sobrescreve o $ProdutoModelo['Id']
-
-
return $modelo->Adiciona(); // O novo broda adicionado...
-
}
-
}
Partindo do princípio que você tenha noções básicas de MVC, acima é nossa Controller.php. Ele recebe os dados vindo do usuário e indica para qual Modelo(Model) será derecionado os dados para aplicarmos a regra de negócio.
Falando em Modelo...
-
<?php
-
-
class Modelo {
-
private $Id;
-
private $Nome;
-
private $Idade;
-
-
if(!$params) return;
-
foreach($params as $pname => $pvalue) {
-
$this->$pname = $pvalue;
-
}
-
}
-
-
/**
-
* Adiciona um usuário e tal.
-
*
-
* @return string || boolean
-
*/
-
public function Adiciona() {
-
// Regra de negócio aqui, ó!
-
if(!$this->Id) return false;
-
$this->Id = (int)$this->Id;
-
-
try {
-
Dao::Adiciona($this);
-
return 'Usuário cadastrado com número: ' . $this->Id;
-
}catch(Exception $e) {
-
// Salva Exception no log e tal, e exibe uma mensagem ao usuário
-
return "Não foi possível Adicionar! =~";
-
}
-
}
-
-
-
/* setters e getters mágicos */
-
public function __set($pname, $pvalue) { $this->$pname = $pvalue; }
-
public function __get($pname) { return $this->$pname; }
-
-
}
O mais importante de tudo é isso aqui, ó:
-
public function __set($pname, $pvalue) { $this->$pname = $pvalue; }
-
public function __get($pname) { return $this->$pname; }
Setando isto, assim que eu chamar: $metodo->Id = 2 meu atributo Id do objeto Modelo passará a ter o valor 2. Caso eu simplesmente rode um $metodo->Id; eu poderei resgatar o valor passado ao atributo.
Para quem ainda não viu os atributos da class Metodo, aqui estão eles:
-
private $Id;
-
private $Nome;
-
private $Idade;
Note que eu descrevi no Método construtor da classe uma iteração foreach para correr o $Params em busca de setters para setar. Obviamente se passarmos um Atributo não existente, um erro será lançado, para tanto será necessário um tratamento do dado inserido para garantir que o atributo realmente existe.
Como descrevemos a Dao ali no método Adiciona() da classe Modelo, coloco seu conteúdo abaixo:
-
<?php
-
-
class Dao {
-
-
// faz alguma coisa no banco e tal.
-
return $mod->Id; // Retorna o novo id cadastrado, por exemplo
-
}
-
}
Então, se eu criasse a seguinte estrutura:
Os três atributos (1, Fulaninha e 22) seriam passados à seus respectivos Atributos dentro da Classe Modelo, pois a Controller fez o tratamento desse Array passando os valores coerentes de acordo com a exigência da classe Modelo.
Uma alternativa seria inutilizar esse método construtor __construct(Array $params) e chamar os valores direto, para isto, basta modificarmos nossa Controller que estará tudo resolvido:
-
<?php
-
-
-
final class Controller {
-
-
-
$modelo->Id = $Produto[0];
-
$modelo->Nome = $Produto[1];
-
$modelo->Idade = $Produto[2];
-
return $modelo->Adiciona(); // O novo broda adicionado...
-
}
-
}
Pronto, não utilizamos mais o __construct() para popular nossos atributos.
Desvantagens
Apesar de ser muito útil e facilitar muito a criação dos getters e setters das nossas aplicações, vale lembrar que essa forma deixa muito 'limitada' nosso controle ao gets e sets do objeto. Uma das limitações se dá quanto ao nome do método get/set que usando a sobrecarga, nos obriga a usar o mesmo nome do atributo criado na classe.
Outro problema é quanto a atualização de nomes. Se eu precisar mudar o nome do atributo, terei que mudar em toda a extensão do código criado, Controllers, Daos e Views.
Resumindo: Essa é uma ferramenta que pode lhe ajudar muito da mesma forma que pode te quebrar legal. Cabe você avaliar quando usá-la e quando usar o tradicional:
-
<?php
-
public function setId($i) { $this->Id = $i; }
-
public function getId() { return $this->Id; }
-
-
public function setNome($n) { $this->NomeCompleto = $n; }
-
public function getNome() { return $this->NomeCompleto; }






“utro problema quanto a atualizao de nomes. Se eu precisar mudar o nome do atributo, terei que mudar em toda a extenso do cdigo criado, Controllers, Daos e Views.”
O que pode ser feito para evitar isso seria criar uma condio temporria dentro do __set e __get para o novo nome do atributo, e aps o sistema ter sido todo adaptado para o novo nome, s tirar a condio
abrao!
Sem dvida so uteis e bem prticos, especialmente em classes mais genericas.
Outro problema quando se precisa dar tratamento em entradas ou sadas especificas, que pode gerar um mtodo muito grande.
Bom lgela neh quebra um galho mas ainda h que melhorar bastante pra se usar sem limitaes… =)
regra de negocio no modelo?
controller serve pra direcionarmos para qual usuario sera aplicado a regra de negocio?
cada um diz uma coisa sobre mvc mas ngm diz o certo.
@jhon
MVC é bem definido sim. Explico:
Modelo MVC web, temos:
View – a visualização (arquivo de template, etc)
Controller – divide-se em duas:
— FrontController: tem a missão de direcionar o fluxo para uma controller, no caso, a “chamada” pelo usuário na View. Ex: index.php é uma FrontController.
— Controller: é o cara que recebe o “clicar do botão” do usuário lá na View. A controladora recebe este “evento” e tem a missão de chamar a Regra de negócio para fazer valer a ação. Ao fim, devolve ao usuário uma View com a resposta.
— Model: aqui há uma porção de subdivisões. Mas de forma simples ela é quem faz a coisa acontecer. É aqui que fica a regra de negócio da sua aplicação.
Recomendo a leitura de livros/materiais sobre Arquitetura de software para entender mais. Na página livros aqui do blog você poderá encontrar alguns títulos bons para ler.
O assunto (Arquitetura em camadas) é extenso e depois que pega o caminho você começa a entender o por quê das coisas.
Abraço,
No Model sim ficam a regras de negócio (como validações e segurança).
Agora, como você vai implementar o Controller.. é outra história… mas as responsabilidades são simples.. o Controller deve executar operações no Model e selecionar as View’s necessárias.