{"id":674,"date":"2016-05-20T10:07:12","date_gmt":"2016-05-20T13:07:12","guid":{"rendered":"https:\/\/blog.umbler.com\/?p=674"},"modified":"2018-12-06T10:51:23","modified_gmt":"2018-12-06T12:51:23","slug":"php-7-error-handling-assertions-expectations","status":"publish","type":"post","link":"https:\/\/blog.umbler.com\/br\/php-7-error-handling-assertions-expectations\/","title":{"rendered":"#5 PHP 7 &#8211; Error Handling, Assertions e Expectations"},"content":{"rendered":"<p>Nesse post, falaremos sobre Error Handling no PHP 7, explicando, primeiramente, os conceitos de Assertions e Expectations.<\/p>\n<h3>Assertions<\/h3>\n<p>Desde o PHP 4 a fun\u00e7\u00e3o <code>'assert()'<\/code> est\u00e1 dispon\u00edvel, e ela serve para adicionar &#8216;sanity-checks&#8217; no c\u00f3digo. Ela deve ser utilizada somente para desenvolvimento, nunca em ambiente de produ\u00e7\u00e3o, e pode ser facilmente ativada e desativada usando <code>'assert_options()'<\/code> ou <code>'assert.active'<\/code> no php.ini.<\/p>\n<p>Para usar assertions voc\u00ea passa uma express\u00e3o ou string como primeiro par\u00e2metro. Veja no c\u00f3digo abaixo um exemplo, e se a express\u00e3o ou string resultar em FALSE, ser\u00e1 retornado um &#8216;warning&#8217;.<\/p>\n<pre class=\"code-highlighter line-numbers theme-dark\"><code class=\"language-php\">assert('$user instanceof \\MyProject\\User');\r\nassert($user instanceof \\MyProject\\User);\r\n<\/code><\/pre>\n<p>O &#8216;warning&#8217; que pode ser retornado \u00e9 algo do tipo:<\/p>\n<pre class=\"code-highlighter line-numbers theme-dark\"><code class=\"language-php\">Warning: assert(): Assertion \"$user instanceof \\MyProject\\User\" failed in  on line \r\n<\/code><\/pre>\n<h3>Expectations<\/h3>\n<p>No PHP 7, o <code>'assert()'<\/code> foi expandido para Expectations RFC, permitindo fazer chamadas a assertions zero-cost, que n\u00e3o geram impactos sobre o desempenho. Com essa mudan\u00e7a, n\u00e3o s\u00f3 \u00e9 poss\u00edvel desativar assertions, mas tamb\u00e9m remover toda a sobrecarga completamente.<\/p>\n<p>Nessa configura\u00e7\u00e3o, assertions n\u00e3o s\u00e3o compiladas, independente da string ou express\u00e3o passadas, portanto, geram um impacto 0 (zero) sobre o desempenho. Isso \u00e9 diferente caso assertions esteja desativada, que vai resultar em express\u00f5es que ainda ser\u00e3o avaliadas, afetando potencialmente a execu\u00e7\u00e3o e ir\u00e1 ignorar a chamada.<\/p>\n<p>Veja abaixo um exemplo de ativa\u00e7\u00e3o de assertions:<\/p>\n<pre class=\"code-highlighter line-numbers theme-dark\"><code class=\"language-php\">\/\/Ativa assertions\r\nzend.assertions  = 1\r\n\/\/Disativa assertions\r\nzend.assertions  = 0\r\n\/\/define zero-coast assertions\r\nzend.assertions  = -1\r\n<\/code><\/pre>\n<h3>Conclus\u00e3o<\/h3>\n<p>Com a adi\u00e7\u00e3o de assertions zero-cost, voc\u00ea finalmente ter\u00e1 uma maneira leve para adicionar sanity-check ao seu c\u00f3digo durante o desenvolvimento, sem afetar a produ\u00e7\u00e3o. Assertions podem ser um primeiro passo no caminho para a adi\u00e7\u00e3o de teste unit\u00e1rios para a sua aplica\u00e7\u00e3o.<\/p>\n<h2>Error Handling<\/h2>\n<p>Desde o PHP 4 que a manipula\u00e7\u00e3o de erros esteve inalterada, exceto pela adi\u00e7\u00e3o de <code>E_STRICT<\/code> no PHP 5, <code>E_RECOVERABLE_ERROR<\/code> no PHP 5.2 e <code>E_DEPRECATED no PHP 5.3<\/code>.<br \/>\nAntes do PHP 7, se uma classe n\u00e3o fosse instanciada corretamente, um valor nulo ou objeto era retornado. Agora, todas as classes v\u00e3o lan\u00e7ar uma exce\u00e7\u00e3o no caso de falha no instanciamento, variando o tipo e a raz\u00e3o da falha.<\/p>\n<pre class=\"code-highlighter line-numbers theme-dark\"><code class=\"language-php\">try {\r\n    new MessageFormatter('pt_BR', null);\r\n} catch (\\IntlException $e) {\r\n}\r\n<\/code><\/pre>\n<p>O fragmento de c\u00f3digo acima vai resultar em uma \\IntlException com a mensagem Contructor failed.<\/p>\n<h3>Engine Exceptions<\/h3>\n<p>Com o PHP 7, quase todos os erros fatais e captur\u00e1veis ser\u00e3o tratados como &#8220;engine exceptions&#8221;. Isso \u00e9 poss\u00edvel porque uma exce\u00e7\u00e3o n\u00e3o capturada ainda resulta em um erro fatal.<br \/>\nCom essa mudan\u00e7a temos alguns benef\u00edcios:<\/p>\n<ul class=\"icon-ul\">\n<li><i class=\"icon icon-li icon-check\"><\/i> <code>Objetos __destruct()<\/code> s\u00e3o chamados<\/li>\n<li><i class=\"icon icon-li icon-check\"><\/i>Callbacks registrados com <code>register_sutdown_function()<\/code> s\u00e3o chamados<\/li>\n<li><i class=\"icon icon-li icon-check\"><\/i>Assim como acontece com todas as exce\u00e7\u00f5es, haver\u00e1 um rastreamento de pilha, tornando-o mais f\u00e1cil a depura\u00e7\u00e3o<\/li>\n<\/ul>\n<h3>Error Exceptions<\/h3>\n<p>O PHP 7 traz novos tipos de &#8220;error exceptions&#8221;, cada uma com um prop\u00f3sito diferente. Vejamos alguns deles.<\/p>\n<h4>\\AssertionError<\/h4>\n<p>Com as melhorias feitas para uso de assertions, se voc\u00ea informa &#8216;assert.exception&#8217; como 1 no php.ini, uma exce\u00e7\u00e3o ser\u00e1 lan\u00e7ada quando a declara\u00e7\u00e3o falhar.<\/p>\n<pre class=\"code-highlighter line-numbers theme-dark\"><code class=\"language-php\">try {\r\n    ini_set('assert.exception', 1);\r\n    assert('true === false', 'Assertion failed');\r\n} catch (\\AssertionError $e) {\r\n}\r\n<\/code><\/pre>\n<p>O c\u00f3digo acima vai resultar em uma exce\u00e7\u00e3o com a mensagem passada como segundo par\u00e2metro para a fun\u00e7\u00e3o <code>'assert()'<\/code>, &#8220;Assertion failed&#8221;.<br \/>\n<em><br \/>\nSe voc\u00ea n\u00e3o informar o segundo par\u00e2metro para a fun\u00e7\u00e3o <code>'assert()'<\/code>, a exce\u00e7\u00e3o \\AssertionError n\u00e3o ter\u00e1 nenhuma mensagem. Ainda sim ser\u00e1 poss\u00edvel obter informa\u00e7\u00f5es como a origem e a informa\u00e7\u00e3o de que a afirma\u00e7\u00e3o falhou.<br \/>\n<\/em><\/p>\n<h4>\\TypeError<\/h4>\n<p>Agora que o PHP permite definir o tipo de vari\u00e1vel e retorno de m\u00e9todos e fun\u00e7\u00f5es, estes tamb\u00e9m lan\u00e7ar\u00e3o exce\u00e7\u00f5es informando sobre os erros.<\/p>\n<pre class=\"code-highlighter line-numbers theme-dark\"><code class=\"language-php\">function example(callable $callback)\r\n{\r\n   return $callback()\r\n}\r\ntry{\r\n  example(new stdClass);\r\n}catch(\\TypeError $e){\r\n}\r\n<\/code><\/pre>\n<p>O c\u00f3digo acima vai resultar em uma exce\u00e7\u00e3o com a mensagem &#8220;Argument 1 passed to example() must be callable object given, called in on line &#8220;, pois foi passado como par\u00e2metro uma classe e n\u00e3o uma fun\u00e7\u00e3o.<\/p>\n<h4>\\ArithmeticError e \\DivisionByZeroError<\/h4>\n<p>Essas duas exce\u00e7\u00f5es foram adicionadas para poder lidar com c\u00e1lculos aritm\u00e9ticos. A primeira, \\ArithmeticError, ser\u00e1 lan\u00e7ada sempre que ocorrer um erro ao executar opera\u00e7\u00f5es matem\u00e1ticas. A segunda, \\DivisionByZeroError, \u00e9 mais espec\u00edfica, e vai ser lan\u00e7ada sempre que houver uam tentativa de divis\u00e3o por zero.<\/p>\n<pre class=\"code-highlighter line-numbers theme-dark\"><code class=\"language-php\">try{\r\n  1 &gt;&gt; -1;\r\n}catch(\\ArithmeticError $e){\r\n}\r\n<\/code><\/pre>\n<p>O c\u00f3digo acima vai resultar em uma exce\u00e7\u00e3o com a mensagem &#8220;Bit shift by negative number&#8221;.<\/p>\n<pre class=\"code-highlighter line-numbers theme-dark\"><code class=\"language-php\">try{\r\n  10 % 0\r\n}catch(\\DivisionByZeroError $e){\r\n}\r\n<\/code><\/pre>\n<p>O c\u00f3digo acima vai resultar em uma exce\u00e7\u00e3o com a mensagem &#8220;Modulo by zero&#8221;, pois h\u00e1 uma tentativa de dividir um valor por zero.<\/p>\n<h3>Conclus\u00e3o<\/h3>\n<p>Essas novas exce\u00e7\u00f5es que vieram com o PHP 7 v\u00e3o ter grande impacto na forma como voc\u00ea escreve o seu c\u00f3digo, mas se voc\u00ea n\u00e3o estiver utilizando &#8216;set_error_handler()&#8217;, ent\u00e3o n\u00e3o ter\u00e1 a necessidade de fazer altera\u00e7\u00f5es na sua aplica\u00e7\u00e3o para que ela continue funcionando.<\/p>\n<h3>PHP 7<\/h3>\n<p>Confira outros posts da nossa s\u00e9rie de PHP 7:<\/p>\n<ul>\n<li>#1 <a href=\"https:\/\/blog.umbler.com\/php-7-mudancas-na-linguagem\/\" target=\"_blank\" rel=\"noopener\"> Mudan\u00e7as b\u00e1sicas na Linguagem <\/a><\/li>\n<li>#2 <a href=\"https:\/\/blog.umbler.com\/php-7-recursos-obsoletos\/\" target=\"_blank\" rel=\"noopener\"> Recursos Obsoletos<\/a><\/li>\n<li>#3 <a href=\"https:\/\/blog.umbler.com\/sintaxe-uniforme-de-variaveis-no-php-7\/\" target=\"_blank\" rel=\"noopener\"> Sintaxe Uniforme de Vari\u00e1veis<\/a><\/li>\n<li>#4 <a href=\"https:\/\/blog.umbler.com\/php-7-type-hints\/\" target=\"_blank\" rel=\"noopener\"> PHP 7: Type Hints <\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Nesse post, falaremos sobre Error Handling no PHP 7, explicando, primeiramente, os conceitos de Assertions e Expectations. Assertions Desde o PHP 4 a fun\u00e7\u00e3o &#8216;assert()&#8217; est\u00e1 dispon\u00edvel, e ela serve para adicionar &#8216;sanity-checks&#8217; no c\u00f3digo. Ela deve ser utilizada somente para desenvolvimento, nunca em ambiente de produ\u00e7\u00e3o, e pode ser facilmente ativada e desativada usando [&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":[82,83,84,85,86,30,57],"class_list":["post-674","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-comunidade","category-dev","tag-assertions","tag-error-exceptions","tag-error-handling","tag-exceptions","tag-manipulacao-de-erros","tag-php","tag-php-7"],"_links":{"self":[{"href":"https:\/\/blog.umbler.com\/br\/wp-json\/wp\/v2\/posts\/674"}],"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=674"}],"version-history":[{"count":0,"href":"https:\/\/blog.umbler.com\/br\/wp-json\/wp\/v2\/posts\/674\/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=674"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.umbler.com\/br\/wp-json\/wp\/v2\/categories?post=674"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.umbler.com\/br\/wp-json\/wp\/v2\/tags?post=674"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}