Un modo semplice per trasmettere una classe standard PHP a un tipo specifico
Se lavori con PHP orientato agli oggetti in WordPress e stai costruendo vari modelli che si adattano alle tue applicazioni web, è probabile che tu abbia a che fare con il recupero di versioni serializzate di quei modelli a un certo punto durante l’esecuzione di un programma.
Ecco la cosa, però: a volte, quei dati non serializzati ritornano come classi PHP standard. Ciò significa che se ispezioni il tipo (attraverso vari strumenti di debug), vedrai che sono del tipo stdClass.
Se hai costruito correttamente i tuoi modelli, il tuo codice avrà funzioni che stdClass non ha e vorrai chiamarle.
Inoltre, non puoi semplicemente eseguirne il cast da un tipo all’altro come puoi fare con i tipi nativi (come stringhe, numeri interi e così via). In situazioni del genere, devi essere in grado di eseguire il cast di una classe standard PHP su un tipo specifico.
Ed ecco una funzione che ti aiuterà a fare proprio questo.
Trasmetti a PHP una classe standard in un tipo specifico
Per questo esempio, supponiamo quanto segue:
- Ho una classe con namespace come AcmeModelProduct.
- Ad un certo punto, viene salvato nel database di WordPress ma quando viene recuperato viene impostato come un’istanza di stdClass.
- Ho bisogno che la versione non serializzata dell’oggetto sia quella del Prodotto.
A tal fine, ho la seguente funzione disponibile che inserisco nei progetti quando ne ho bisogno:
<?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), '"'), ':')
));
}
Certo, la funzione è commentata con tutti i dettagli che posso fornire, ma ci sono alcune cose che posso spiegare un po’ più in dettaglio nel contesto di un post rispetto a quanto posso nel contesto di un commento al codice.
Capire il codice
Innanzitutto, è importante assicurarsi di aver compreso le seguenti funzioni PHP (tutte ben definite nel manuale PHP):
- deserializzare. Crea un valore PHP da una rappresentazione archiviata.
- sprintf. Restituisce una stringa formattata
- strlen. Ottieni la lunghezza della stringa
- str. Trova la prima occorrenza di una stringa.
- serializzare. Genera una rappresentazione memorizzabile di un valore.
Quindi, sì, l’istanza in entrata della classe viene recuperata e quindi lanciata come tipo specificato, ma in che modo le funzioni precedenti svolgono un ruolo in questo? Ha a che fare con il modo in cui una classe viene serializzata nel database di WordPress.
Prendi ad esempio la seguente stringa:
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";}
Lo so: non è esattamente un piacere da recensire, ma è esattamente il modo in cui WordPress serializza un oggetto. Inoltre, quando viene recuperato dal database, viene eseguito e quindi restituito come istanza stdClass, non come un’istanza del tipo che era prima del salvataggio.
È qui che entra in gioco la funzione di cui sopra. Per ripristinarlo al suo tipo di offerta, ti consigliamo di lanciarlo come tale. E per farlo, puoi semplicemente fare quanto segue:
<?php
$exampleObject = get_option('acmeModelProject', null);
if (null === $exampleObject) {
return;
}
$exampleObject = $this->cast($exampleObject, 'AcmeModelProduct');
Nota che sto recuperando un oggetto che è stato serializzato nella tabella delle opzioni. Non sto discutendo se dovresti farlo o meno, questo è a scopo di esempio.
In secondo luogo, nota che sto chiamando cast su un’istanza di $this quindi $this potrebbe essere un’istanza di una classe o potrebbe essere un metodo nella classe base. Non importa (purché quest’ultimo sia contrassegnato come protetto ).
Da lì, ora hai un’istanza della classe che hai salvato originariamente con tutte le informazioni a tua disposizione com’era quando l’hai salvata per la prima volta.