{"id":230504,"date":"2022-12-07T10:52:00","date_gmt":"2022-12-07T07:52:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=230504"},"modified":"2022-11-09T22:41:06","modified_gmt":"2022-11-09T19:41:06","slug":"una-manera-facil-de-convertir-una-clase-estandar-de-php-en-un-tipo-especifico","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/es\/una-manera-facil-de-convertir-una-clase-estandar-de-php-en-un-tipo-especifico\/","title":{"rendered":"Una manera f\u00e1cil de convertir una clase est\u00e1ndar de PHP en un tipo espec\u00edfico"},"content":{"rendered":"\n<p>Si trabaja con PHP orientado a objetos en WordPress y est\u00e1 creando varios modelos que se adaptan a sus aplicaciones web, lo m\u00e1s probable es que se enfrente a la recuperaci\u00f3n de versiones serializadas de esos modelos en alg\u00fan momento durante la ejecuci\u00f3n de un programa.<\/p>\n<p>Sin embargo, aqu\u00ed est\u00e1 la cosa: a veces, los datos no serializados regresan como clases est\u00e1ndar de PHP. Esto significa que si inspecciona el tipo (a trav\u00e9s de varias herramientas de depuraci\u00f3n), ver\u00e1 que son del tipo de <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>Si ha estado construyendo correctamente sus modelos, su c\u00f3digo tendr\u00e1 funciones que <strong>stdClass<\/strong> no tiene, y querr\u00e1 llamarlas.<\/p>\n<p>Adem\u00e1s, no puede simplemente convertirlos de un tipo a otro como puede hacerlo con los tipos nativos (como cadenas, enteros, etc.). En situaciones como esa, debe poder convertir una clase est\u00e1ndar de PHP en un tipo espec\u00edfico.<\/p>\n<p>Y aqu\u00ed hay una funci\u00f3n que te ayudar\u00e1 a hacer precisamente eso.<\/p>\n<h2>Transmitir una clase est\u00e1ndar de PHP a un tipo espec\u00edfico<\/h2>\n<p>Para este ejemplo, suponga lo siguiente:<\/p>\n<ol>\n<li>Tengo una clase que tiene un espacio de nombres como <strong>AcmeModelProduct<\/strong>.<\/li>\n<li>En alg\u00fan momento, se guarda en la base de datos de WordPress, pero cuando se recupera se establece como una instancia de <strong>stdClass<\/strong>.<\/li>\n<li>Necesito que la versi\u00f3n no serializada del objeto sea la del <strong>Producto<\/strong>.<\/li>\n<\/ol>\n<p>Con ese fin, tengo disponible la siguiente funci\u00f3n que coloco en los proyectos <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\">cuando la necesito:<\/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>Claro, la funci\u00f3n se comenta con tanto detalle como puedo proporcionar, pero hay algunas cosas que puedo explicar un poco m\u00e1s en el contexto de una publicaci\u00f3n que en el contexto de un comentario de c\u00f3digo.<\/p>\n<h3>Comprender el c\u00f3digo<\/h3>\n<p>Primero, es importante asegurarse de comprender las siguientes funciones de PHP (todas bien definidas en el manual de 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\">deserializar<\/a> _ Crea un valor PHP a partir de una representaci\u00f3n almacenada.<\/li>\n<li><a href=\"https:\/\/php.net\/manual\/en\/function.sprintf.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">sprintf<\/a>. Devolver una cadena formateada<\/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> _ Obtener longitud de cadena<\/li>\n<li><a href=\"https:\/\/php.net\/manual\/en\/function.strstr.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">callestr<\/a>. Encuentra la primera aparici\u00f3n de una cadena.<\/li>\n<li><a href=\"https:\/\/php.net\/manual\/en\/function.serialize.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">serializar<\/a> _ Genera una representaci\u00f3n almacenable de un valor.<\/li>\n<\/ul>\n<p>Entonces, s\u00ed, la instancia entrante de la clase se recupera y luego se convierte en el tipo especificado, pero \u00bfc\u00f3mo juegan un papel las funciones anteriores en esto? Tiene que ver con c\u00f3mo se serializa una clase en la base de datos de WordPress.<\/p>\n<p>Tomemos por ejemplo la <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/49aae6f2d029b369b2c4bdb35c7b8107#file-01-serialized-data-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">siguiente cadena:<\/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 s\u00e9, no es exactamente un placer revisarlo, pero es exactamente c\u00f3mo WordPress serializa un objeto. Adem\u00e1s, cuando se recupera de la base de datos, se hace y luego se devuelve como una instancia de <strong>stdClass<\/strong>, no como una instancia del tipo que era antes de que se guardara.<\/p>\n<p>Ah\u00ed es donde entra en juego la funci\u00f3n anterior. Para restaurarlo a su tipo de trato, querr\u00e1 emitirlo como tal. Y para hacer eso, simplemente puede hacer lo siguiente:<\/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>Tenga en cuenta que estoy recuperando un objeto que se ha serializado en la tabla de opciones. No estoy argumentando si debe hacer esto o no, esto es para fines de ejemplo.<\/p>\n<p>En segundo lugar, tenga en cuenta que estoy llamando a <strong>emitir<\/strong> en una instancia de <strong>$this<\/strong>, por lo que <strong>$this<\/strong> podr\u00eda ser una instancia de una clase o podr\u00eda ser un m\u00e9todo en la clase base. No importa (siempre y cuando este \u00faltimo est\u00e9 marcado como <strong>protected<\/strong> ).<\/p>\n<p>A partir de ah\u00ed, ahora tiene una instancia de la clase que guard\u00f3 originalmente con toda la informaci\u00f3n disponible como cuando la guard\u00f3 por primera vez.<\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">Fuente de grabaci\u00f3n:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/tommcfarlin.com\" class=\"external external_icon\">tommcfarlin.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>No puede simplemente convertirlos de un tipo a otro como puede hacerlo con los tipos nativos (como cadenas, enteros, etc.). En situaciones como esa, debe poder convertir una clase est\u00e1ndar de PHP en un tipo espec\u00edfico.<\/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":[800],"tags":[1172],"class_list":["post-230504","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-php-2","tag-affiai-es"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/posts\/230504","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/comments?post=230504"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/posts\/230504\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/media\/236170"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/media?parent=230504"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/categories?post=230504"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/tags?post=230504"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}