{"id":230226,"date":"2022-12-07T10:55:00","date_gmt":"2022-12-07T07:55:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=230226"},"modified":"2022-11-09T20:41:04","modified_gmt":"2022-11-09T17:41:04","slug":"prosty-sposob-na-rzutowanie-standardowej-klasy-php-na-okreslony-typ","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/pl\/prosty-sposob-na-rzutowanie-standardowej-klasy-php-na-okreslony-typ\/","title":{"rendered":"Prosty spos\u00f3b na rzutowanie standardowej klasy PHP na okre\u015blony typ"},"content":{"rendered":"\n<p>Je\u015bli pracujesz z obiektowym PHP w WordPressie i budujesz r\u00f3\u017cne modele, kt\u00f3re pasuj\u0105 do twoich aplikacji internetowych, istnieje prawdopodobie\u0144stwo, \u017ce b\u0119dziesz mia\u0142 do czynienia z pobieraniem zserializowanych wersji tych modeli w pewnym momencie podczas wykonywania programu.<\/p>\n<p>Oto jednak rzecz: Czasami te niezserializowane dane wracaj\u0105 jako standardowe klasy PHP. Oznacza to, \u017ce je\u015bli sprawdzisz typ (za pomoc\u0105 r\u00f3\u017cnych narz\u0119dzi do debugowania), zobaczysz, \u017ce jest to typ <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>Je\u015bli poprawnie zbudowa\u0142e\u015b te modele, tw\u00f3j kod b\u0119dzie zawiera\u0142 funkcje, kt\u00f3rych nie ma <strong>klasa stdClass<\/strong> i b\u0119dziesz chcia\u0142 je wywo\u0142a\u0107.<\/p>\n<p>Co wi\u0119cej, nie mo\u017cesz po prostu rzutowa\u0107 ich z jednego typu na inny, tak jak w przypadku typ\u00f3w natywnych (takich jak \u0142a\u0144cuchy, liczby ca\u0142kowite itd.). W takich sytuacjach musisz by\u0107 w stanie rzutowa\u0107 standardow\u0105 klas\u0119 PHP na okre\u015blony typ.<\/p>\n<p>A oto funkcja, kt\u00f3ra Ci w tym pomo\u017ce.<\/p>\n<h2>Rzutuj klas\u0119 standardow\u0105 PHP na okre\u015blony typ<\/h2>\n<p>W tym przyk\u0142adzie za\u0142\u00f3\u017cmy, \u017ce:<\/p>\n<ol>\n<li>Mam klas\u0119, kt\u00f3ra znajduje si\u0119 w przestrzeni nazw jako <strong>AcmeModelProduct<\/strong>.<\/li>\n<li>W pewnym momencie jest zapisywany w bazie danych WordPressa, ale po pobraniu jest ustawiany jako instancja <strong>stdClass<\/strong>.<\/li>\n<li>Potrzebuj\u0119, aby nieserializowana wersja obiektu by\u0142a wersj\u0105 <strong>Product<\/strong>.<\/li>\n<\/ol>\n<p>W tym celu mam do dyspozycji nast\u0119puj\u0105c\u0105 funkcj\u0119, kt\u00f3r\u0105 wrzucam do projekt\u00f3w <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\">, gdy tego potrzebuj\u0119:<\/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>Jasne, funkcja jest skomentowana tak szczeg\u00f3\u0142owo, jak mog\u0119 poda\u0107, ale jest kilka rzeczy, kt\u00f3re mog\u0119 wyja\u015bni\u0107 nieco dok\u0142adniej w kontek\u015bcie postu ni\u017c w kontek\u015bcie komentarza do kodu.<\/p>\n<h3>Zrozumienie Kodeksu<\/h3>\n<p>Po pierwsze, wa\u017cne jest, aby upewni\u0107 si\u0119, \u017ce rozumiesz nast\u0119puj\u0105ce funkcje PHP (wszystkie s\u0105 dobrze zdefiniowane w podr\u0119czniku 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\">unserializowa\u0107<\/a>. Tworzy warto\u015b\u0107 PHP z przechowywanej reprezentacji.<\/li>\n<li><a href=\"https:\/\/php.net\/manual\/en\/function.sprintf.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">sprintf<\/a>. Zwr\u00f3\u0107 sformatowany ci\u0105g<\/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>. Uzyskaj d\u0142ugo\u015b\u0107 ci\u0105gu<\/li>\n<li><a href=\"https:\/\/php.net\/manual\/en\/function.strstr.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">strstr<\/a>. Znajd\u017a pierwsze wyst\u0105pienie ci\u0105gu.<\/li>\n<li><a href=\"https:\/\/php.net\/manual\/en\/function.serialize.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">serializowa\u0107<\/a>. Generuje mo\u017cliw\u0105 do przechowywania reprezentacj\u0119 warto\u015bci.<\/li>\n<\/ul>\n<p>Wi\u0119c tak, przychodz\u0105ca instancja klasy jest pobierana, a nast\u0119pnie rzutowana jako okre\u015blony typ, ale jak powy\u017csze funkcje odgrywaj\u0105 w tym rol\u0119? Ma to zwi\u0105zek ze sposobem serializacji klasy w bazie danych WordPress.<\/p>\n<p>We\u017amy na przyk\u0142ad <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/49aae6f2d029b369b2c4bdb35c7b8107#file-01-serialized-data-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">nast\u0119puj\u0105cy ci\u0105g:<\/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>Wiem \u2013 przegl\u0105danie nie jest przyjemno\u015bci\u0105, ale dok\u0142adnie tak WordPress serializuje obiekt. Ponadto, gdy jest pobierany z bazy danych, jest to robione, a nast\u0119pnie zwracane jako instancja <strong>stdClass<\/strong>, a nie jako instancja typu, w kt\u00f3rym by\u0142a przed zapisaniem.<\/p>\n<p>W tym miejscu w gr\u0119 wchodzi powy\u017csza funkcja. Aby przywr\u00f3ci\u0107 go do jego typu transakcji, musisz go przes\u0142a\u0107 jako taki. Aby to zrobi\u0107, mo\u017cesz po prostu wykona\u0107 nast\u0119puj\u0105ce czynno\u015bci:<\/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>Zauwa\u017c, \u017ce pobieram obiekt, kt\u00f3ry zosta\u0142 zserializowany do tabeli opcji. Nie zastanawiam si\u0119, czy powiniene\u015b to zrobi\u0107, czy nie, to jest na przyk\u0142ad w celach.<\/p>\n<p>Po drugie, zauwa\u017c, \u017ce wywo\u0142uj\u0119 <strong>rzutowanie<\/strong> na instancj\u0119 <strong>$this<\/strong>, wi\u0119c <strong>$this<\/strong> mo\u017ce by\u0107 instancj\u0105 klasy lub mo\u017ce by\u0107 metod\u0105 w klasie bazowej. Nie ma to znaczenia (o ile ten ostatni jest oznaczony jako <strong>chroniony<\/strong> ).<\/p>\n<p>Stamt\u0105d masz teraz instancj\u0119 klasy, kt\u00f3r\u0105 pierwotnie zapisa\u0142e\u015b, ze wszystkimi dost\u0119pnymi dla ciebie informacjami, tak jak podczas pierwszego zapisania.<\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">\u0179r\u00f3d\u0142o nagrywania:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/tommcfarlin.com\" class=\"external external_icon\">tommcfarlin.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Nie mo\u017cesz po prostu rzutowa\u0107 ich z jednego typu na inny, tak jak w przypadku typ\u00f3w natywnych (takich jak ci\u0105gi, liczby ca\u0142kowite itd.). W takich sytuacjach musisz by\u0107 w stanie rzutowa\u0107 standardow\u0105 klas\u0119 PHP na okre\u015blony typ.<\/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":[805],"tags":[1169],"class_list":["post-230226","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-php-7","tag-affiai-pl"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/posts\/230226","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/comments?post=230226"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/posts\/230226\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/media\/236170"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/media?parent=230226"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/categories?post=230226"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/tags?post=230226"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}