Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Bruno Augusto

Mesclar Objetos stdClass

Recommended Posts

Dá pra fazer sem ser assim:

 

class Object extends stdClass {

   public function merge( stdClass $param ) {

       foreach( $param as $property => $value ) {

           $this -> $property = $value;
       }
   }
}

 

?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Dá pra fazer sem ser assim:

 

Bruno e seus problemas cabulosos.

 

Mas dessa vez nem vou perguntar o que você quer fazer, de cara dá para perceber que é um POG descabido.

 

Ao fazer isso você perde o encapsulamento e obrigará alguém a ter uma bola de cristal, caso venha a manter esse código.

 

Se você está, de fato, precisando fazer isso, talvez seja hora de reanalisar sua modelagem.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Não é POG não.

 

Só não queria criar toda uma estrutura megalomaníaca apenas para facilitar a definição de opções para um sistema.

 

Cada classe abstrata instancia um objeto stdClass simples para armazenamento de opções-padrão definidas através de um método abstrato.

 

Quando instanciada a classe concreta, pode-se passar um stdClass no construtor para sobrescrever algumas das propriedades padrão. E daí a necessidade de mesclar dois stdClass: o "nativo" da classe abstrata e o "personalizado" vindo pelo construtor de onde for usado.

 

abstract class AbstractFoo implements IFoo {

   protected $options;

   public function __construct( stdClass $options = NULL ) {

       $this -> options = new Object; // Para ter acesso à IObject::merge(), jhá que stdClass não tem

       $this -> setDefaults();

       if( ! is_null( $options ) ) {
           $this -> options -> merge( $options );
       }
   }

   abstract protected function setDefaults();

   public function getOptions() {
       return $this -> options;
   }
}

class Foo extends AbstractFoo {

   protected function setDefaults() {

       $this -> options -> filename = 'File.txt';
       $this -> options -> savePath = '/Public';
   }
}

$foo = new Foo;

var_dump( $foo -> getOptions() );

/**
* Saída:
*
* object(Object)[2]
*   public 'filename' => string 'File.txt' (length=8)
*   public 'savePath' => string '/Public' (length=7)
*/

$options = new stdClass;
$options -> filename = 'New.txt';

$foo2 = new Foo( $options );

var_dump( $foo2 -> getOptions() );

/**
* Saída:
*
* object(Object)[2]
*   public 'filename' => string 'New.txt' (length=8)
*   public 'savePath' => string '/Public' (length=7)
*/

Com código acho que ficou melhor explicado né?

 

Não vejo isso como errado, mas me incomoda a forma como esse IObject::merge() esteá funcionando...

Compartilhar este post


Link para o post
Compartilhar em outros sites

Você rodou o código de exemplo acima ou, de repente, só de ver, viu o que ele faz?

 

A classe abstrata possui um conjunto de opções que afetarão a forma como as classes concretas que dela extenderem farão certas coisas.

 

Porém, seu construtor recebe um objeto como parâmetro permitindo que o usuário altere as definições padrão, separada do construtor em setDefaults, que abstrato (já que cada classe concreta pode ter diferentes opções).

 

Se o parâmetro fosse um array, poderia tranquilamente usar array_merge() ou, se fosse o caso, usar uma derivação dele com suporte à recursividade.

 

Mas e se eu quisesse usar um objeto stdClass? Foi daí que surgiu essa questão, apenas como curiosidade (que eu tenho de sobra).

 

Eu fiz, mas não sei se é a melhor forma. De repente você pode conhecer um meio de se fazer sem usar foreach, quem sabe.

 

Estou apenas fazer aquilo que o fórum propõe, movimentando idéias ;)

 

Atualmente, esse trecho de código faz sim parte de um sistema maior, porém opera na sua própria classe que maximiza a funcionalidade desse recurso.

 

Originalmente todo o processo manual usava diversas linhas e, com o uso constante, que visa personalizar todos os objetos, de quase todos os módulos que desenvolvo, começou a ficar tedioso, daí transofrmei num classe só para isso.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Bruno, abaixo seguem links importantíssimos para você. Por favor, visite-os e conheça os recursos que o PHP fornece a orientação a objetos:

 

http://br3.php.net/manual/pt_BR/ref.classobj.php

http://br3.php.net/manual/pt_BR/reserved.interfaces.php

http://br3.php.net/manual/pt_BR/book.reflection.php

Compartilhar este post


Link para o post
Compartilhar em outros sites

nao testei o codigo mas, observando superficialmente, parece faltar a interface não ?

Qual delas, na sua opinião, estaria faltando. Saliento apenas que o código acima eu escrevi na hora em que postava. Só testei para poder postara saída também.

 

Bruno, abaixo seguem links importantíssimos para você. Por favor, visite-os e conheça os recursos que o PHP fornece a orientação a objetos:

 

http://br3.php.net/manual/pt_BR/ref.classobj.php

http://br3.php.net/manual/pt_BR/reserved.interfaces.php

http://br3.php.net/manual/pt_BR/book.reflection.php

Jaime, conheço muito bem esses recursos e utilizo-os tanto quanto eu posso, da melhor forma que meus conhecimentos me permitem.

 

Descritivamente, a cada um dos links postados:

 

- Do primeiro link, apenas utilizo get_object_vars() para mapear um objeto stdClass de volta para um array. Atualmente não uso, mas tenho o recurso pronto.

 

- Do segundo link, "não preciso" usar, afinal ao que parece os objetos stdClass já são iteráveis o que leva a crer que já implementam pelo menos Iterator (e consequentemente Traversable), mesmo que class_implements() não mostre nada.

 

- Do terceiro link, não se aplica ao caso, muito embora eu conheço e utilize fortemente ele, já que meu sistemas de roteamento de URL é todo construído pela Reflection.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Pessoal, desculpa fazer o tópico dar uma de fênix, mas vi esse post no forum, estava caçando no google uma forma de mesclar dois stdClass, e fiz um teste e me espantei com o resultado.

 

O processo consiste em passar os dois objetos para array, juntar os dois e passar novamente para objeto, infelizmente só é útil se tivermos 2 stdClass, o seu caso cobre classes implementadas.

 

$objetoFinal = (Object) array_merge( (array) $objeto1 , (Array) $objeto2 );

 

Apesar de ser um recurso da linguagem, é uma baita POG, mas resolve alguns problemas e permite que escrevamos menos código.

 

Viva a POG! Desde de que orientada a objetos!

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.