Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Olá pessoal, gostaria que alguém fizesse um resumo bem didático sobre esse código abaixo me explicando os métodos usados nele __set __get __call. Pesquisei sobre eles, mas estou com algumas dúvidas a respeito do funcionamento, características e seus usos. Nesta parte LogManager::logar("Foi chamado o método '$nomeDoMetodo' na classe Pessoa e ele não existe."); não consegui compreender o uso de LogManager::logar (acredito que este código está errado nessa parte) se possível explique o uso do :: nesse trecho.
Se vocês acharem uma maneira melhor sem utilizar esse código que eu estava estudando, sinta se à vontade... :)
<?php
class Pessoa
{
private $_dados;
public function __set( $chave, $valor )
{
$this->dados[ $chave ] = $valor;
}
public function __get( $chave )
{
return $this->{$chave};
}
public function __call( $nomeDoMetodo, $argumentos )
{
LogManager::logar("Foi chamado o método '$nomeDoMetodo' na classe Pessoa e ele não existe.");
}
}
$pessoa = new Pessoa();
$pessoa->andar();
?>Muito obrigado João Batista era tudo o que eu precisa e mais um bocado :] Estou tentando aprender POO e estudar sendo autodidata é complicado e as dúvidas sempre aparecem rsrs... Quando vi sua explicação que por sinal foi muita boa, fiquei ate um pouco desnorteado achando que não entenderia esse script que você fez, mas tudo deu certo e entendi, sempre achei POO um bicho de 7 cabeças, e não imaginava o quanto é grande poder dela.
Gostaria de saber só mais uma coisa, a ordem que esse código vai ser executado quando você instância a classe, por causa dos métodos mágicos será esta? --> método __construct --> método __set --> método _call --> método __unset --> método __call --> método __call . Digo essa ordem levando em conta essa instancia abaixo.
<?php
$teste = new ValueObject( "tabela" );
$teste->nome = "João Neto";
$teste->idade = 27;
$teste->linguagem = "PHP";
$teste->insert();
unset( $teste->idade );
$teste->insert();
$teste->update( "id" , 10 );
?>
Não pude deixar de notar que você é de Franca, sou de Batatais ^^Obrigado pela força, Abraço!>
Gostaria de saber só mais uma coisa, a ordem que esse código vai ser executado quando você instância a classe, por causa dos métodos mágicos será esta? --> método __construct --> método __set --> método _call --> método __unset --> método __call --> método __call . Digo essa ordem levando em conta essa instancia abaixo.
<?php
$teste = new ValueObject( "tabela" );
$teste->nome = "João Neto";
$teste->idade = 27;
$teste->linguagem = "PHP";
$teste->insert();
unset( $teste->idade );
$teste->insert();
$teste->update( "id" , 10 );
?>
De fato, a chamada será exatamente essa, olhe só:
/applications/core/interface/imageproxy/imageproxy.php?img=http://www.visualcom.com.br/imagens/ValueObject.jpg&key=dbd81e4a2eabce78ef951dc057c61eee5af0b95912a2fdbdfb3e5efa86841eb2" alt="Imagem Postada" class="bbc_img">
João Batista muito obrigado!!
Joao,
poderia me explicar esse codigo?
printf( "INSERT INTO `%s`(`%s`) VALUES('%s');\n" , $this->table , implode( "`,`" , array_keys( $this->data ) ) , implode( "','" , $this->data ) );
porque dos "implode"; como funciona para ele lançar oque é campos de tabela e oque sao valores a serem atribuidos?
Eu poderia fazer um codigo desses que aceitasse insert de qualquer formulario para qualquer tabela?
vlw
>
poderia me explicar esse codigo?
printf( "INSERT INTO `%s`(`%s`) VALUES('%s');\n" , $this->table , implode( "`,`" , array_keys( $this->data ) ) , implode( "','" , $this->data ) );
porque dos "implode"; como funciona para ele lançar oque é campos de tabela e oque sao valores a serem atribuidos?
A função implode pega os itens de uma matriz e transforma em uma matriz utilizando um separador passado como primeiro argumento.
$itens = array( 'a' , 'b' , 'c' , 'd' );
echo implode( '-' , $itens ); //a-b-c-d
É comum pensar nesse separador como uma vírgula, pipe, hífem ou qualquer separador simples, porém o implode é muito mais poderoso que isso, com ele, podemos com uma única linha obter o mesmo resultado que teríamos iterando uma matriz através de um loop:
echo '<html><head><title>Implode</title></head><body><table><tr>';
for ( $i = 0 , $t = count( $itens ) ; $i < $t ; $i++ ){
echo '<td>' . $itens[ $i ] . '</td>';
}
echo '</tr></table></body></html>';
A saída do código acima será:
>
<html><head><title>Implode</title></head><body><table><tr><td>a</td><td>b</td><td>c</td><td>d</td></tr></table></body></html>
Para conseguir o mesmo resultado sem iterar a matriz com um loop basta pensar no separador como algo mais elaborado, utilizando o exemplo das <td></td> da tabela acima:
echo '<html><head><title>Implode</title></head><body><table><tr><td>' . implode( '</td><td>' , $itens ) . '</td></tr></table></body></html>';
A saída será exatamente a mesma.
Pensando nos separadores dessa forma, é possível utilizar esses separadores para montar uma consulta SQL:
$campos = array( 'nome' , 'endereco' , 'bairro' , 'cidade' );
$valores = array( 'Neto' , 'Rua dos bobos, 0' , 'bairro' , 'Franca' );
$tabela = 'tabela';
echo 'SELECT `' . implode( '`,`' , $campos ) . '` FROM ' . $tabela;
echo 'INSERT INTO ' . $tabela . '(`' . implode( '`,`' , $campos ) . '`) VALUES("' . implode( '","' , $valores ) . '");';
A saída do código acima será:
>
SELECT `nome`,`endereco`,`bairro`,`cidade` FROM tabela
INSERT INTO tabela(`nome`,`endereco`,`bairro`,`cidade`) VALUES("Neto","Rua dos bobos, 0","bairro","Franca");
>
Eu poderia fazer um codigo desses que aceitasse insert de qualquer formulario para qualquer tabela?
Quando você fala em "qualquer formulario para qualquer tabela" você está falando em abstração e isso não se consegue sem algum planejamento, é necessário levar em conta vários fatores inclusive segurança.
Mas se você quiser brincar um pouco com isso, o PHP além dos métodos mágicos lhe permite a criação de classes em tempo de execução, juntando isso mais os métodos mágicos e o implode para nos ajudar um pouco você pode fazer alguma coisa assim:
/**
* Registramos uma função de autoload que irá criar nossas classes em tempo de execução
*/
spl_autoload_register( create_function( '$class' , 'eval( sprintf( "class %s extends Tabela {}" , $class ) );' ) );
/**
* Essa é a classe base das nossas tabelas.
*/
class Tabela {
private $fields;
final public function __get( $name ){
return isset( $this->fields[ $name ] ) ? $this->fields[ $name ] : null;
}
final public function __set( $name , $value ){
$this->fields[ $name ] = $value;
}
public function select(){
return sprintf( 'SELECT `%s` FROM `%s`;' , implode( '`,`' , array_keys( $this->fields ) ) , get_class( $this ) );
}
public function insert(){
return sprintf( 'INSERT INTO `%s`(`%s`) VALUES("%s");' , get_class( $this ) , implode( '`,`' , array_keys( $this->fields ) ) , implode( '","' , array_values( $this->fields ) ) );
}
}
/**
* Preste atenção que não existe uma classe tb_usuarios declarada em lugar nenhum, ela não existe e será criada em
* tempo de execução pela nossa função de __autoload
*/
$teste = new tb_usuarios();
$teste->id = 10;
$teste->nome = "João Batista Neto";
$teste->user = "neto";
$teste->senha = "testedesenha";
$teste->ativo = "s";
echo $teste->insert();
>
Olá pessoal, gostaria que alguém fizesse um resumo bem didático sobre esse código abaixo me explicando os métodos usados nele __set __get __call. Pesquisei sobre eles, mas estou com algumas dúvidas a respeito do funcionamento, características e seus usos. Nesta parte LogManager::logar("Foi chamado o método '$nomeDoMetodo' na classe Pessoa e ele não existe."); não consegui compreender o uso de LogManager::logar (acredito que este código está errado nessa parte) se possível explique o uso do :: nesse trecho.
Bom amigão, vamos lá:
__construct é usado para criar um novo objeto da classe e __destruct é usado para destruir o objeto.
__call é usado para chamar um método da classe.
__set, __unset e __get são referentes às propriedades, então quando queremos definir um valor de uma propriedade do objeto dinamicamente usamos esses métodos.
<?php
/**
* Demonstração dos métodos mágicos do PHP
* @author João Neto <neto.joaobatista@gmail.com>
* @method string insert() insert() Simula a insersão de um novo registro na base de dados
class ValueObject {
/**
* O nome da tabela no banco de dados
* @var string
*/
Agora usando o código acima:
Sempre que usamos o operador new o método mágico __construct é chamado e para ele é passado os argumentos utilizados na chamada:
$teste = new ValueObject( "tabela" );
Depois de criar o objeto vamos definir algumas propriedades:
Para cada uma dessas atribuições é chamado o método mágico __set e para ele é passado dois parâmetros, o primeiro é o nome da propriedade e o segundo o valor, por exemplo:
$teste->nome = "João Neto";
A linha acima é o mesmo que escrever:
$teste->__set( "nome" , "João Neto" );
O contrário do método __set é o método __unset, em vez de definir ele remove a definição:
unset( $teste->nome );
O código acima remove a definição da propriedade nome e é o mesmo que o código abaixo:
$teste->__unset( "nome" );
O método __get é usado para recuperar o valor da propriedade:
echo $teste->nome;
A saída do código acima será: João Neto. Similarmente ao método __set, o método __get é chamado sempre que tentamos recuperar o valor de uma propriedade não definida, escrever o código acima é o mesmo que:
echo $teste->__get( "nome" );
Ao contrário dos métodos __get, __set e __unset; O método mágico __call está relacionado aos métodos da classe e não às propriedades, por exemplo:
$teste->insert();
O código é o mesmo que escrever:
$teste->__call( "insert" , array() );
Ou então:
$teste->update( "id" , 10 );
O código acima é o mesmo que escrever:
$teste->__call( "update" , array( "id" , 10 ) );
Usando a classe ValueObject:
A saída do código acima será:
Como pode ver, os métodos mágicos nos permite fazer coisas simples como demonstrei com a ValueObject, mas podem ir tão longe quanto sua imaginação permitir.
Um tema interessante para estudar é o uso desses métodos mágicos em conjunto com Lazzy Initialization.