Uma maneira fácil de converter uma classe padrão PHP para um tipo específico
Se você trabalha com PHP orientado a objetos no WordPress e está construindo vários modelos que se encaixam em seus aplicativos da Web, as chances são de que você vai lidar com a recuperação de versões serializadas desses modelos em algum momento durante a execução de um programa.
Aqui está a coisa, porém: Às vezes, esses dados não serializados voltam como classes PHP padrão. Isso significa que, se você inspecionar o tipo (por meio de várias ferramentas de depuração), verá que eles são do tipo stdClass.
Se você estiver construindo adequadamente seus modelos, seu código terá funções que a stdClass não possui, e você desejará chamá-las.
Além disso, você não pode simplesmente convertê-los de um tipo para outro como você pode fazer com tipos nativos (como strings, inteiros e assim por diante). Em situações como essa, você precisa ser capaz de converter uma classe padrão do PHP para um tipo específico.
E aqui está uma função que irá ajudá-lo a fazer exatamente isso.
Cast um PHP uma classe padrão para um tipo específico
Para este exemplo, suponha o seguinte:
- Eu tenho uma classe com namespace como AcmeModelProduct.
- Ele, em algum momento, é salvo no banco de dados do WordPress, mas quando recuperado é definido como uma instância de stdClass.
- Eu preciso que a versão não serializada do objeto seja a do Product.
Para esse fim, tenho a seguinte função disponível que coloco em projetos conforme necessário:
<?php
/**
* This function will take an instance of a PHP stdClass and attempt to cast it to
* the type of the specified $className.
*
* For example, we may pass 'AcmeModelProduct' as the $className.
*
* @param object $instance an instance of the stdClass to convert
* @param string $className the name of the class type to which we want to cals
*
* @return mixed a version of the incoming $instance casted as the specified className
*/
protected function cast($instance, $className)
{
return unserialize(sprintf(
'O:%d:"%s"%s',
strlen($className),
$className,
strstr(strstr(serialize($instance), '"'), ':')
));
}
Claro, a função é comentada com o máximo de detalhes que posso fornecer, mas há algumas coisas que posso explicar um pouco mais no contexto de uma postagem do que no contexto de um comentário de código.
Entendendo o Código
Primeiro, é importante garantir que você entenda as seguintes funções do PHP (todas elas estão bem definidas no manual do PHP):
- desserializar. Cria um valor PHP de uma representação armazenada.
- sprintf. Retorna uma string formatada
- forte. Obter comprimento da string
- strstr. Encontre a primeira ocorrência de uma string.
- serializar. Gera uma representação armazenável de um valor.
Então, sim, a instância de entrada da classe é recuperada e depois convertida como o tipo especificado, mas como as funções acima desempenham um papel nisso? Tem a ver com como uma classe é serializada no banco de dados do WordPress.
Tomemos por exemplo a seguinte string:
O:17:"AcmeModelProduct":8:{s:25:"�AcmeModelProduct�number";s:3:"532";s:23:"�AcmeModelProduct�name";s:23:"Aura Bath & Spa - Matte";s:27:"�AcmeModelProduct�longName";s:56:"Aura Bath & Spa Waterborne Interior Paint - Matte Finish";s:22:"�AcmeModelProduct�url";s:37:"http://www.benjaminmoore.com/aura_532";s:27:"�AcmeModelProduct�shortUrl";s:9:"/aura_532";s:26:"�AcmeModelProduct�image1x";s:153:"www2.benjaminmoore.com/ShowPropertyServlet?nodePath=/BEA Repository/imagerepository/public_site/product_images_new/IA_pri_0532//image_88x86.content_en_US";s:26:"�AcmeModelProduct�image2x";s:155:"www2.benjaminmoore.com/ShowPropertyServlet?nodePath=/BEA Repository/imagerepository/public_site/product_images_new/IA_pri_0532//image_197x193.content_en_US";s:26:"�AcmeModelProduct�image3x";s:155:"www2.benjaminmoore.com/ShowPropertyServlet?nodePath=/BEA Repository/imagerepository/public_site/product_images_new/IA_pri_0532//image_197x193.content_en_US";}
Eu sei – não é exatamente um prazer revisar, mas é exatamente como o WordPress serializa um objeto. Além disso, quando é recuperado do banco de dados, é feito e retornado como uma instância stdClass, não como uma instância do tipo que era antes de ser salva.
É aí que a função acima entra em jogo. Para restaurá-lo ao seu tipo de negócio, convém convertê-lo como tal. E para fazer isso, você pode simplesmente fazer o seguinte:
<?php
$exampleObject = get_option('acmeModelProject', null);
if (null === $exampleObject) {
return;
}
$exampleObject = $this->cast($exampleObject, 'AcmeModelProduct');
Observe que estou recuperando um objeto que foi serializado na tabela de opções. Eu não estou argumentando se você deve fazer isso ou não, isso é para fins de exemplo.
Em segundo lugar, observe que estou chamando cast em uma instância de $this para que $this possa ser uma instância de uma classe ou um método na classe base. Não importa (desde que o último esteja marcado como protegido ).
A partir daí, agora você tem uma instância da classe que você salvou originalmente com todas as informações disponíveis para você como estavam quando você a salvou pela primeira vez.