{"id":644,"date":"2016-04-27T13:08:07","date_gmt":"2016-04-27T16:08:07","guid":{"rendered":"https:\/\/blog.umbler.com\/?p=644"},"modified":"2018-12-06T10:55:55","modified_gmt":"2018-12-06T12:55:55","slug":"php-7-type-hints","status":"publish","type":"post","link":"https:\/\/blog.umbler.com\/br\/php-7-type-hints\/","title":{"rendered":"#4 PHP 7 &#8211; Type Hints"},"content":{"rendered":"<p>Como se sabe, o PHP \u00e9 uma linguagem fracamente tipada, que n\u00e3o se preocupa muito com os tipos de dados. Uma mesma vari\u00e1vel pode receber valores diferentes a qualquer momento. Uma hora ela pode ser string, duas linhas depois se tornar um array e por a\u00ed vai.<\/p>\n<p>O PHP 7 introduziu recursos de tipagem, que v\u00e3o permitir definir o tipo de valor que uma vari\u00e1vel vai receber, checando se o valor recebido \u00e9 compat\u00edvel com o tipo de valor especificado para a vari\u00e1vel ou at\u00e9 mesmo o tipo de dados que uma fun\u00e7\u00e3o ir\u00e1 retornar.<\/p>\n<p>No PHP 5 esse recurso ja funcionava, mas, somente com arrays e objetos, no PHP 7 adicionaram o suporte a <strong>float<\/strong>, <strong>int<\/strong>, <strong>string<\/strong> e <strong>boolean<\/strong>.<br \/>\nPara que a verifica\u00e7\u00e3o do tipo de dado funcione \u00e9 preciso ativa-l\u00e1 atrav\u00e9s da op\u00e7\u00e3o <code>strict_types<\/code>, que deve estar ativa.<\/p>\n<pre class=\"code-highlighter line-numbers theme-dark\"><code class=\"language-php\">declare(strict_types=1);<\/code><\/pre>\n<p>A seguir temos um c\u00f3digo de uma fun\u00e7\u00e3o que imprime um texto na tela a partir de um valor passado como par\u00e2metro. Esse valor deve ser uma string, e, caso n\u00e3o seja, ser\u00e1 retornado um erro do tipo <em><strong>&#8220;Uncaught TypeError&#8221;<\/strong><\/em>, ao inv\u00e9s de imprimir o valor na tela.<\/p>\n<pre class=\"code-highlighter line-numbers theme-dark\"><code class=\"language-php\">declare(strict_types=1);\r\nfunction ShowText(string $text){\r\n  echo 'The variable is: ' . $text;\r\n}\r\nShowText(\"Type Hints PHP 7\");<\/code><\/pre>\n<p>Na primeira linha ativamos a verifica\u00e7\u00e3o de tipos, em seguida criamos a fun\u00e7\u00e3o, e logo depois chamamos a execu\u00e7\u00e3o da fun\u00e7\u00e3o.<\/p>\n<p>Repare que na declara\u00e7\u00e3o da fun\u00e7\u00e3o a vari\u00e1vel recebeu o tipo de dado antes de ser declarada: <code>string $text<\/code>. Se o tipo n\u00e3o tivesse sido informado, ela aceitaria qualquer valor e n\u00e3o retornaria nenhum erro do tipo <em><strong>&#8220;Uncaught TypeError<\/strong><\/em>&#8220;.<\/p>\n<p>Al\u00e9m do PHP fazer a valida\u00e7\u00e3o do valor passado para a vari\u00e1vel, ele tamb\u00e9m faz uma tentativa de convers\u00e3o do valor passado para o tipo especificado, o que chamamos de <em><strong>&#8220;Coercive Type Hints&#8221;<\/strong><\/em>.<\/p>\n<p>Veja no exemplo abaixo que a fun\u00e7\u00e3o vai receber 2 par\u00e2metros, um inteiro e uma string, e mesmo passando a vari\u00e1vel que deveria ser um n\u00famero inteiro como string, n\u00e3o ser\u00e1 retornado um erro do tipo <strong><em>&#8220;Uncaught TypeError&#8221;<\/em><\/strong>, pois o PHP vai converter a string em inteiro.<\/p>\n<pre class=\"code-highlighter line-numbers theme-dark\"><code class=\"language-php\">function SendMessage(int $code, string $message)\r\n{\r\n    echo $code. ' - ' .$message;\r\n}\u2028\r\nSendMessage(404, \"File Not Found\");\r\nSendMessage(\"200\", \"OK\");\u2028<\/code><\/pre>\n<p>Veja bem que na primeira chamada da fun\u00e7\u00e3o <strong><em>&#8220;SendMessage&#8221;<\/em><\/strong> os valores das vari\u00e1veis foram passados corretamente, mas na segunda as duas vari\u00e1veis foram passadas como string. Devendo a primeira vari\u00e1vel ser um n\u00famero inteiro, o PHP tentou fazer a convers\u00e3o, e, como ela foi bem sucedida, n\u00e3o foi retornado nenhum erro.<br \/>\nEssa convers\u00e3o pode causar perda de precis\u00e3o nos dados e at\u00e9 mesmo a perda de dados. Veja um exemplo onde os par\u00e2metros devem ser n\u00famero inteiros (int), mas os valores passados s\u00e3o decimais (float).<\/p>\n<pre class=\"code-highlighter line-numbers theme-dark\"><code class=\"language-php\">function Sum(int $x, int $y)\r\n{\r\n    return $x + $y;\r\n}\r\nadd(97.234, 61.53);<\/code><\/pre>\n<p>Como o tipo de vari\u00e1vel foi definido como int, o PHP vai tentar fazer a convers\u00e3o, logo os valores deixar\u00e3o de ser 97.234 e 61.53 para ser 97 e 61, respectivamente. O valor retornado ent\u00e3o n\u00e3o ser\u00e1 158.764, mas sim 158.<\/p>\n<h2>Return Type Hints<\/h2>\n<p>Assim como \u00e9 poss\u00edvel determinar o tipo de valor das vari\u00e1veis e par\u00e2metros de uma fun\u00e7\u00e3o, tamb\u00e9m \u00e9 poss\u00edvel determinar o tipo de valor retornado por uma fun\u00e7\u00e3o. A regra \u00e9 a mesma da apresentada acima para as vari\u00e1veis e par\u00e2metros, mudando somente a sintaxe de escrita da fun\u00e7\u00e3o.<\/p>\n<pre class=\"code-highlighter line-numbers theme-dark\"><code class=\"language-php\">function Divide(int $x, int $y): int {\r\n  return $x \/ $y;\r\n}\r\nDivide(6,3);\r\nDivide(8,3);<\/code><\/pre>\n<p>A fun\u00e7\u00e3o acima simplesmente retorna o valor da divis\u00e3o entre 2 n\u00famero inteiros, sendo que o retorno deve ser um n\u00famero inteiro.<\/p>\n<p>Duas chamadas \u00e0 fun\u00e7\u00e3o Divide foram feitas, na primeira s\u00e3o passados os valores 6 e 3, que dividos d\u00e3o 2, um valor inteiro que corresponde ao tipo de valor que a fun\u00e7\u00e3o deve retornar. J\u00e1 a segunda chamada, que usou os valores 8 e 3, vai retornar um erro, pois o valor da divis\u00e3o n\u00e3o inteiro, e sim um float (2,66666667).<\/p>\n<h2>Conclus\u00e3o<\/h2>\n<p>Mesmo com essa implementa\u00e7\u00e3o de tipagem de dados, ainda h\u00e1 um n\u00edvel de inconsist\u00eancia e perda de informa\u00e7\u00e3o, mas de qualquer forma j\u00e1 \u00e9 uma evolu\u00e7\u00e3o. Vamos aguardar e ver o que futuras vers\u00f5es do PHP trar\u00e3o de novidades e maior consist\u00eancia em rela\u00e7\u00e3o a tipagem de dados.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Como se sabe, o PHP \u00e9 uma linguagem fracamente tipada, que n\u00e3o se preocupa muito com os tipos de dados. Uma mesma vari\u00e1vel pode receber valores diferentes a qualquer momento. Uma hora ela pode ser string, duas linhas depois se tornar um array e por a\u00ed vai. O PHP 7 introduziu recursos de tipagem, que [&hellip;]<\/p>\n","protected":false},"author":37,"featured_media":5612,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3,23],"tags":[57,80,81],"class_list":["post-644","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-comunidade","category-dev","tag-php-7","tag-tipagem-de-dados","tag-type-hints"],"_links":{"self":[{"href":"https:\/\/blog.umbler.com\/br\/wp-json\/wp\/v2\/posts\/644"}],"collection":[{"href":"https:\/\/blog.umbler.com\/br\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.umbler.com\/br\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.umbler.com\/br\/wp-json\/wp\/v2\/users\/37"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.umbler.com\/br\/wp-json\/wp\/v2\/comments?post=644"}],"version-history":[{"count":0,"href":"https:\/\/blog.umbler.com\/br\/wp-json\/wp\/v2\/posts\/644\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.umbler.com\/br\/wp-json\/wp\/v2\/media\/5612"}],"wp:attachment":[{"href":"https:\/\/blog.umbler.com\/br\/wp-json\/wp\/v2\/media?parent=644"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.umbler.com\/br\/wp-json\/wp\/v2\/categories?post=644"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.umbler.com\/br\/wp-json\/wp\/v2\/tags?post=644"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}