{"id":231076,"date":"2022-12-07T10:21:00","date_gmt":"2022-12-07T07:21:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=231076"},"modified":"2022-11-10T01:49:20","modified_gmt":"2022-11-09T22:49:20","slug":"un-modo-semplice-per-trasmettere-una-classe-standard-php-a-un-tipo-specifico","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/it\/un-modo-semplice-per-trasmettere-una-classe-standard-php-a-un-tipo-specifico\/","title":{"rendered":"Un modo semplice per trasmettere una classe standard PHP a un tipo specifico"},"content":{"rendered":"\n<p>Se lavori con PHP orientato agli oggetti in WordPress e stai costruendo vari modelli che si adattano alle tue applicazioni web, \u00e8 probabile che tu abbia a che fare con il recupero di versioni serializzate di quei modelli a un certo punto durante l&#8217;esecuzione di un programma.<\/p>\n<p>Ecco la cosa, per\u00f2: a volte, quei dati non serializzati ritornano come classi PHP standard. Ci\u00f2 significa che se ispezioni il tipo (attraverso vari strumenti di debug), vedrai che sono del tipo <a href=\"https:\/\/php.net\/manual\/en\/language.types.object.php#language.types.object.casting\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">stdClass<\/a>.<\/p>\n<p>Se hai costruito correttamente i tuoi modelli, il tuo codice avr\u00e0 funzioni che <strong>stdClass<\/strong> non ha e vorrai chiamarle.<\/p>\n<p>Inoltre, non puoi semplicemente eseguirne il cast da un tipo all&#8217;altro come puoi fare con i tipi nativi (come stringhe, numeri interi e cos\u00ec via). In situazioni del genere, devi essere in grado di eseguire il cast di una classe standard PHP su un tipo specifico.<\/p>\n<p>Ed ecco una funzione che ti aiuter\u00e0 a fare proprio questo.<\/p>\n<h2>Trasmetti a PHP una classe standard in un tipo specifico<\/h2>\n<p>Per questo esempio, supponiamo quanto segue:<\/p>\n<ol>\n<li>Ho una classe con namespace come <strong>AcmeModelProduct<\/strong>.<\/li>\n<li>Ad un certo punto, viene salvato nel database di WordPress ma quando viene recuperato viene impostato come un&#8217;istanza di <strong>stdClass<\/strong>.<\/li>\n<li>Ho bisogno che la versione non serializzata dell&#8217;oggetto sia quella del <strong>Prodotto<\/strong>.<\/li>\n<\/ol>\n<p>A tal fine, ho la seguente funzione disponibile che inserisco nei progetti <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/49aae6f2d029b369b2c4bdb35c7b8107#file-00-cast-class-to-type-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">quando ne ho bisogno:<\/a><\/strong><\/p>\n<pre><code>&lt;?php\n\/**\n * This function will take an instance of a PHP stdClass and attempt to cast it to\n * the type of the specified $className.\n *\n * For example, we may pass 'AcmeModelProduct' as the $className.\n *\n * @param object $instance  an instance of the stdClass to convert\n * @param string $className the name of the class type to which we want to cals\n *\n * @return mixed a version of the incoming $instance casted as the specified className\n *\/\nprotected function cast($instance, $className)\n{\n    return unserialize(sprintf(\n        'O:%d:\"%s\"%s',\n        strlen($className),\n        $className,\n        strstr(strstr(serialize($instance), '\"'), ':')\n    ));\n}\n<\/code><\/pre>\n<p>Certo, la funzione \u00e8 commentata con tutti i dettagli che posso fornire, ma ci sono alcune cose che posso spiegare un po&#8217; pi\u00f9 in dettaglio nel contesto di un post rispetto a quanto posso nel contesto di un commento al codice.<\/p>\n<h3>Capire il codice<\/h3>\n<p>Innanzitutto, \u00e8 importante assicurarsi di aver compreso le seguenti funzioni PHP (tutte ben definite nel manuale PHP):<\/p>\n<ul>\n<li><a href=\"https:\/\/php.net\/manual\/en\/function.unserialize.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">deserializzare<\/a>. Crea un valore PHP da una rappresentazione archiviata.<\/li>\n<li><a href=\"https:\/\/php.net\/manual\/en\/function.sprintf.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">sprintf<\/a>. Restituisce una stringa formattata<\/li>\n<li><strong><a href=\"https:\/\/php.net\/manual\/en\/function.sprintf.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">strlen<\/a><\/strong>. Ottieni la lunghezza della stringa<\/li>\n<li><a href=\"https:\/\/php.net\/manual\/en\/function.strstr.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">str<\/a>. Trova la prima occorrenza di una stringa.<\/li>\n<li><a href=\"https:\/\/php.net\/manual\/en\/function.serialize.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">serializzare<\/a>. Genera una rappresentazione memorizzabile di un valore.<\/li>\n<\/ul>\n<p>Quindi, s\u00ec, l&#8217;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.<\/p>\n<p>Prendi ad esempio la <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/49aae6f2d029b369b2c4bdb35c7b8107#file-01-serialized-data-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">seguente stringa:<\/a><\/strong><\/p>\n<pre><code>O:17:\"AcmeModelProduct\":8:{s:25:\"\ufffdAcmeModelProduct\ufffdnumber\";s:3:\"532\";s:23:\"\ufffdAcmeModelProduct\ufffdname\";s:23:\"Aura Bath &amp; Spa - Matte\";s:27:\"\ufffdAcmeModelProduct\ufffdlongName\";s:56:\"Aura Bath &amp; Spa Waterborne Interior Paint - Matte Finish\";s:22:\"\ufffdAcmeModelProduct\ufffdurl\";s:37:\"http:\/\/www.benjaminmoore.com\/aura_532\";s:27:\"\ufffdAcmeModelProduct\ufffdshortUrl\";s:9:\"\/aura_532\";s:26:\"\ufffdAcmeModelProduct\ufffdimage1x\";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:\"\ufffdAcmeModelProduct\ufffdimage2x\";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:\"\ufffdAcmeModelProduct\ufffdimage3x\";s:155:\"www2.benjaminmoore.com\/ShowPropertyServlet?nodePath=\/BEA Repository\/imagerepository\/public_site\/product_images_new\/IA_pri_0532\/\/image_197x193.content_en_US\";}<\/code><\/pre>\n<p>Lo so: non \u00e8 esattamente un piacere da recensire, ma \u00e8 esattamente il modo in cui WordPress serializza un oggetto. Inoltre, quando viene recuperato dal database, viene eseguito e quindi restituito come istanza <strong>stdClass<\/strong>, non come un&#8217;istanza del tipo che era prima del salvataggio.<\/p>\n<p>\u00c8 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:<\/p>\n<pre><code>&lt;?php\n$exampleObject = get_option('acmeModelProject', null);\nif (null === $exampleObject) {\n  return;\n}\n\n$exampleObject = $this-&gt;cast($exampleObject, 'AcmeModelProduct');\n<\/code><\/pre>\n<p>Nota che sto recuperando un oggetto che \u00e8 stato serializzato nella tabella delle opzioni. Non sto discutendo se dovresti farlo o meno, questo \u00e8 a scopo di esempio.<\/p>\n<p>In secondo luogo, nota che sto chiamando <strong>cast<\/strong> su un&#8217;istanza di <strong>$this<\/strong> quindi <strong>$this<\/strong> potrebbe essere un&#8217;istanza di una classe o potrebbe essere un metodo nella classe base. Non importa (purch\u00e9 quest&#8217;ultimo sia contrassegnato come <strong>protetto<\/strong> ).<\/p>\n<p>Da l\u00ec, ora hai un&#8217;istanza della classe che hai salvato originariamente con tutte le informazioni a tua disposizione com&#8217;era quando l&#8217;hai salvata per la prima volta.<\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">Fonte di registrazione:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/tommcfarlin.com\" class=\"external external_icon\">tommcfarlin.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Non puoi semplicemente trasmetterli da un tipo all&#8217;altro come puoi fare con i tipi nativi (come stringhe, numeri interi e cos\u00ec via). In situazioni del genere, devi essere in grado di eseguire il cast di una classe standard PHP su un tipo specifico.<\/p>\n","protected":false},"author":1,"featured_media":236170,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[804],"tags":[1168],"class_list":["post-231076","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-php-6","tag-affiai-it"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/posts\/231076","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/comments?post=231076"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/posts\/231076\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/media\/236170"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/media?parent=231076"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/categories?post=231076"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/tags?post=231076"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}