Estou usando um sistema de armazenamento de terceiros que só retorna objetos stdClass, não importa o que eu forneça por algum motivo obscuro. Portanto, estou curioso para saber se existe uma maneira de lançar / converter um objeto stdClass em um objeto completo de um determinado tipo.
Por exemplo, algo como:
//$stdClass is an stdClass instance
$converted = (BusinessClass) $stdClass;
Estou apenas lançando a stdClass em uma matriz e alimentando-a para o construtor BusinessClass, mas talvez haja uma maneira de restaurar a classe inicial da qual não estou ciente.
Observação: não estou interessado no tipo de respostas 'Alterar seu sistema de armazenamento', pois não é o ponto de interesse. Por favor, considere isso mais uma questão acadêmica sobre as capacidades linguísticas.
Felicidades
PDOStatement::fetchObject
realizar essa tarefa?Respostas:
Veja o manual sobre Malabarismo de Tipos sobre possíveis elencos.
Os lançamentos permitidos são:
Você teria que escrever um Mapeador que faça a conversão de stdClass para outra classe concreta. Não deve ser muito difícil de fazer.
Ou, se você estiver com um humor hackeado, pode adaptar o seguinte código:
que pseudocats um array para um objeto de uma determinada classe. Isso funciona primeiro serializando a matriz e, em seguida, alterando os dados serializados para que representem uma determinada classe. O resultado é desserializado para uma instância desta classe então. Mas, como eu disse, é hackeado, então espere efeitos colaterais.
Para objeto para objeto, o código seria
fonte
__PHP_Incomplete_Class
objeto usando este método (pelo menos a partir do PHP 5.6).fooBar
s (o privado deexample\Foo
e o público de stdClass). Em vez disso, ele substitui o valor.Você pode usar a função acima para lançar objetos de classe não semelhantes (PHP> = 5.3)
EXEMPLO:
fonte
@Given the user :username has the id :id
no meu recurso e tratá-lo com reflexos na classe de contexto$destination = new $destination();
pode ser trocado$destination = ( new ReflectionClass( $destination ) )->newInstanceWithoutConstructor();
se você precisar evitar chamar o construtor.Para mover todas as propriedades existentes de a
stdClass
para um novo objeto de um nome de classe especificado:Uso:
Resultado:
Isso é limitado por causa do
new
operador, pois não se sabe quais parâmetros seriam necessários. Provavelmente adequado para o seu caso.fonte
Eu tenho um problema muito similar. A solução de reflexão simplificada funcionou bem para mim:
fonte
Espero que alguém ache isso útil
fonte
Função alterada para deep casting (usando recursão)
fonte
E ainda outra abordagem usando o padrão decorator e getter e setters mágicos do PHP:
fonte
BTW: a conversão é muito importante se você for serializado, principalmente porque a desserialização quebra o tipo de objetos e se transforma em stdclass, incluindo objetos DateTime.
Atualizei o exemplo do @Jadrovski, agora ele permite objetos e arrays.
exemplo
array de exemplo
código: (é recursivo). No entanto, não sei se é recursivo com matrizes. Pode estar faltando um is_array extra
fonte
considere adicionar um novo método ao BusinessClass:
então você pode fazer uma nova BusinessClass a partir de $ stdClass:
fonte
Mais uma abordagem.
O seguinte agora é possível graças à versão recente do PHP 7.
Neste exemplo, $ foo está sendo inicializado como uma classe anônima que recebe um array ou stdClass como único parâmetro para o construtor.
Por fim, percorremos cada um dos itens contidos no objeto passado e os atribuímos dinamicamente à propriedade de um objeto.
Para tornar este evento Approch mais genérico, você pode escrever uma interface ou uma Característica que irá implementar em qualquer classe onde você deseja ser capaz de lançar uma stdClass.
fonte
Converta-o em uma matriz, retorne o primeiro elemento dessa matriz e defina o parâmetro de retorno para essa classe. Agora você deve obter o preenchimento automático para essa classe, já que ele irá regconizá-la como essa classe em vez de stdclass.
fonte