Falhando miseralvelmente com PHP

6,525 views

Published on

Erros têm de fazer parte do dia a dia do desenvolvedor, porém a maioria prefere ignorá-los ou simplesmente não sabem como lidar com os mesmos. Nesta palestra de 50min vamos passar por duas diferentes formas de lidar com eles: procedural/imperativo e Exceptions além de ver como manter e utilizar mensagens de erros a fim de serem úteis no seu dia a dia.

Published in: Technology

Falhando miseralvelmente com PHP

  1. 1. Falhando miseravelmente com PHPAugusto Pascutti
  2. 2. 50min para resolver:
  3. 3. A página ta toda em brancoaqui, de novo.Usuário do sistema
  4. 4. Como eu faço pro PHP nãoexibir esse monte deE_NOTICE chato?Desenvolvedor querendo fazer merda
  5. 5. Tem um E_WARNING e algumacoisa sobre data na página.Usuário do sistema
  6. 6. Eu entro e dá erro.Usuários
  7. 7. 50 minutos sobre:Erros e outras mensagens relevantesUtilidade dessas mensagensGeração dessas mensagens
  8. 8. Errose outras mensagens relevantes
  9. 9. Since the beginning, life hasrelied upon the transmission ofmessages.RFC 3164:The BSD syslog Protocol
  10. 10. SeveridadesTipos de mensagens relevantes
  11. 11. Severidades:• Emergency: deu merda. Sistema inutilizado• Alert: vai da merda. Faça alguma coisa logo• Critical: tem tudo pra dar merda• Error: coisas que não deveriam acontecer• Warning: aviso.Tome mais cuidado• Notice: normal, mas ainda assim significativo• Informational• Debug
  12. 12. Severidades precisam de umcontextoEu mesmo, agora há pouco.
  13. 13. Severidades no PHPOu as utilizadas e disponíveis no PHP de todo mundo.
  14. 14. E_ERRORUm erro sem recuperação, a execução é interrompida.
  15. 15. E_PARSEErros de sintaxe, a execução é interrompida.
  16. 16. E_WARNINGUm erro não fatal, a execução continua.
  17. 17. E_NOTICEIndica um erro muito provável, a execução continua.
  18. 18. E_DEPRECATEDIndica uso de código que deixará de funcionar emversões futuras.
  19. 19. E_STRICTSugestões para melhor interoperabilidade ecompatibilidade futura.
  20. 20. Utilidadedessas mensagens
  21. 21. Um arquivo de log é como umamulher: quanto mais gostosa(o),mais atenção você presta.Newton
  22. 22. Baiduspider/2.0; +http://www.baidu.com/search/spider.html)"123.125.68.79 - - [20/Jun/2012:19:53:24 +0200] "GET / HTTP/1.1" 200 625 "-" "Mozilla/5.0 (compatible;Baiduspider/2.0; +http://www.baidu.com/search/spider.html)"178.154.210.252 - - [20/Jun/2012:19:54:10 +0200] "GET /?C=S;O=A HTTP/1.1" 200 663 "-" "Mozilla/5.0(compatible; YandexBot/3.0; +http://yandex.com/bots)"74.125.126.102 - - [20/Jun/2012:20:15:28 +0200] "GET / HTTP/1.1" 200 606 "http://www.google.com/url?sa=t&rct=j&q=error&source=web&cd=1&ved=0CFAQFjAG&url=http%3A%2F%2Fwww.isrolab.com%2F&ei=GxPiT5PsL4e04AHPtgE&usg=AFQjCNHnmjmdkUV584ORIpOXz7zAPX0UHQ" "Mozilla/4.0 (compatible; MSIE 7.0; WindowsNT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; InfoPath.2; .NETCLR 3.0.4506.2152; .NET CLR 3.5.30729)"74.125.126.103 - - [20/Jun/2012:20:15:29 +0200] "GET /icons/blank.gif HTTP/1.1" 200 383 "http://www.isrolab.com/" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; InfoPath.2; .NET CLR 3.0.4506.2152; .NET CLR3.5.30729)"74.125.126.93 - - [20/Jun/2012:20:15:29 +0200] "GET /icons/folder.gif HTTP/1.1" 200 460 "http://www.isrolab.com/" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; InfoPath.2; .NET CLR 3.0.4506.2152; .NET CLR3.5.30729)"74.125.126.82 - - [20/Jun/2012:20:15:30 +0200] "GET /favicon.ico HTTP/1.1" 404 449 "-" "Mozilla/4.0(compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR3.5.21022; InfoPath.2; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)"184.82.92.239 - - [20/Jun/2012:21:03:44 +0200] "GET /logs/access.log HTTP/1.1" 200 2519 "http://isrolab.com/""Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; Mozilla/4.0 (compatible; MSIE 6.0; Windows NT5.1; SV1) ; .NET CLR 3.5.30729)"173.236.21.106 - - [20/Jun/2012:21:16:22 +0200] "GET /robots.txt HTTP/1.0" 404 488 "-" "Mozilla/5.0(compatible; MJ12bot/v1.4.3; http://www.majestic12.co.uk/bot.php?+)"173.236.21.106 - - [20/Jun/2012:21:16:23 +0200] "GET / HTTP/1.0" 200 621 "-" "Mozilla/5.0 (compatible;MJ12bot/v1.4.3; http://www.majestic12.co.uk/bot.php?+)"213.186.122.2 - - [20/Jun/2012:21:27:53 +0200] "GET /logs/?C=D;O=D HTTP/1.1" 200 658 "-" "Mozilla/5.0(compatible; AhrefsBot/3.0; +http://ahrefs.com/robot/)"66.249.72.65 - - [20/Jun/2012:21:28:00 +0200] "GET /robots.txt HTTP/1.1" 404 508 "-" "Mozilla/5.0 (compatible;Googlebot/2.1; +http://www.google.com/bot.html)"66.249.72.65 - - [20/Jun/2012:21:28:00 +0200] "GET /logs/ HTTP/1.1" 200 723 "-" "Mozilla/5.0 (compatible;Googlebot/2.1; +http://www.google.com/bot.html)"123.125.71.44 - - [20/Jun/2012:21:38:57 +0200] "GET / HTTP/1.1" 200 913 "-" "Mozilla/5.0 (compatible;Baiduspider/2.0; +http://www.baidu.com/search/spider.html)"220.181.108.88 - - [20/Jun/2012:21:39:48 +0200] "GET / HTTP/1.1" 200 913 "-" "Mozilla/5.0 (compatible;Baiduspider/2.0; +http://www.baidu.com/search/spider.html)"178.154.210.252 - - [20/Jun/2012:21:45:12 +0200] "GET /logs/ HTTP/1.1" 200 728 "-" "Mozilla/5.0 (compatible;YandexBot/3.0; +http://yandex.com/bots)"139.18.2.209 - - [20/Jun/2012:22:31:43 +0200] "GET / HTTP/1.1" 200 912 "-" "findlinks/2.6 (+http://wortschatz.uni-leipzig.de/findlinks/)"
  23. 23. Pegue já seu exemplo!!g filetype:log access.log
  24. 24. Eu não preciso disso, já tenho oAnalytics em todas as páginas.Algum desenvolvedor
  25. 25. Como usar isso?O (meu) jeito *nix
  26. 26. word, line, character, and byte countwc
  27. 27. #!/bin/bash[~/Apache] $ wc -l access.log65063 access.log
  28. 28. print lines matching a patterngrep
  29. 29. #!/bin/bash[~/Apache] $ wc -l access.log65063 access.log[~/Apache] $ grep "HTTP/1.1" access.log | wc -l52129
  30. 30. #!/bin/bash[~/Apache] $ wc -l access.log65063 access.log[~/Apache] $ grep "HTTP/1.1" access.log | wc -l52129[~/Apache] $ grep "HTTP/1.0" access.log | wc -l13007
  31. 31. #!/bin/bash[~/Apache] $ wc -l access.log65063 access.log[~/Apache] $ grep "HTTP/1.1" access.log | wc -l52129[~/Apache] $ grep "HTTP/1.0" access.log | wc -l13007[~/Apache] $ grep -v "HTTP/1.1" access.log | grep -v "HTTP/1.0"114.66.65.89 - - [24/Dec/2012:07:46:27 +0100] "GET /logs/access.log vxc2xa4Nxd41.0" 200 1963700 "http://www.isrolab.com/" "Mozilla/5.0 (Windows NT 6.1; rv:2.0b7pre)Gecko/20100921 Firefox/4.0b7pre"
  32. 32. #!/bin/bash[~/Apache] $ wc -l access.log65063 access.log[~/Apache] $ grep "HTTP/1.1" access.log | wc -l52129[~/Apache] $ grep "HTTP/1.0" access.log | wc -l13007[~/Apache] $ grep -v "HTTP/1.1" access.log | grep -v "HTTP/1.0"114.66.65.89 - - [24/Dec/2012:07:46:27 +0100] "GET /logs/access.log vxc2xa4Nxd41.0" 200 1963700 "http://www.isrolab.com/" "Mozilla/5.0 (Windows NT 6.1; rv:2.0b7pre)Gecko/20100921 Firefox/4.0b7pre"
  33. 33. Procura isso no Analytics agora.Augusto Pascutti
  34. 34. display first lines of a filehead
  35. 35. #!/bin/bash[~/Apache]$ head -n 1 access.log1.202.218.8 - - [20/Jun/2012:19:05:12 +0200] "GET /robots.txtHTTP/1.0" 404 492 "-" ""Mozilla/5.0"
  36. 36. pattern-directed scanning and processing languageawk
  37. 37. #!/bin/bash[~/Apache]$ head -n 1 access.log1.202.218.8 - - [20/Jun/2012:19:05:12 +0200] "GET /robots.txtHTTP/1.0" 404 492 "-" ""Mozilla/5.0"[~/Apache]$ head -n 1 access.log | awk {print $1}1.202.218.8
  38. 38. #!/bin/bash[~/Apache]$ head -n 1 access.log1.202.218.8 - - [20/Jun/2012:19:05:12 +0200] "GET /robots.txtHTTP/1.0" 404 492 "-" ""Mozilla/5.0"[~/Apache]$ head -n 1 access.log | awk {print $1}1.202.218.8[~/Apache]$ awk {print $1} access.log | head -n 101.202.218.8208.115.113.91123.125.71.20220.181.108.101123.125.68.79178.154.210.25274.125.126.10274.125.126.10374.125.126.9374.125.126.82
  39. 39. sort lines of text filessort
  40. 40. #!/bin/bash[~/Apache]$ awk {print $1} access.log | head -n 51.202.218.8208.115.113.91123.125.71.20220.181.108.101123.125.68.79
  41. 41. #!/bin/bash[~/Apache]$ awk {print $1} access.log | head -n 51.202.218.8208.115.113.91123.125.71.20220.181.108.101123.125.68.79[~/Apache]$ awk {print $1} access.log | head -n 5 | sort1.202.218.8123.125.68.79123.125.71.20208.115.113.91220.181.108.101
  42. 42. report or filter out repeated lines in a fileuniq
  43. 43. #!/bin/bash[~/Apache]$ awk {print $1} access.log | sort | uniq | wc -l7967
  44. 44. #!/bin/bash[~/Apache]$ awk {print $1} *.log | sort | uniq | wc -l7967[~/Apache]$ awk {print $1} *.log | sort | uniq | head -n 101.0.250.1211.179.147.21.2.209.1301.2.215.1511.2.216.1101.2.217.901.202.218.131.202.218.141.202.218.151.202.218.21
  45. 45. Quais os IPs que mais acessaramo access.log dele?Já que sabemos que não fomos os únicos.
  46. 46. Você já ouviu falar em “bashscript”, certo?Eu
  47. 47. #!/bin/bash[~/Apache]$ for ip in `awk {print $1} *.log | sort | uniq`; do> count=`grep “$ip” access.log | grep access.log | wc -l`;> echo "$count $ip" >> ip-safadenhos.txt;> done;
  48. 48. #!/bin/bash[~/Apache]$ wc -l *.txt9479 ip-safadenhos.txt
  49. 49. #!/bin/bash[~/Apache]$ wc -l *.txt9479 ip-safadenhos.txt[~/Apache]$ awk {print $1} *.txt | grep -v 0 | wc -l5619
  50. 50. Top 10
  51. 51. #!/bin/bash[~/Apache]$ sort -nr ip-safadenhos.txt | head -n 10246 88.250.57.232184 216.151.130.179121 88.190.16.3690 199.59.56.2484 80.93.217.3873 216.152.251.771 89.233.105.12568 120.196.161.25168 120.196.161.25158 190.254.21.236
  52. 52. Como usar isso no dia a dia?Já que ninguém tem tempo sobrando.
  53. 53. Pegue já seu outro exemplo!!g filetype:log error.log E_ERROR
  54. 54. Log do PHPVia linha de comando.
  55. 55. LC_Page_Admin.php(69)] from 126.29.228.69login_id = ()[acf83d9069c4c9036fa852909503b631]2013/01/30 00:49:03 [/hiroshima-gift.co.jp/html/admin/index.php] Fatal error(E_ERROR): Call to a memberfunction doAction() on a non-object on [/home/bravecreate/www/hiroshima-gift.co.jp/data/class/pages/admin/LC_Page_Admin.php(69)] from 126.29.228.69login_id = ()[acf83d9069c4c9036fa852909503b631]2013/01/30 00:50:38 [/hiroshima-gift.co.jp/html/admin/index.php] Fatal error(E_ERROR): Call to a memberfunction doAction() on a non-object on [/home/bravecreate/www/hiroshima-gift.co.jp/data/class/pages/admin/LC_Page_Admin.php(69)] from 126.29.228.69login_id = ()[acf83d9069c4c9036fa852909503b631]2013/01/30 00:50:59 [/hiroshima-gift.co.jp/html/admin/index.php] Fatal error(E_ERROR): Call to a memberfunction doAction() on a non-object on [/home/bravecreate/www/hiroshima-gift.co.jp/data/class/pages/admin/LC_Page_Admin.php(69)] from 126.29.228.69login_id = ()[acf83d9069c4c9036fa852909503b631]2013/04/02 14:09:39 [/hiroshima-gift.co.jp/html/index.php] Fatal error(E_USER_ERROR):DB処çê †ãÅ §ã‚¨ãƒ©ãƒ¼ãÅ Œç™ºç”ŸãÅ —ãÅ ¾ãÅ —ãÅ Ÿã€‚SQL: [SET SESSION storage_engine = InnoDB]PlaceHolder: [array ()]MDB2 Error: insufficient permissions_doQuery: [Error message: Could not select the database: bravecreate_nagasakiya_ec][Last executed query: SET SESSION storage_engine = InnoDB][Native code: 1044][Native message: Access denied for user bravecreate@% to database bravecreate_nagasakiya_ec]on [/home/bravecreate/www/hiroshima-gift.co.jp/data/class/SC_Query.php(1008)] from 66.249.74.233customer_id =/home/bravecreate/www/hiroshima-gift.co.jp/html/index.php(32): LC_Page_Index_Ex->init/home/bravecreate/www/hiroshima-gift.co.jp/data/class_extends/page_extends/LC_Page_Index_Ex.php(47):LC_Page_Index->init/home/bravecreate/www/hiroshima-gift.co.jp/data/class/pages/LC_Page_Index.php(45): LC_Page->init/home/bravecreate/www/hiroshima-gift.co.jp/data/class/pages/LC_Page.php(97): SC_Helper_PageLayout->sfGetPageLayout/home/bravecreate/www/hiroshima-gift.co.jp/data/class/helper/SC_Helper_PageLayout.php(54):SC_Helper_PageLayout->getPageProperties/home/bravecreate/www/hiroshima-gift.co.jp/data/class/helper/SC_Helper_PageLayout.php(112):SC_Query::getSingletonInstance/home/bravecreate/www/hiroshima-gift.co.jp/data/class/SC_Query.php(104): SC_Query->__construct/home/bravecreate/www/hiroshima-gift.co.jp/data/class/SC_Query.php(88): SC_DB_DBFactory_MYSQL->initObjQuery/home/bravecreate/www/hiroshima-gift.co.jp/data/class/db/dbfactory/SC_DB_DBFactory_MYSQL.php(323): SC_Query->exec/home/bravecreate/www/hiroshima-gift.co.jp/data/class/SC_Query.php(231): SC_Query->query/home/bravecreate/www/hiroshima-gift.co.jp/data/class/SC_Query.php(814): SC_Query->execute/home/bravecreate/www/hiroshima-gift.co.jp/data/class/SC_Query.php(971): SC_Query->error
  56. 56. #!/bin/bash[~/PHP]$ awk /(E_[A-Z])/ {print $5} error.log | sort | uniq -c24 error(E_ERROR):15 error(E_USER_ERROR):
  57. 57. #!/bin/bash[~/PHP]$ awk /(E_[A-Z])/ {print $5} error.log | sort | uniq -c24 error(E_ERROR):15 error(E_USER_ERROR):[~/PHP]$ awk -F: /E_ERROR/ {print $4} error.log | sort | uniqCall to a member function doAction() on a non-object on [/home/bravecreate/www/hiroshima-gift.co.jp/data/class/SC_View.php(137)]Call to a member function doAction() on a non-object on [/home/bravecreate/www/hiroshima-gift.co.jp/data/class/SC_View.php(137)]Call to a member function doAction() on a non-object on [/home/bravecreate/www/hiroshima-gift.co.jp/data/class/pages/admin/LC_Page_Admin.php(69)]
  58. 58. Geraçãodessas mensagens
  59. 59. ConfiguraçõesOu coisas que podem provocar diferentes resultadosno seu PHP.
  60. 60. display_errorsVocê quer ver esses erros?
  61. 61. ini_set(‘display_errors’,‘On’)Exibe erros em HTML para usuário.(Ideal para ambiente de desenvolvimento)
  62. 62. ini_set(‘display_errors’,‘Off’)Não exibe erros.(Ideal para ambiente de produção)
  63. 63. log_errorsEnvia os erros para o arquivo de log configurado.
  64. 64. ini_set(‘log_errors’,‘On’)Salva os erros no arquivo de log.(Ideal em todos os ambientes)
  65. 65. ini_set(‘log_errors’,‘Off’)Não salva erros no arquivo de log.(Não sei porque você irá querer isso)
  66. 66. error_logOnde você deseja que o arquivo de log seja gerado?
  67. 67. error_reportingQuais severidades utilizar?
  68. 68. 1 <?php2 ini_set(display_errors, 1);3 error_reporting(E_ALL);45 if ($_POST[user]) {6 // ...7 }8 /**9 * Output:10 *11 * PHP Notice: Undefined index: user in notices.php on line 512 */
  69. 69. 1 <?php2 ini_set(display_errors, 1);3 error_reporting(E_ALL ^ E_NOTICE);45 if ($_POST[user]) {6 // ...7 }8 /**9 * Output:10 *11 */
  70. 70. 1 <?php2 ini_set(display_errors, 1);3 error_reporting(E_ALL);45 echo date(l).PHP_EOL;67 date_default_timezone_set(America/Sao_Paulo);89 echo date(l).PHP_EOL;1011 /**12 * Output:13 *14 * PHP Warning: date(): It is not safe to rely on the systems15 * timezone settings. You are *required* to use the date.timezone16 * setting or the date_default_timezone_set() function.17 * In case you used any of those methods and you are still getting18 * this warning, you most likely misspelled the timezone identifier.19 * We selected the timezone UTC for now, but please set date.timezone20 * to select your timezone. in date.php on line 521 *22 * Saturday23 * Saturday24 */
  71. 71. 1 <?php2 ini_set(display_errors, 1);3 error_reporting(E_ALL);45 include nao-existe.php;67 /**8 * Output:9 *10 * PHP Warning: include(nao-existe.php): failed to open stream:11 * No such file or directory in warning.php on line 512 */
  72. 72. 1 <?php2 ini_set(display_errors, 1);3 error_reporting(E_ALL);45 require nao-existe.php;6 /**7 * Output:8 *9 * PHP Warning: require(nao-existe.php): failed to open stream:10 * No such file or directory in warning.php on line 511 *12 * Fatal error: require(): Failed opening required13 * nao-existe.php in error.php on line 514 */
  73. 73. Procedural
  74. 74. trigger_error()Gera uma mensagem de determinada severidade.
  75. 75. 1 <?php2 date_default_timezone_set(America/Sao_Paulo);3 error_reporting(-1);4 ini_set(log_errors, 1);5 ini_set(error_log, duh.log);67 define(APP_ENV, getenv(APP_ENV) ?: dev);8 switch (APP_ENV) {9 case live:10 ini_set(display_errors, 0);11 break;12 default:13 ini_set(display_errors, 1);14 break;15 }1617 if (false === extension_loaded(xdebug)) {18 trigger_error(Conhece o xDebug?, X_USER_NOTICE);19 }2021 if (false === version_compare($current=PHP_VERSION, $required=6.4.0, >=)) {22 $msg = sprintf(Versão mínima do PHP requerida %s. (%s), $required, $current);23 trigger_error($msg, E_USER_ERROR);24 unset($required, $current);25 }2627 if (false === file_exists($autoload = vendor/autoload.php)) {28 trigger_error(Por favor, rode a instale com `make install`., E_USER_ERROR);29 }30
  76. 76. error_log()Envia mensagem para o log de erros.
  77. 77. 1 <?php2 ini_set(display_errors, 0);3 ini_set(log_errors, 1);4 error_reporting(-1);56 error_log(É nóis na fita!);7 error_log(Não me deixa cair no SPAM!, 1, a@a.com);
  78. 78. 1 <?php2 ini_set(display_errors, 0);3 ini_set(log_errors, 1);4 error_reporting(-1);56 error_log(É nóis na fita!);7 error_log(Não me deixa cair no SPAM!, 1, a@a.com);
  79. 79. ExceptionsErros num paradigma Orientado a Objetos
  80. 80. 1 <?php23 namespace Math;45 class Operation6 {7 public static function sum()8 {9 $args = func_get_args();10 $result = 0;11 foreach ($args as $arg) {12 if (false == is_int($arg)) {13 $msg = Somente inteiros permitidos;14 throw new InvalidArgumentException($msg);15 }16 $result += (integer) $arg;17 }1819 return $result;20 }21 }2223 echo Operation::sum(1,2,3,5.0);
  81. 81. 1 <?php23 namespace Math;45 require math.php; // use autoload, por favor!67 use InvalidArgumentException;8 use Exception;910 class Grades11 {12 public static function average($prova1, $prova2, $prova3)13 {14 try {15 $total = Operation::sum($prova1, $prova2, $prova3);16 } catch (InvalidArgumentException $e) {17 $msg = Alguma nota esta errada.;18 throw new InvalidArgumentException($msg, null, $e);19 } catch (Exception $e) {20 $msg = Calcular media de notas.;21 throw new RuntimeException($msg, null, $e);22 }23 }24 }2526 echo Grades::average(10, 10, 9.8);
  82. 82. SPL Exceptionshttp://php.net/spl
  83. 83. Quer saber mais?Acabou de sair do forno.
  84. 84. PSR-3Um padrão de logs para o PHP
  85. 85. Concluindo
  86. 86. Falhando miseravelmente com PHPUma re-interpretação do título.
  87. 87. Falhando miseravelmente com PHPErros e mensagens do sistema DEVEM ser expostossempre que possível.
  88. 88. Falhando miseravelmente com PHPExpostos pra todos os desenvolvedores (e administradores)envolvidos na manutenção do sistema, não para usuários.Muito menos para toda internet.
  89. 89. Falhando miseravelmente com PHPPELO MENOS os gerados pelo próprio PHP.
  90. 90. Dúvidas?ou críticas, sugestões, declarações, conjecturações, etc...

×