{"id":22764593,"url":"https://github.com/kuria/debug","last_synced_at":"2025-04-13T04:37:30.421Z","repository":{"id":57009945,"uuid":"92076001","full_name":"kuria/debug","owner":"kuria","description":"Collection of useful debugging utilities","archived":false,"fork":false,"pushed_at":"2025-01-05T21:14:53.000Z","size":40,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-26T21:37:40.648Z","etag":null,"topics":["debug","dump","error","exception","hex","php"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kuria.png","metadata":{"files":{"readme":"README.rst","changelog":"CHANGELOG.rst","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-05-22T16:36:40.000Z","updated_at":"2025-01-05T21:14:54.000Z","dependencies_parsed_at":"2022-08-21T13:10:11.628Z","dependency_job_id":null,"html_url":"https://github.com/kuria/debug","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kuria%2Fdebug","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kuria%2Fdebug/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kuria%2Fdebug/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kuria%2Fdebug/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kuria","download_url":"https://codeload.github.com/kuria/debug/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248665779,"owners_count":21142122,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["debug","dump","error","exception","hex","php"],"created_at":"2024-12-11T12:09:26.424Z","updated_at":"2025-04-13T04:37:30.402Z","avatar_url":"https://github.com/kuria.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"Debug utilities\n###############\n\nCollection of useful debugging utilities.\n\n.. image:: https://travis-ci.com/kuria/debug.svg?branch=master\n   :target: https://travis-ci.com/kuria/debug\n\n.. contents::\n   :depth: 2\n\n\nRequirements\n************\n\nPHP 7.1+\n\n\nDumper\n******\n\nUtilities for inspecting arbitrary values.\n\n\nDumping any value\n=================\n\nDumping arbitrary PHP values with nesting and string length limits.\n\n.. code:: php\n\n   \u003c?php\n\n   use Kuria\\Debug\\Dumper;\n\n   $values = [\n       'foo bar',\n       123,\n       -123,\n       1.53,\n       -1.53,\n       true,\n       false,\n       fopen('php://stdin', 'r'),\n       null,\n       array(1, 2, 3),\n       new \\stdClass(),\n   ];\n\n   echo Dumper::dump($values);\n\nOutput:\n\n::\n\n  array[11] {\n      [0] =\u003e \"foo bar\"\n      [1] =\u003e 123\n      [2] =\u003e -123\n      [3] =\u003e 1.530000\n      [4] =\u003e -1.530000\n      [5] =\u003e true\n      [6] =\u003e false\n      [7] =\u003e resource(stream#10)\n      [8] =\u003e NULL\n      [9] =\u003e array[3]\n      [10] =\u003e object(stdClass)\n  }\n\n- see other arguments of ``dump()`` for nesting and string limits\n- if an object implements the ``__debugInfo()`` method, its output\n  will be used instead of the properties\n- if an object implements the ``__toString()`` method, its output\n  will be used instead of its properties if:\n\n  A. it has no properties\n  B. the properties cannot be displayed due to the nesting limit\n\n- if an object implements the ``\\DateTimeInterface``, its value\n  will be formatted as a string\n\n\nDumping strings\n===============\n\nSafely dumping arbitrary strings. All ASCII \u003c 32 will be escaped in C style.\n\n.. code:: php\n\n   \u003c?php\n\n   use Kuria\\Debug\\Dumper;\n\n   echo Dumper::dumpString(\"Foo\\nBar\");\n\nOutput:\n\n::\n\n  Foo\\nBar\n\n\nDumping string as HEX\n=====================\n\nUseful for dumping binary data or examining actual bytes of a text.\n\n.. code:: php\n\n   \u003c?php\n\n   use Kuria\\Debug\\Dumper;\n\n   echo Dumper::dumpStringAsHex(\"Lorem\\nIpsum\\nDolor\\nSit\\nAmet\\n\");\n\nOutput:\n\n::\n\n       0 : 4c 6f 72 65 6d 0a 49 70 73 75 6d 0a 44 6f 6c 6f [Lorem.Ipsum.Dolo]\n      10 : 72 0a 53 69 74 0a 41 6d 65 74 0a                [r.Sit.Amet.]\n\n\nGetting object properties\n=========================\n\n.. code:: php\n\n   \u003c?php\n\n   use Kuria\\Debug\\Dumper;\n\n   class Foo\n   {\n       public static $staticProperty = 'lorem';\n       public $publicProperty = 'ipsum';\n       private $privateProperty = 'dolor';\n   }\n\n   print_r(Dumper::getObjectProperties(new Foo()));\n\nOutput:\n\n::\n\n  Array\n  (\n      [staticProperty] =\u003e ReflectionProperty Object\n          (\n              [name] =\u003e staticProperty\n              [class] =\u003e Foo\\Foo\n          )\n\n      [publicProperty] =\u003e ReflectionProperty Object\n          (\n              [name] =\u003e publicProperty\n              [class] =\u003e Foo\\Foo\n          )\n\n      [privateProperty] =\u003e ReflectionProperty Object\n          (\n              [name] =\u003e privateProperty\n              [class] =\u003e Foo\\Foo\n          )\n\n  )\n\n\nOutput\n******\n\nUtilities related to PHP's output system.\n\n\nCleaning output buffers\n=======================\n\n.. code:: php\n\n   \u003c?php\n\n   use Kuria\\Debug\\Output;\n\n   // clean all buffers\n   Output::cleanBuffers();\n\n   // clean buffers up to a certain level\n   Output::cleanBuffers(2);\n\n   // clean all buffers and catch exceptions\n   $bufferedOutput = Output::cleanBuffers(null, true);\n\n\nCapturing output buffers\n========================\n\n.. code:: php\n\n   \u003c?php\n\n   use Kuria\\Debug\\Output;\n\n   // capture all buffers\n   Output::captureBuffers();\n\n   // capture buffers up to a certain level\n   Output::captureBuffers(2);\n\n   // capture all buffers and catch exceptions\n   $bufferedOutput = Output::captureBuffers(null, true);\n\n\nReplacing all headers\n=====================\n\nReplace all headers (unless they've been sent already):\n\n.. code:: php\n\n   \u003c?php\n\n   use Kuria\\Debug\\Output;\n\n   Output::replaceHeaders(['Content-Type: text/plain; charset=UTF-8']);\n\n\nError\n*****\n\nPHP error utilities.\n\n\nGetting name of a PHP error code\n================================\n\n.. code:: php\n\n   \u003c?php\n\n   use Kuria\\Debug\\Error;\n\n   var_dump(Error::getName(E_USER_ERROR));\n\nOutput:\n\n::\n\n  string(10) \"E_USER_ERROR\"\n\n\nException\n*********\n\nException utilities.\n\nRendering an exception\n======================\n\n.. code:: php\n\n   \u003c?php\n\n   use Kuria\\Debug\\Exception;\n\n   $invalidArgumentException = new \\InvalidArgumentException('Bad argument', 123);\n   $runtimeException = new \\RuntimeException('Something went wrong', 0, $invalidArgumentException);\n\n   echo Exception::render($runtimeException);\n\nOutput:\n\n::\n\n  RuntimeException: Something went wrong in example.php on line 6\n  #0 {main}\n\n\nIncluding all previous exceptions and excluding the traces\n----------------------------------------------------------\n\n.. code:: php\n\n   \u003c?php\n\n   echo Exception::render($runtimeException, false, true);\n\nOutput:\n\n::\n\n  [1/2] RuntimeException: Something went wrong in example.php on line 6\n  [2/2] InvalidArgumentException (123): Bad argument in example.php on line 5\n\n\nGetting a list of all previous exceptions\n=========================================\n\n.. code:: php\n\n   \u003c?php\n\n   use Kuria\\Debug\\Exception;\n\n   try {\n       try {\n           throw new \\InvalidArgumentException('Invalid parameter');\n       } catch (\\InvalidArgumentException $e) {\n           throw new \\RuntimeException('Something went wrong', 0, $e);\n       }\n   } catch (\\RuntimeException $e) {\n       $exceptions = Exception::getChain($e);\n\n       foreach ($exceptions as $exception) {\n           echo $exception-\u003egetMessage(), \"\\n\";\n       }\n   }\n\nOutput:\n\n::\n\n  Something went wrong\n  Invalid parameter\n\n\nJoining exception chains together\n=================================\n\nJoining exception chains has some uses in exception-handling code where\nadditional exception may be thrown.\n\n.. code:: php\n\n   \u003c?php\n\n   use Kuria\\Debug\\Exception;\n\n   $c = new \\Exception('C');\n   $b = new \\Exception('B', 0, $c);\n   $a = new \\Exception('A', 0, $b);\n\n   $z = new \\Exception('Z');\n   $y = new \\Exception('Y', 0, $z);\n   $x = new \\Exception('X', 0, $y);\n\n   // print current chains\n   echo \"A's chain:\\n\", Exception::render($a, false, true), \"\\n\\n\";\n   echo \"X's chain:\\n\", Exception::render($x, false, true), \"\\n\\n\";\n\n   // join chains (any number of exceptions can be passed)\n   // from right to left: the last previous exception is joined to the exception on the left\n   Exception::joinChains($a, $x);\n\n   // print the modified X chain\n   echo \"X's modified chain:\\n\", Exception::render($x, false, true), \"\\n\";\n\nOutput:\n\n::\n\n  A's chain:\n  [1/3] Exception: A in example.com on line 7\n  [2/3] Exception: B in example.com on line 6\n  [3/3] Exception: C in example.com on line 5\n\n  X's chain:\n  [1/3] Exception: X in example.com on line 11\n  [2/3] Exception: Y in example.com on line 10\n  [3/3] Exception: Z in example.com on line 9\n\n  X's modified chain:\n  [1/6] Exception: X in example.com on line 11\n  [2/6] Exception: Y in example.com on line 10\n  [3/6] Exception: Z in example.com on line 9\n  [4/6] Exception: A in example.com on line 7\n  [5/6] Exception: B in example.com on line 6\n  [6/6] Exception: C in example.com on line 5\n\n\nSimplified real-world example\n-----------------------------\n\nWithout joining exception chains\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n.. code:: php\n\n   \u003c?php\n\n   use Kuria\\Debug\\Exception;\n\n   // print uncaught exceptions\n   set_exception_handler(function ($uncaughtException) {\n       echo Exception::render($uncaughtException, false, true);\n   });\n\n   try {\n       // some code which may throw an exception\n       throw new \\Exception('Initial exception');\n   } catch (\\Exception $exception) {\n       // handle the exception\n       try {\n           // some elaborate exception-handling code which may also throw an exception\n           throw new \\Exception('Exception-handler exception');\n       } catch (\\Exception $additionalException) {\n           // the exception-handling code has crashed\n           throw new \\Exception('Final exception', 0, $additionalException);\n       }\n   }\n\nOutput:\n\n::\n\n  [1/2] Exception: Final exception in example.php on line 20\n  [2/2] Exception: Exception-handler exception in example.php on line 17\n\nNotice that the information about *Initial exception* is lost completely.\n\nWe could glue the *Initial exception*'s info to the *Final exception*'s message,\nbut that would be rather ugly and hard to read.\n\n\nWith joining exception chains\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n.. code:: php\n\n   \u003c?php\n\n   try {\n       // some code which may throw an exception\n       throw new \\Exception('Initial exception');\n   } catch (\\Exception $exception) {\n       // handle the exception\n       try {\n           // some elaborate exception-handling code which may also throw an exception\n           throw new \\Exception('Exception-handler exception');\n       } catch (\\Exception $additionalException) {\n           // the exception-handling code has crashed\n\n           // join exception chains\n           Exception::joinChains($exception, $additionalException);\n\n           throw new \\Exception('Something went wrong while handling an exception', 0, $additionalException);\n       }\n   }\n\nOutput:\n\n::\n\n    [1/3] Exception: Something went wrong while handling an exception in example.php on line 24\n    [2/3] Exception: Exception-handler exception in /example.php on line 17\n    [3/3] Exception: Initial exception in example.php on line 12\n\nNow the *Initial exception* is accessible as one of the previous exceptions.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkuria%2Fdebug","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkuria%2Fdebug","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkuria%2Fdebug/lists"}