Loading…

PHPDebugConsole + Error Handler v3.2 No more var_dump()

Overview & Usage

PHPDebugConsole is a browser/javascript like console class for PHP (logging, debugging, value inspecting, etc).


    • PHPDebugConsole is great!
    • No browser plugin necessary
    • features/options = array(
      • 0=>PHP port of the javascript web console API
      • outputOpts=>array(
        • 0=>HTML (as seen here)
        • 1=>ChromeLogger
        • 2=>FirePHP
        • 3=>Plain-text / file / stream
        • 4=>ServerLog
        • 5=><script>
        • 6=>"plugin" (send log realtime via websockets, etc)
        )
      • 1=>password protected
      • 2=>errors (even fatal) are captured / logged / displayed
      • 3=>send error notices via email, Discord, Slack, or Teams (throttled as to not to send out a flood of emails)
      • 4=>send debug log via email
      )
    • Styling: as of v2.0: supports styling and substitution
    • example object =
      It's Magic Example
      implements
      Stringable
      properties
      private offLimits = I'm a private property
      methods
      public __toString(): string

      return value

      • It's Magic
      private foo(string $bar): string
    • types are styled
      • array(
        • string=><em>Strings</em><br /> get visual\u{00a0}whitespace&trade; and control-char highlighting (hover over the highlights). Ⅴersion 3.3 adds cօnfᴜsable char highlighting
        • boolean yea=>true
        • boolean nay=>false
        • int=>7
        • float=>123.45
        • null=>null
        • timestamp (string)=>1726171670
        • numeric string=>42
        )
    • Table - Click headings to sort
       citystatepopulation
      0AtlantaGA472522
      1BuffaloNY256902
      2ChicagoIL2704958
      3DenverCO693060
      4SeattleWA704352
      5TulsaOK403090

    Quick Start

    Installation Option A:

    Install via Composer as bdk/debug

    Add to composer.json

    {
        "require": {
            "bdk/debug": "^3.2"
        }
    }

    or

    composer require bdk/debug --update-no-dev

    Installation Option B:

    Download and extract PHPDebugConsole to your webserver

    You will need to include and register our autoloader

    require 'path-to/src/Debug/Autoloader.php';
    $autoloader = new \bdk\Debug\Autoloader();
    $autoloader->register();
    // you can now instantiate Debug
    $debug = new \bdk\Debug();
    Download PHPDebugConsole

    Usage

    <?php
    require __DIR__ . '/vendor/autoload.php';		// If installed via composer
    
    // If not using composer uncomment the next 3 lines
    // require 'path-to/src/Debug/Autoloader.php';
    // $autoloader = new \bdk\Debug\Autoloader();
    // $autoloader->register();
    
    $debug = new \bdk\Debug(array(
    	'collect' => true,
    	'output' => true,
    ));
    
    $debug->log('hello world');

    Quality / Badges

    • No Dependencies
    • Supported PHP versions
    • Github Build Status
    • Codacy Score
    • Code Climate - Maintainability
    • Code Climate - Coverage

    Features

    • Automatically outputs to HTML, serverLog, or stream appropriate to environment / request
    • Channels:
      • Log PDO/SQL related entries in a "PDO" channel. Log guzzle in a "guzzle" channel. Log routing info in a "route" channel. etc
      • Html output can be filtered by channels. Other routes can filter what they handle / output by channel name.
    • HTML output features
      • Collapsable drawer docked to bottom of viewport.. (look at bottom of this page's viewport for example)
      • filter sidebar - filter by channel, or log-level (alert, error, warning, info, other)
      • syntax highlighted json, xml, sql, php
      • editor links (click on error or file to open relevant file/line in your editor/IDE)
      • fatal error backtraces get context (file-snippets)
    • Automatically email fatal error details to SERVER_ADMIN (configurable / disabled by default)
    • Methods may be called statically or as an instance method
      • To call statically, prefix the method name with an underscore.
        Starting with v3.1, the underscore prefix is no longer required.
      • example: \bdk\Debug::_log('I was logged statically');
    • Logs environment, request/response, $_SESSION, & files included during request. If using a framework extension/bundle, more information may be logged
      • Php Version, ini file(s) location, configured timezone, memory limit
      • If error reporting is less than E_ALL | E_STRICT
      • Checks if expose_php is disabled, whether common extensions, curl & mbstring enabled, whether xdebug is enabled
    • Redact sensitive values
    • Plugins/collectors for Guzzle, Monolog, Mysqli, OAuth, PDO, PhpCurlClass, PSR-3 (logger), PSR-16 (SimpleCache), SoapClient, SwiftMailer, & Twig. See documentation.

    Strings

    • Control chars & non-visual chars shown
    • "Confusable" chars are highlighted (as of ver 3.3)
    • Base64, json, & serialized detected & inspected. (serialized only unserialized if safe to do so)
    • HTML, json, SQL, & XML prettified. (Other formats may be prettified via plugin)
    • Binary strings inspected and mime/content-type shown
    • Numeric strings tested if timestamp and readable date/time shown
    String Examples

      • value a = 1726171670
      • value b = \u{feff}This string has it all: <ul> <li>Pesky <abbr title="Byte-Order-Mark">BOM</abbr></li> <li>HTML</li> <li>control chars: </li> <li>easy-to-miss characters such as \u{00a0}(nbsp), \u{2009}(thsp), &amp; \u{200b}(zwsp).</li> <li>Con𝘧usable characters (as of ver 3.3)</li> </ul>
      • value c =
        iVBORw0KGgoAAAANSUhEUgAAAcIAAAA/CAMAAAEzugiSAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJ bWFnZVJlYWR5ccllPAAAAMBQTFRF+pMFrgIC9PHp0mNlcF1gXlSo2s/JjWZiDgWTklUTTiMf69sI … 13100 more bytes (not logged)
        string(binary)
        • mime type = image/png
        • size = 9687
        • Binary data not collected
      • value d =
        (prettified) { "poop": "\ud83d\udca9", "int": 42, "password": "█████████" }
        array(
        • poop=>💩
        • int=>42
        • password=>█████████
        )
      • value e =
        YTo0OntpOjA7czo1OiJwaG9uZSI7aToxO3M6NjoibGFwdG9wIjtpOjI7czo3OiJkZXNrdG9wIjtpOjM7czo2OiJ0YWJsZXQiO30=
        a:4:{i:0;s:5:"phone";i:1;s:6:"laptop";i:2;s:7:"desktop";i:3;s:6:"tablet";}
        array(
        • 0=>phone
        • 1=>laptop
        • 2=>desktop
        • 3=>tablet
        )

      Objects

      PHPDebugConsole dumps just about every piece of info you would need to know about an object

      • Classname
      • Interfaces
      • Inheritance
      • Final?
      • Readonly?
      • Constants
        • Name
        • Type (PHP 8.3) (v3.1)
        • Value
        • Attributes (PHP 8)
        • PhpDoc description (PHP 7.1)
        • Visibility (PHP 7.1)
      • Properties
        • Name
        • Type
        • Value

          Did value come from object's debugInfo() method?

        • Attributes (PHP 8)
        • Deprecated? (v3.3)
        • Dynamic? (v3.1)
        • Hooks (PHP 8.4 / v3.3)
        • Inheritance
          (Where was it last declared?)
        • Visibility - public | protected | private | magic | magic-read | magic-write | debug
          Can be combination of the above (example private magic-read)
        • PhpDoc description
        • Promoted (PHP 8)
        • Static?
      • Methods
        • Name
        • Visibility - public | protected | private | magic
        • What interface method implements (if any) (v3.2)
        • Attributes (PHP 8)
        • Deprecated?
        • Inheritance
          (Where was it last declared?)
        • Final?
        • Static?
        • Static variables (v3.2)
        • PhpDoc description
        • PhpDoc @throws info (v3.2)
        • Return type & PhpDoc description
        • Parameters
          • name
          • type
          • optional?
          • default value
          • Attributes (PHP 8)
          • Promoted? (PHP 8)
          • PhpDoc description
      • PhpDoc tags
      • Attributes (PHP 8)

        PHP Attributes are inspected for Class, Constants, Properties, Methods, Method Params

      • Anonymous?
      Example Object

        • Click on the classname or [+] expandy below to inspect the object
        • array(
          • Once expanded, hover over various things for tooltips
          • Click on the toggle button at the top to show/hide protected, private, etc
          • Click on "ArrayAccess" to toggle showing ArrayAccess methods
          )
        • this is the __toString return value Acme\Widget
          modifiers
          final
          attributes
          Acme\Attributes\ExampleClassAttribute(foo, bar:baz)
          extends
          Acme\Component
          implements
          ArrayAccess
          constants
          Inherited from Acme\Component
          public EVENT_RENDER = widget.render
          properties (via __debugInfo)
          This object has a __get method
          public baz = the 'ol __debugInfo a'roo
          public dynamic = Deprecated
          magic thing = I'm not included in debugInfo #reasons
          private Acme\GiantObj bar = NOT INSPECTED
          debug blah = I'm returned in __debugInfo, but not otherwise a property
          Inherited from Acme\Component
          public static string encoding = UTF-8
          protected int count = 10
          private array foo = array()
          methods
          This object has a __call method
          public __construct(int $count)
          public __debugInfo(): array
          public __toString(): string

          return value

          • this is the __toString return value
          public static getFlags(): array
          public illConceived(string $version = PHP_VERSION, string &...$key)

          static variables

          • accumulatrix= 3.2
          final public run(): string
          magic shazam(): Acme\Response
          protected someInternalThing()
          private somePrivateThing()
          Inherited from Acme\Component
          public __call(string $name, array $arguments): mixed
          public __get(string $name): mixed
          public offsetExists(string $key): bool
          public offsetGet(string $key): mixed
          public offsetSet(string $key, mixed $key): void
          public offsetUnset(string $$key): void
          phpDoc
          author: James Acme <james@example.com>

        Methods

        Note: In the examples below, instantiation of $debug has been omitted for brevity.

        Note: As of v2.0, all instance methods can be called statically by prefixing "_" (underescore) to the method name.
        example: \bdk\Debug::_log('I was logged statically');

        Note: As of v3.1, Any method added via plugin (every method of interest) may be called statically without the underscore prefix.
        example: \bdk\Debug::log('I was logged statically');

        Logging methods

        alert(string $message[, string $level = error[, bool $dismissible = false]]): static

        Display an alert at the top of the log

        Parameters

        $message
        message to be displayed
        $level
        error, info, success, or warn
        "danger" & "warning" are still accepted, however deprecated
        $dismissible
        (false) Whether to display a close icon/button
        Return Value
        bdk\Debug

        Can use styling & substitutions.
        If using substitutions will need to pass $level & $dismissible as meta values

        This method does not have a web console API equivalent.
        Example Source
        $debug->log("pretending to attempt database connection");
        $debug->alert('Couldn\'t connect to the SQL server!', $debug->meta('icon', 'fa fa-times-circle fa-lg'));
        $debug->alert('Location: <a class="alert-link" href="#">/some-redirect-url</a>', 'info', $debug->meta(array(
            'icon' => 'fa fa-external-link fa-lg',
            'sanitize' => false,
        )));
        Example Output

          • pretending to attempt database connection
          Changelog:
          • v3.3 - Now accepts arbitrary arguments (like log, info, warn, & error)
          • v3.0 - danger & warning levels replaced with error & warn
          • v2.0
          assert(bool $assertion[, mixed …$msg = null]): Debug

          If first argument evaluates false, log the remaining parameters

          Parameters
          assertion
          Any boolean expression. If the assertion is false, the message is logged
          msg
          (optional) variable num of values to output if assertion fails if none provided, will use calling file & line num
          Return Value
          Debug
          2.0 Default message used if none passed 2.3 Support for substitution & formatting
          Example Source
          $debug->assert(1 + 1 === 2, 'basic addition');
          $debug->assert(1 * 1 === 2, 'basic multiplication');
          $debug->assert(false);  // no message parameter
          Example Output

            • basic multiplication
            • Assertion failed: /path/to/mypage.inc.php (line 3)
            Supports substitution & formatting, see log() for examples
            Changelog:
            • v2.3: Support for substitution & formatting
            • v2.0: Default message used if none passed
            clear(int $bitmask = bdk\Debug::CLEAR_LOG): Debug

            Clear the log

            Parameters
            bitmask
            A bitmask of options self::CLEAR_ALERTS : Clear alerts generated with alert() self::CLEAR_LOG : default Clear log entries (excluding warn & error) self::CLEAR_LOG_ERRORS : Clear warn & error self::CLEAR_SUMMARY : Clear summary entries (excluding warn & error) self::CLEAR_SUMMARY_ERRORS : Clear warn & error within summary groups self::CLEAR_ALL : Clear all log entries self::CLEAR_SILENT : Don't add log entry
            Return Value
            Debug
            Description
            This method executes even if collect is false
            Example Source
            $debug->log('now you see me');
            $debug->error('yikes, I\'m an error');
            $debug->clear();
            $debug->info('hover over "cleared" entry for file & line');
            Example Output

              • yikes, I'm an error
              • Cleared log (sans errors)
              • hover over "cleared" entry for file & line
              Changelog:
              • v2.2
              count(mixed $label = null[, int $flags = null]): static
              count(int $flags): static

              Log the number of times this has been called with the given label.

              Parameters
              label
              Label. If omitted, logs the number of times count() has been called at this particular line.
              flags
              (optional) A bitmask of \bdk\Debug::COUNT_NO_INC : don't increment the counter (ie, just get the current count) \bdk\Debug::COUNT_NO_OUT : don't output/log
              Return Value
              int
              The new count (or current count when using COUNT_NO_INC)
              Description
              Count is maintained even when collect is false If collect = false, count() will be performed "silently"
              Example Source
              $debug->count();
              $debug->count('myCounter');
              for ($i=0; $i<2; $i++) {
                  $debug->count();
                  $debug->count('myCounter', \bdk\Debug::COUNT_NO_OUT); // don't output now
              }
              $debug->log('after loop');
              $debug->count();
              $debug->count('myCounter');
              echo 'myCounter value = '.$debug->count('myCounter', \bdk\Debug::COUNT_NO_INC | \bdk\Debug::COUNT_NO_OUT); // don't increment or output, just return
              Example Output
              myCounter value = 4

                • count = 1
                • myCounter = 1
                • count = 2
                • count = 3
                • after loop
                • count = 4
                • myCounter = 4
                Changelog:
                • v2.1: $flags argument added
                countReset(mixed $label = null[, int $flags = null]): static
                countReset(int $flags): static

                Resets the counter

                Parameters
                label
                (optional) specify the counter to reset
                flags
                (optional) currently only one option : \bdk\Debug::COUNT_NO_OUT` : don't output/log
                Return Value
                Debug
                Description
                Counter is reset even when debugging is disabled (ie collect is false).
                Example Source
                $debug->count('myCounter');
                for ($i=0; $i<2; $i++) {
                    $debug->count('myCounter', \bdk\Debug::COUNT_NO_OUT); // don't output now
                }
                $debug->log('after loop');
                $debug->count('myCounter');
                $debug->log('do the reset');
                $debug->countReset('myCounter');
                $debug->log('get count without incrementing...');
                $debug->count('myCounter', \bdk\Debug::COUNT_NO_INC);
                $debug->log('calling count after reset');
                $debug->count('myCounter');
                Example Output

                  • myCounter = 5
                  • after loop
                  • myCounter = 8
                  • do the reset
                  • myCounter = 0
                  • get count without incrementing...
                  • myCounter = 0
                  • calling count after reset
                  • myCounter = 1
                  Changelog:
                  • v2.3
                  error(mixed …$arg): Debug

                  Log an error message.

                  Parameters
                  arg
                  message / values
                  Return Value
                  Debug
                  Example Source
                  $debug->log('the four basic methods', 'log', 'info', 'warn', 'error');
                  $debug->info('User logged in', false);
                  $debug->warn('DROP TABLE', 'Students');
                  $debug->error('No Such Table', 'Students');
                  Example Output

                    • the four basic methods, log, info, warn, error
                    • User logged in = false
                    • DROP TABLE = Students
                    • No Such Table = Students
                    Supports substitution & formatting, see log() for examples
                    Changelog:
                    • v3.0: first param now gets htmlspecialchar()'d by default
                      use meta('sanitizeFirst', false) to allow html
                    group(mixed …$arg): Debug

                    Create a new inline group

                    Parameters
                    arg
                    label / values
                    Return Value
                    Debug
                    Meta options (see meta)
                    option description since
                    argsAsParams (true) 3.0
                    boldLabel (true) 3.0
                    hideIfEmpty (false) Group will be completely hidden (as opposed to collapsed) if it doesn't contain any log entries (or only contains hidden groups) 2.0
                    isFuncName (false) 3.0
                    level (null) "error", "info" or "warn" 2.0
                    ungroup (false) Group will be converted to log entry if 1 or fewer log entries 3.0
                    • To close the group, call groupEnd().
                    • If no params are passed, the group's label will default to the current function/method name, or "group" if not inside a function.
                    Example Source
                    $debug->log("This is the outer level");
                    doStuff();
                    $debug->log("Back to the outer level");
                    function doStuff() {
                        // we'll grab the debug instance with \bdk\Debug::getInstance()
                        $debug = \bdk\Debug::getInstance();
                        $debug->log("Level 2");
                        $debug->groupCollapsed('group', 'a', true, null);
                            $debug->log("Level 3");
                            $debug->warn("Level 3 warning");    // note: error & warn will uncollapse the groups they're in
                        $debug->groupEnd();
                        $found = isPlaneHere(6.7, 105.62);
                        $debug->info('found', $found);
                        $debug->log("Back to level 2");
                        $debug->group('I\'ll be hidden', $debug->meta('hideIfEmpty'));
                        $debug->groupEnd();
                        $debug->groupEnd();
                    }
                    function isPlaneHere($lat,$lon) {
                        // we'll use the static methods here
                        // note how additional params will appear formatted as if function args
                        \bdk\Debug::groupCollapsed(__FUNCTION__, $lat, $lon); // use _ prefix if using < v3.1
                        \bdk\Debug::log('Analyizing the data...'); // use _ prefix if using < v3.1
                        $return = false;
                        \bdk\Debug::groupEnd($return); // use _ prefix if using < v3.1
                        return $return;
                    }
                    Example Output

                      • This is the outer level
                      • doStuff
                        • Level 2
                        • group(a, true, null)
                          • Level 3
                          • Level 3 warning
                        • isPlaneHere(6.7, 105.62)
                          • Analyizing the data...
                          • return = false
                        • found = false
                        • Back to level 2
                      • Back to the outer level
                      groupCollapsed(mixed …$arg): Debug

                      Create a new inline group

                      Parameters
                      arg
                      label / values
                      Return Value
                      Debug
                      Description

                      Unlike group(), groupCollapsed(), will initially be collapsed

                      Meta options (see meta)
                      option description since
                      argsAsParams (true) 3.0
                      boldLabel (true) 3.0
                      hideIfEmpty (false) Group will be completely hidden (as opposed to collapsed) if it doesn't contain any log entries (or only contains hidden groups) 2.0
                      isFuncName (false) 3.0
                      level (null) "error", "info" or "warn" 2.0
                      ungroup (false) Group will be converted to log entry if 1 or fewer log entries 3.0
                      • To close the group, call groupEnd().
                      • If no params are passed, the group's label will default to the current function/method name, or "group" if not inside a function.
                      groupCollapsed() will be expanded if it contains a nested error or warn, or if groupUncollapse() was used
                      Example Source
                      $debug->log("This is the outer level");
                      doStuff();
                      $debug->log("Back to the outer level");
                      function doStuff() {
                          // we'll grab the debug instance with \bdk\Debug::getInstance()
                          $debug = \bdk\Debug::getInstance();
                          $debug->log("Level 2");
                          $debug->groupCollapsed('group', 'a', true, null);
                              $debug->log("Level 3");
                              $debug->warn("Level 3 warning");    // note: error & warn will uncollapse the groups they're in
                          $debug->groupEnd();
                          $found = isPlaneHere(6.7, 105.62);
                          $debug->info('found', $found);
                          $debug->log("Back to level 2");
                          $debug->group('I\'ll be hidden', $debug->meta('hideIfEmpty'));
                          $debug->groupEnd();
                          $debug->groupEnd();
                      }
                      function isPlaneHere($lat,$lon) {
                          // we'll use the static methods here
                          // note how additional params will appear formatted as if function args
                          \bdk\Debug::groupCollapsed(__FUNCTION__, $lat, $lon); // use _ prefix if using < v3.1
                          \bdk\Debug::log('Analyizing the data...'); // use _ prefix if using < v3.1
                          $return = false;
                          \bdk\Debug::groupEnd($return); // use _ prefix if using < v3.1
                          return $return;
                      }
                      Example Output

                        • This is the outer level
                        • doStuff
                          • Level 2
                          • group(a, true, null)
                            • Level 3
                            • Level 3 warning
                          • isPlaneHere(6.7, 105.62)
                            • Analyizing the data...
                            • return = false
                          • found = false
                          • Back to level 2
                        • Back to the outer level
                        groupEnd(mixed $value = bdk\Debug\Abstraction\Abstracter::UNDEFINED): Debug

                        Close current group

                        Parameters
                        value
                        (optional) "return" value
                        Return Value
                        Debug
                        Description

                        Every call to group(), groupCollapsed(), and groupSummary() should be paired with groupEnd()

                        The optional return value will be visible when the group is both expanded and collapsed.

                        Example Source
                        $debug->log("This is the outer level");
                        doStuff();
                        $debug->log("Back to the outer level");
                        function doStuff() {
                            // we'll grab the debug instance with \bdk\Debug::getInstance()
                            $debug = \bdk\Debug::getInstance();
                            $debug->log("Level 2");
                            $debug->groupCollapsed('group', 'a', true, null);
                                $debug->log("Level 3");
                                $debug->warn("Level 3 warning");    // note: error & warn will uncollapse the groups they're in
                            $debug->groupEnd();
                            $found = isPlaneHere(6.7, 105.62);
                            $debug->info('found', $found);
                            $debug->log("Back to level 2");
                            $debug->group('I\'ll be hidden', $debug->meta('hideIfEmpty'));
                            $debug->groupEnd();
                            $debug->groupEnd();
                        }
                        function isPlaneHere($lat,$lon) {
                            // we'll use the static methods here
                            // note how additional params will appear formatted as if function args
                            \bdk\Debug::groupCollapsed(__FUNCTION__, $lat, $lon); // use _ prefix if using < v3.1
                            \bdk\Debug::log('Analyizing the data...'); // use _ prefix if using < v3.1
                            $return = false;
                            \bdk\Debug::groupEnd($return); // use _ prefix if using < v3.1
                            return $return;
                        }
                        Example Output

                          • This is the outer level
                          • doStuff
                            • Level 2
                            • group(a, true, null)
                              • Level 3
                              • Level 3 warning
                            • isPlaneHere(6.7, 105.62)
                              • Analyizing the data...
                              • return = false
                            • found = false
                            • Back to level 2
                          • Back to the outer level
                          Changelog:
                          • v2.3: accepts $value parameter
                          groupSummary(int $priority = 0): Debug

                          Open a "summary" group

                          Description

                          Debug methods called from within a groupSummary will appear at the top of the log. Call groupEnd() to close the summary group

                          All groupSummary groups will appear together at the top of the output

                          Parameters
                          priority
                          (0) The higher the priority, the earlier the group will appear in output
                          Return Value
                          Debug
                          This method does not have a web console API equivalent.
                          Example Source
                          $debug->log('foo');
                          
                          $debug->groupSummary();
                          $debug->log('I\'m at the top of the log');
                          $debug->groupEnd();
                          
                          $debug->groupSummary(1);
                          // get the current git branch we're working on and display it
                          exec('git branch | grep \* | cut -d " " -f2', $gitCmdOutput);
                          $debug->log(
                              '%c<i class="fa fa-github" aria-hidden="true"></i>%s',
                              'font-size:1.5em; background-color:#ddd; padding:1px 3px;',
                              $gitCmdOutput[0],
                              $debug->meta('sanitizeFirst', false)
                          );
                          $debug->groupEnd();
                          
                          $debug->info('as of v3.0, the git branch is logged by default');
                          Example Output
                          • feature/groupSummary
                          • I'm at the top of the log

                          • foo
                          • as of v3.0, the git branch is logged by default
                          "Built in" & "Peak Memory Usage" are appended to the priority-1 group just before the log is output.
                          groupUncollapse(): Debug

                          Uncollapse ancestor groups

                          Description

                          This will only occur if cfg['collect'] is currently true

                          This method does not have a web console API equivalent.
                          Return Value
                          Debug
                          Note: error(), warn(), and any errors will also uncollapse groups
                          Example Source
                          $debug->groupCollapsed('Turtle 1');
                            $debug->groupCollapsed('Turtle 2');
                              $debug->groupCollapsed('Turtle 3');
                              $debug->log('Working on this bit of code');
                              $debug->log('it\'s inside all of these collapsed groups');
                              $debug->log('groupUncollapse() opens things up');
                              $debug->groupUncollapse();  // jaws of life to the rescue;
                              $debug->info('warn() and error() will also accomplish this');
                              $debug->groupEnd();
                            $debug->groupEnd();
                          $debug->groupEnd();
                          Example Output

                            • Turtle 1
                              • Turtle 2
                                • Turtle 3
                                  • Working on this bit of code
                                  • it's inside all of these collapsed groups
                                  • groupUncollapse() opens things up
                                  • warn() and error() will also accomplish this
                            info(mixed …$arg): Debug

                            Log some informative information

                            Parameters
                            arg
                            message / values
                            Return Value
                            Debug
                            Example Source
                            $debug->log('the four basic methods', 'log', 'info', 'warn', 'error');
                            $debug->info('User logged in', false);
                            $debug->warn('DROP TABLE', 'Students');
                            $debug->error('No Such Table', 'Students');
                            Example Output

                              • the four basic methods, log, info, warn, error
                              • User logged in = false
                              • DROP TABLE = Students
                              • No Such Table = Students
                              Supports substitution & formatting, see log() for examples
                              Changelog:
                              • v3.0: first param now gets htmlspecialchar()'d by default
                                use meta('sanitizeFirst', false) to allow html
                              log(mixed …$arg): Debug

                              Log general information

                              Parameters
                              arg
                              message / values
                              Return Value
                              Debug
                              Example Source
                              $debug->log('param1');
                              $debug->log('param1', 'param2');    // two params output as param1 = param2
                              $debug->log('param1', 'param2', 'param3'); // more than two params will be separated by ', '
                              $debug->log('string', 123, 123.4, '123.4', array('foo'=>'bar'), true, null); // types are styled
                              $debug->log('%cStyling:%c as of v%.1f: %csupports <a target="_blank" href="https://console.spec.whatwg.org/#formatter">styling and substitution</a>',
                                  'border:1px outset rgba(0,0,0,.15); border-radius:.33em; background:linear-gradient(to bottom, #fefcea 0%, #f1da36 100%); color:#330; text-shadow: 1px 1px 1px rgba(255,255,255,0.4); font-size:1.3em; font-weight:bold; padding:2px .6em;',
                                  '', // empty css... essentially clearing previous styling
                                  2.0,
                                  'border:#000 solid 1px; box-shadow:2px 1px 0px 0px #000; background-color:rgba(0,0,0,.15); padding:2px .33em; display:inline-block; margin-bottom: .25em;',
                                  $debug->meta('sanitizeFirst', false)
                              );
                              $array = array(
                                  'string' => 'foobar',
                                  'string_html' => '<span class="test">'."\r\n\t".'htmlspecialchar\'d &amp; whitespace shown</span>'."\n",
                                  'boolTrue' => true,
                                  'boolFalse' => false,
                                  'null' => null,
                                  'int' => 123,
                                  'now' => time(),    // hover to see formatted (int/float that's +/- 90 days is assumed to be a timestamp)
                                  'float' => 3.14159265,
                                  'infinity' => INF,
                                  'notANumber' => NAN,
                                  'numeric' => "123",
                                  'string_with_hidden' => "\xef\xbb\xbfPesky <abbr title=\"Byte-Order-Mark\">BOM</abbr>, control char (\x07), and non\xc2\xa0breaking space.",
                              );
                              $debug->log('array', $array);
                              Example Output

                                • param1
                                • param1 = param2
                                • param1, param2, param3
                                • string, 123, 123.4, 123.4, array(
                                  • foo=>bar
                                  )
                                  , true, null
                                • Styling: as of v2.0: supports styling and substitution
                                • array = array(
                                  • string=>foobar
                                  • string_html=><span class="test"> htmlspecialchar'd &amp; whitespace shown</span>
                                  • boolTrue=>true
                                  • boolFalse=>false
                                  • null=>null
                                  • int=>123
                                  • now=>1726171670
                                  • float=>3.14159265
                                  • infinity=>INF
                                  • notANumber=>NaN
                                  • numeric=>123
                                  • string_with_hidden=>\u{feff}Pesky <abbr title="Byte-Order-Mark">BOM</abbr>, control char (), and non\u{00a0}breaking space.
                                  )
                                assert(), log(), info(), warn(), & error() methods support formatting (aka substitution)
                                Changelog:
                                • v3.0: first param now gets htmlspecialchar()'d by default
                                  use meta('sanitizeFirst', false) to allow html
                                profile(string $name = null): Debug

                                Starts recording a performance profile

                                Parameters
                                name
                                Optional profile name
                                Return Value
                                Debug
                                How it works:
                                • Uses PHP's register_tick_function() under the hood… which requires declare(ticks=1); be declared in any code-block/file that contains funcitons/methods/code to be profiled. (yuck)
                                • enableProfiling to the rescude
                                Example Source
                                /*
                                    enablePofiling must be set before files containing code to be profiled are included
                                    (should be set when instantiating PHPDebugConsole)
                                */
                                $debug->setCfg('enableProfiling', true);
                                $debug->profile();
                                // build a html form
                                //    this is real-world.  guess the framework
                                //    how many classes and calls does it take to build a form?!
                                // ...
                                $debug->profileEnd();
                                
                                Example Output

                                  • Profile 'Profile 1' started
                                  • Profile 'Profile 1' Results
                                     callstotalTimeownTime
                                    CBaseController::beginWidget10.6497570.016487
                                    CModule::__get350.3743570.001115
                                    BootActiveForm::inputRow340.3723180.002285
                                    BootInput::run340.3495550.005287
                                    CModel::getValidators1310.3051930.087937
                                    CHtml::openTag340.2728060.001669
                                    BootInput::getLabel270.243550.001747
                                    BootActiveForm::dropDownListRow80.1663880.000251
                                    CListIterator::next28510.1620770.162077
                                    CModel::isAttributeRequired730.1589480.005975
                                    BootActiveForm::textFieldRow180.1587010.000439
                                    CActiveForm::dropDownList90.1197840.000368
                                    CHtml::activeDropDownList90.1168680.00125
                                    CHtml::tag3720.1145030.012069
                                    CHtml::resolveValue400.1118830.026433
                                    CHtml::renderAttributes4090.1112580.111258
                                    CActiveForm::textField190.0733670.000563
                                    CHtml::activeTextField190.0671020.00162
                                    CHtml::activeInputField230.0613790.004848
                                    WForm::label270.0490110.002613
                                    CModel::createValidators10.0414180.000133
                                    BootActiveForm::checkBoxRow70.0406090.000235
                                    buildCustField30.0374630.001219
                                    AppSettingManager::get40.0313540.000555
                                    MyModel::rules10.0310990.000325
                                    WForm::resolveArgs480.027970.010955
                                    ValidationRule::model10.0256956.5E-5
                                    YiiBase::log160.0250590.004995
                                    CList::getIterator1510.0221660.005364
                                    CLogger::log160.0200650.002577
                                    CComponent::__get350.0194560.002591
                                    CDbCommand::getText160.0191840.00109
                                    WForm::checkBox70.0189220.000215
                                    CActiveForm::label270.0181920.001984
                                    CActiveRecord::model10.0178529.1E-5
                                    CLogger::flush160.0174880.001229
                                    CListIterator::__construct1510.0168020.016802
                                    AccessManager::isAllowed20.0167740.000702
                                    include180.0164720.010252
                                    CEvent::__construct160.0162590.001548
                                    CHtml::activeLabel270.0162080.004621
                                    CActiveRecordMetaData::__construct10.0161780.000325
                                    CActiveForm::checkBox70.0158750.000245
                                    CDbSchema::getTable10.0158530.000114
                                    CMysqlSchema::loadTable10.0157396.8E-5
                                    CMysqlSchema::findColumns10.0155620.000515
                                    CActiveRecord::query20.0151920.000198
                                    WForm::resolveName990.0147460.014746
                                    CComponent::raiseEvent160.0147110.00158
                                    CDbConnection::createCommand40.0138270.000416
                                    CWidgetFactory::createWidget340.0136040.009948
                                    CDbCommand::queryRow20.0123910.000661
                                    CDbCommand::__construct40.0122410.001517
                                    CModule::getComponent20.0117870.000314
                                    AccessRole::isAllowed100.011730.000417
                                    CHtml::label270.0115870.003098
                                    SAML2_autoload80.0114580.00304
                                    BootActiveForm::error340.0108590.006517
                                    CHtml::activeCheckBox70.010530.000966
                                    CDbCommand::queryInternal20.0104790.001404
                                    ValidationRuleManager::findOptionsByModel10.0102833.9E-5
                                    CValidator::createValidator200.0100670.004505
                                    WForm::hiddenField40.0095780.000119
                                    CLogRouter::collectLogs160.0095280.003129
                                    CActiveRecord::find10.009266.0E-5
                                    spl_autoload_call60.0090630.000206
                                    YiiBase::import100.0088990.001484
                                    CBaseController::createWidget10.0088952.8E-5
                                    CHtml::hiddenField80.0084330.000782
                                    WForm::resolveModel560.0078340.007834
                                    CWebApplication::getWidgetFactory10.007699.8E-5
                                    BootActiveForm::checkBoxListRow10.0075692.4E-5
                                    YiiBase::autoload80.007520.000231
                                    WebUser::__get120.0073430.000347
                                    CLogRoute::collectLogs320.0063990.00285
                                    AccessRule::match100.0063490.002645
                                    WForm::resolveAttribute1010.0059550.005955
                                    CHtml::inputField110.0058290.001498
                                    CHtml::resolveNameID400.0056240.005476
                                    YiiBase::trace30.0055790.000144
                                    WebUser::_getModel200.005440.00057
                                    CWebUser::__get200.005260.000473
                                    ActiveRecord::__get650.0052290.004732
                                    BootActiveForm::checkBoxList10.0051453.3E-5
                                    WebUser::getState390.0050630.001931
                                    CWebUser::hasState200.0047870.001617
                                    BootActiveForm::inputsList10.0044150.000679
                                    BootActiveForm::getErrorHtml340.0043420.002017
                                    AppSettingManager::arrayPath180.0043080.004308
                                    YiiBase::getPathOfAlias30.003930.001696
                                    WForm::resolveLabel270.003620.001737
                                    CLogger::getLogs320.003550.00355
                                    BootInput::init340.0032610.003261
                                    CWebUser::getIsGuest200.0032580.000518
                                    YiiBase::createComponent20.0032530.000316
                                    WForm::textField10.0032446.1E-5
                                    CActiveForm::hiddenField40.0031780.000103
                                    CWebUser::getState390.0031320.003132
                                    CHtml::activeHiddenField40.0030750.000293
                                    WForm::dropDownList10.003054.9E-5
                                    CActiveRecord::getAttributeLabel430.0030.003
                                    CHtml::checkBox30.0029530.000686
                                    CHtml::resolveName430.002940.00294
                                    AccessManager::_getUserRole20.0024688.8E-5
                                    CMysqlSchema::createColumn40.0024140.000723
                                    WebUser::getDefaultRoleContexts100.0022690.000245
                                    CDbCommandBuilder::createFindCommand20.0020990.000552
                                    WebUser::getAllowedRoles100.0020240.000743
                                    CWidget::__construct340.0019520.001952
                                    CDbColumnSchema::init50.0017980.000444
                                    CComponent::__isset200.0016120.001612
                                    BootActiveForm::init10.0011776.9E-5
                                    CList::insertAt210.0011170.001117
                                    CActiveForm::init10.0011084.6E-5
                                    CHtml::beginForm10.0009970.000139
                                    WebUser::getDefaultRole100.0009020.000247
                                    CHtml::normalizeUrl10.0008586.8E-5
                                    CMysqlColumnSchema::extractLimit50.0007960.000165
                                    CDbCommand::prepare60.0006790.000385
                                    CDbColumnSchema::extractLimit50.0006310.000631
                                    ValidationRule::afterFind20.0006126.0E-5
                                    CDbCommand::setText40.0005140.000267
                                    CDbCommand::bindValue20.0005080.000105
                                    CDbCriteria::compare20.0005010.000357
                                    CActiveRecord::getPrimaryKey20.0003280.000189
                                    call_user_func20.0003285.5E-5
                                    CActiveRecord::applyScopes20.0003130.000134
                                    CMysqlColumnSchema::extractType50.0003110.000311
                                    CDbSchema::quoteColumnName50.0002830.000283
                                    MyModel::getReferenceName20.0002736.3E-5
                                    CDbConnection::setActive40.0002720.000272
                                    CComponent::hasEventHandler40.0002630.000263
                                    CDbCommand::cancel40.0002470.000247
                                    CMysqlColumnSchema::extractDefault20.0002475.7E-5
                                    CApplicationComponent::init20.0002199.3E-5
                                    CComponent::__set20.0002130.000108
                                    CDbCommandBuilder::applyLimit20.0001960.000196
                                    ActiveRecord::init20.0001955.9E-5
                                    CActiveRecord::beforeFind20.0001915.4E-5
                                    CDbColumnSchema::extractDefault20.000199.6E-5
                                    CActiveRecord::afterFind20.0001835.7E-5
                                    CActiveRecord::getDbCriteria20.0001790.000179
                                    CComponent::attachBehaviors30.0001780.000178
                                    CActiveRecord::setAttribute20.0001690.000169
                                    CDbCommandBuilder::ensureTable20.0001570.000157
                                    CWidgetFactory::init10.0001514.2E-5
                                    CDbCriteria::addCondition20.0001440.000144
                                    ActiveRecord::attachEvents20.0001360.000136
                                    CDbCommandBuilder::createCriteria20.0001320.000132
                                    CList::__construct10.000127.2E-5
                                    CDbConnection::getPdoType20.0001190.000119
                                    CModel::setScenario20.0001160.000116
                                    CMysqlSchema::resolveTableNames10.0001090.000109
                                    usort10.0001042.2E-5
                                    CHttpRequest::getUrl19.8E-52.5E-5
                                    CDbColumnSchema::typecast19.4E-59.4E-5
                                    {closure}18.2E-58.2E-5
                                    CHttpRequest::getRequestUri17.3E-57.3E-5
                                    YiiBase::setPathOfAlias16.4E-56.4E-5
                                    CDbCriteria::__construct16.1E-56.1E-5
                                    uniqueMultiColumnValidator::setCaseSensitiveAttr15.5E-55.5E-5
                                    CWidget::setId15.0E-55.0E-5
                                    CList::setReadOnly14.8E-54.8E-5
                                     0.649763
                                  Changelog:
                                  • v2.3
                                  profileEnd(string $name = null): Debug

                                  Stops recording profile info & adds info to the log

                                  Description
                                  • if name is passed and it matches the name of a profile being recorded, then that profile is stopped.
                                  • if name is passed and it does not match the name of a profile being recorded, nothing will be done
                                  • if name is not passed, the most recently started profile is stopped (named, or non-named).
                                  Parameters
                                  name
                                  Optional profile name
                                  Return Value
                                  Debug
                                  Example Source
                                  /*
                                      enablePofiling must be set before files containing code to be profiled are included
                                      (should be set when instantiating PHPDebugConsole)
                                  */
                                  $debug->setCfg('enableProfiling', true);
                                  $debug->profile();
                                  // build a html form
                                  //    this is real-world.  guess the framework
                                  //    how many classes and calls does it take to build a form?!
                                  // ...
                                  $debug->profileEnd();
                                  
                                  Example Output

                                    • Profile 'Profile 1' started
                                    • Profile 'Profile 1' Results
                                       callstotalTimeownTime
                                      CBaseController::beginWidget10.6497570.016487
                                      CModule::__get350.3743570.001115
                                      BootActiveForm::inputRow340.3723180.002285
                                      BootInput::run340.3495550.005287
                                      CModel::getValidators1310.3051930.087937
                                      CHtml::openTag340.2728060.001669
                                      BootInput::getLabel270.243550.001747
                                      BootActiveForm::dropDownListRow80.1663880.000251
                                      CListIterator::next28510.1620770.162077
                                      CModel::isAttributeRequired730.1589480.005975
                                      BootActiveForm::textFieldRow180.1587010.000439
                                      CActiveForm::dropDownList90.1197840.000368
                                      CHtml::activeDropDownList90.1168680.00125
                                      CHtml::tag3720.1145030.012069
                                      CHtml::resolveValue400.1118830.026433
                                      CHtml::renderAttributes4090.1112580.111258
                                      CActiveForm::textField190.0733670.000563
                                      CHtml::activeTextField190.0671020.00162
                                      CHtml::activeInputField230.0613790.004848
                                      WForm::label270.0490110.002613
                                      CModel::createValidators10.0414180.000133
                                      BootActiveForm::checkBoxRow70.0406090.000235
                                      buildCustField30.0374630.001219
                                      AppSettingManager::get40.0313540.000555
                                      MyModel::rules10.0310990.000325
                                      WForm::resolveArgs480.027970.010955
                                      ValidationRule::model10.0256956.5E-5
                                      YiiBase::log160.0250590.004995
                                      CList::getIterator1510.0221660.005364
                                      CLogger::log160.0200650.002577
                                      CComponent::__get350.0194560.002591
                                      CDbCommand::getText160.0191840.00109
                                      WForm::checkBox70.0189220.000215
                                      CActiveForm::label270.0181920.001984
                                      CActiveRecord::model10.0178529.1E-5
                                      CLogger::flush160.0174880.001229
                                      CListIterator::__construct1510.0168020.016802
                                      AccessManager::isAllowed20.0167740.000702
                                      include180.0164720.010252
                                      CEvent::__construct160.0162590.001548
                                      CHtml::activeLabel270.0162080.004621
                                      CActiveRecordMetaData::__construct10.0161780.000325
                                      CActiveForm::checkBox70.0158750.000245
                                      CDbSchema::getTable10.0158530.000114
                                      CMysqlSchema::loadTable10.0157396.8E-5
                                      CMysqlSchema::findColumns10.0155620.000515
                                      CActiveRecord::query20.0151920.000198
                                      WForm::resolveName990.0147460.014746
                                      CComponent::raiseEvent160.0147110.00158
                                      CDbConnection::createCommand40.0138270.000416
                                      CWidgetFactory::createWidget340.0136040.009948
                                      CDbCommand::queryRow20.0123910.000661
                                      CDbCommand::__construct40.0122410.001517
                                      CModule::getComponent20.0117870.000314
                                      AccessRole::isAllowed100.011730.000417
                                      CHtml::label270.0115870.003098
                                      SAML2_autoload80.0114580.00304
                                      BootActiveForm::error340.0108590.006517
                                      CHtml::activeCheckBox70.010530.000966
                                      CDbCommand::queryInternal20.0104790.001404
                                      ValidationRuleManager::findOptionsByModel10.0102833.9E-5
                                      CValidator::createValidator200.0100670.004505
                                      WForm::hiddenField40.0095780.000119
                                      CLogRouter::collectLogs160.0095280.003129
                                      CActiveRecord::find10.009266.0E-5
                                      spl_autoload_call60.0090630.000206
                                      YiiBase::import100.0088990.001484
                                      CBaseController::createWidget10.0088952.8E-5
                                      CHtml::hiddenField80.0084330.000782
                                      WForm::resolveModel560.0078340.007834
                                      CWebApplication::getWidgetFactory10.007699.8E-5
                                      BootActiveForm::checkBoxListRow10.0075692.4E-5
                                      YiiBase::autoload80.007520.000231
                                      WebUser::__get120.0073430.000347
                                      CLogRoute::collectLogs320.0063990.00285
                                      AccessRule::match100.0063490.002645
                                      WForm::resolveAttribute1010.0059550.005955
                                      CHtml::inputField110.0058290.001498
                                      CHtml::resolveNameID400.0056240.005476
                                      YiiBase::trace30.0055790.000144
                                      WebUser::_getModel200.005440.00057
                                      CWebUser::__get200.005260.000473
                                      ActiveRecord::__get650.0052290.004732
                                      BootActiveForm::checkBoxList10.0051453.3E-5
                                      WebUser::getState390.0050630.001931
                                      CWebUser::hasState200.0047870.001617
                                      BootActiveForm::inputsList10.0044150.000679
                                      BootActiveForm::getErrorHtml340.0043420.002017
                                      AppSettingManager::arrayPath180.0043080.004308
                                      YiiBase::getPathOfAlias30.003930.001696
                                      WForm::resolveLabel270.003620.001737
                                      CLogger::getLogs320.003550.00355
                                      BootInput::init340.0032610.003261
                                      CWebUser::getIsGuest200.0032580.000518
                                      YiiBase::createComponent20.0032530.000316
                                      WForm::textField10.0032446.1E-5
                                      CActiveForm::hiddenField40.0031780.000103
                                      CWebUser::getState390.0031320.003132
                                      CHtml::activeHiddenField40.0030750.000293
                                      WForm::dropDownList10.003054.9E-5
                                      CActiveRecord::getAttributeLabel430.0030.003
                                      CHtml::checkBox30.0029530.000686
                                      CHtml::resolveName430.002940.00294
                                      AccessManager::_getUserRole20.0024688.8E-5
                                      CMysqlSchema::createColumn40.0024140.000723
                                      WebUser::getDefaultRoleContexts100.0022690.000245
                                      CDbCommandBuilder::createFindCommand20.0020990.000552
                                      WebUser::getAllowedRoles100.0020240.000743
                                      CWidget::__construct340.0019520.001952
                                      CDbColumnSchema::init50.0017980.000444
                                      CComponent::__isset200.0016120.001612
                                      BootActiveForm::init10.0011776.9E-5
                                      CList::insertAt210.0011170.001117
                                      CActiveForm::init10.0011084.6E-5
                                      CHtml::beginForm10.0009970.000139
                                      WebUser::getDefaultRole100.0009020.000247
                                      CHtml::normalizeUrl10.0008586.8E-5
                                      CMysqlColumnSchema::extractLimit50.0007960.000165
                                      CDbCommand::prepare60.0006790.000385
                                      CDbColumnSchema::extractLimit50.0006310.000631
                                      ValidationRule::afterFind20.0006126.0E-5
                                      CDbCommand::setText40.0005140.000267
                                      CDbCommand::bindValue20.0005080.000105
                                      CDbCriteria::compare20.0005010.000357
                                      CActiveRecord::getPrimaryKey20.0003280.000189
                                      call_user_func20.0003285.5E-5
                                      CActiveRecord::applyScopes20.0003130.000134
                                      CMysqlColumnSchema::extractType50.0003110.000311
                                      CDbSchema::quoteColumnName50.0002830.000283
                                      MyModel::getReferenceName20.0002736.3E-5
                                      CDbConnection::setActive40.0002720.000272
                                      CComponent::hasEventHandler40.0002630.000263
                                      CDbCommand::cancel40.0002470.000247
                                      CMysqlColumnSchema::extractDefault20.0002475.7E-5
                                      CApplicationComponent::init20.0002199.3E-5
                                      CComponent::__set20.0002130.000108
                                      CDbCommandBuilder::applyLimit20.0001960.000196
                                      ActiveRecord::init20.0001955.9E-5
                                      CActiveRecord::beforeFind20.0001915.4E-5
                                      CDbColumnSchema::extractDefault20.000199.6E-5
                                      CActiveRecord::afterFind20.0001835.7E-5
                                      CActiveRecord::getDbCriteria20.0001790.000179
                                      CComponent::attachBehaviors30.0001780.000178
                                      CActiveRecord::setAttribute20.0001690.000169
                                      CDbCommandBuilder::ensureTable20.0001570.000157
                                      CWidgetFactory::init10.0001514.2E-5
                                      CDbCriteria::addCondition20.0001440.000144
                                      ActiveRecord::attachEvents20.0001360.000136
                                      CDbCommandBuilder::createCriteria20.0001320.000132
                                      CList::__construct10.000127.2E-5
                                      CDbConnection::getPdoType20.0001190.000119
                                      CModel::setScenario20.0001160.000116
                                      CMysqlSchema::resolveTableNames10.0001090.000109
                                      usort10.0001042.2E-5
                                      CHttpRequest::getUrl19.8E-52.5E-5
                                      CDbColumnSchema::typecast19.4E-59.4E-5
                                      {closure}18.2E-58.2E-5
                                      CHttpRequest::getRequestUri17.3E-57.3E-5
                                      YiiBase::setPathOfAlias16.4E-56.4E-5
                                      CDbCriteria::__construct16.1E-56.1E-5
                                      uniqueMultiColumnValidator::setCaseSensitiveAttr15.5E-55.5E-5
                                      CWidget::setId15.0E-55.0E-5
                                      CList::setReadOnly14.8E-54.8E-5
                                       0.649763
                                    Changelog:
                                    • v2.3
                                    table(mixed …$arg): Debug

                                    Output an array or object as a table

                                    Parameters

                                    Takes up to 3 arguments which may be passed in arbitrary order

                                    • The first encountered array (or Traversable object) is the table data.
                                    • The first encountered string is treated as a table caption (javascript API does not support caption)
                                    • If a second array is encountered, it will be used to specify columns to display
                                    Meta options
                                    totalCols (array) columns that should be summed
                                    sortable (true) should table be sortable by clicking on headers?
                                    Example Source
                                    $list = array(
                                        // note different order of keys / not all rows have all cols
                                        array('userId'=>1, 'name'=>'Bob', 'sex'=>'M', 'naughty'=>false),
                                        array('userId'=>10, 'naughty'=>true, 'name'=>'Sally', 'extracol' => 'yes', 'sex'=>'F'),
                                        array('userId'=>2, 'name'=>'Fred', 'sex'=>'M', 'naughty'=>false),
                                    );
                                    $debug->table('people', $list);
                                    $debug->table('people', $list, array('userId', 'name', 'sex'));
                                    $debug->log('people', $list);
                                    $debug->table(array(
                                        'foo' => 'bar',
                                        'slim' => 'jim',
                                    ));
                                    Example Output

                                      • people
                                         userIdnamesexnaughtyextracol
                                        01BobMfalse
                                        110SallyFtrueyes
                                        22FredMfalse
                                      • people
                                         userIdnamesex
                                        01BobM
                                        110SallyF
                                        22FredM
                                      • people = array(
                                        • 0=>array(
                                          • userId=>1
                                          • name=>Bob
                                          • sex=>M
                                          • naughty=>false
                                          )
                                        • 1=>array(
                                          • userId=>10
                                          • naughty=>true
                                          • name=>Sally
                                          • extracol=>yes
                                          • sex=>F
                                          )
                                        • 2=>array(
                                          • userId=>2
                                          • name=>Fred
                                          • sex=>M
                                          • naughty=>false
                                          )
                                        )
                                      •  value
                                        foobar
                                        slimjim

                                      When output as HTML (as above), the table is sortable by clicking on headers.

                                      Changelog:
                                      • v2.1: properly handles Traversable as param
                                      • v2.0: properly handles array of objects (objects can implement Traversable)
                                      time(string $label = null[, float $duration = null]): bdk\Debug

                                      Start a timer identified by label

                                      Parameters
                                      label
                                      unique label
                                      duration
                                      (optional) duration (in seconds). Use this param to log a duration obtained externally.
                                      Return Value
                                      bdk\Debug
                                      Description

                                      Label passed

                                      • if doesn't exist: starts timer
                                      • if does exist: unpauses (does not reset)

                                      Label not passed

                                      • timer will be added to a no-label stack

                                      Does not append log (unless duration is passed).

                                      Use timeEnd or timeGet to get time

                                      Example Source
                                      $debug->time('timer a');
                                      usleep(100);
                                      $debug->time();     // stack: 0
                                      usleep(100);
                                      $debug->time();     // stack: 1
                                      usleep(100);
                                      $debug->timeEnd();  // stack: 1
                                      usleep(100);
                                      $debug->timeEnd('timer a'); // pauses "timer a" and outputs the running time (does not "end" timer)
                                      usleep(100);
                                      $debug->timeEnd();  // stack: 0
                                      $debug->timeEnd('timer a'); // no change... timer not running
                                      Example Output

                                        • time: 414.8483 μs
                                        • timer a: 1.7529 ms
                                        • time: 2.0959 ms
                                        • timer a: 1.7529 ms
                                        Changelog:
                                        • v3.0: duration argument added
                                        timeEnd(string $label = null[, bool $log = true[, bool|auto $return = auto]]): bdk\Debug|float|false

                                        Behaves like a stopwatch.. logs and (optionally) returns running time

                                        Parameters
                                        label
                                        (optional) unique label
                                        log
                                        (true) log it, or return only if passed, takes precedence over silent meta val
                                        return
                                        ('auto') whether to return the value (vs returning $this)) 'auto' : !$log
                                        Return Value
                                        bdk\Debug|float|false
                                        The duration (in sec).

                                        Meta options

                                        precision
                                        (4) how many decimal places
                                        silent
                                        (false) only return / don't log
                                        template
                                        '%label: %time'
                                        unit
                                        ('auto'), 'sec', 'ms', or 'us'
                                        • If label is passed, the timer is paused. Additional calls to timeEnd('label') will return the same value until unpaused with time('label')
                                        • If no label is passed, timer is removed from a timer stack and logged
                                        Example Source
                                        $debug->time('timer a');
                                        usleep(100);
                                        $debug->time();     // stack: 0
                                        usleep(100);
                                        $debug->time();     // stack: 1
                                        usleep(100);
                                        $debug->timeEnd();  // stack: 1
                                        usleep(100);
                                        $debug->timeEnd('timer a'); // pauses "timer a" and outputs the running time (does not "end" timer)
                                        usleep(100);
                                        $debug->timeEnd();  // stack: 0
                                        $debug->timeEnd('timer a'); // no change... timer not running
                                        Example Output

                                          • time: 414.8483 μs
                                          • timer a: 1.7529 ms
                                          • time: 2.0959 ms
                                          • timer a: 1.7529 ms
                                          Changelog:
                                          • v3.0: returnOrTemplate & precision arguments removed.
                                            New meta options: precision, silent, template, & unit
                                          timeGet(string $label = null[, bool $log = true[, bool|auto $return = auto]]): bdk\Debug|float|false

                                          Log/get the running time without stopping/pausing the timer

                                          Parameters
                                          label
                                          (optional) unique label
                                          log
                                          (true) log it
                                          return
                                          ('auto') whether to return the value (vs returning $this)) 'auto' : !$log
                                          Return Value
                                          bdk\Debug|float|false
                                          The duration (in sec). false if specified label does not exist

                                          Meta options

                                          precision
                                          (4) how many decimal places
                                          silent
                                          (false) only return / don't log
                                          template
                                          '%label: %time'
                                          unit
                                          ('auto'), 'sec', 'ms', or 'us'
                                          This method does not have a web console API equivalent.
                                          Example: How to "collect" the time spent inside a function
                                          queryDb('INSERT INTO student (id, name, age) VALUES ("1", "alan", 28)');
                                          // other stuff
                                          queryDb('SELECT * FROM student ORDER BY age');
                                          // other stuff etc
                                          $debug->timeEnd('query db');    // total time spent querying
                                          
                                          function queryDb($query) {
                                              $debug = \bdk\Debug::getInstance();
                                              $debug->groupCollapsed(__FUNCTION__, $query);
                                              $debug->time('query db');           // start / un-pause
                                              // query code omitted
                                              $debug->timeEnd('query db', $debug->meta('silent'));
                                              $debug->groupEnd();
                                              return $results;
                                          }
                                          Example Output

                                            • queryDb(INSERT INTO student (id, name, age) VALUES ("1", "alan", 28))
                                              • queryDb(SELECT * FROM student ORDER BY age)
                                                • query db: 1.0011 ms
                                                Changelog:
                                                • v3.0: returnOrTemplate & precision arguments removed.
                                                  New meta options: precision, silent, template, & unit
                                                timeLog(string $label = null[, $args = null]): bdk\Debug

                                                Logs the current value of a timer that was previously started via time()

                                                Parameters
                                                label
                                                (optional) unique label
                                                args
                                                Return Value
                                                bdk\Debug
                                                Description

                                                also logs additional arguments

                                                Example Source
                                                $debug->time('timer a');
                                                usleep(100);
                                                $debug->timeLog('timer a', 'foo', array('foo'=>'bar'));
                                                usleep(100);
                                                $debug->log('other things happen');
                                                // always logs time since timer last started/unpaused
                                                $debug->timeLog('timer a', 'bar', array('bar'=>'baz'));
                                                Example Output

                                                  • timer a: 2.0928 ms, foo, array(
                                                    • foo=>bar
                                                    )
                                                  • other things happen
                                                  • timer a: 3.1958 ms, bar, array(
                                                    • bar=>baz
                                                    )
                                                  Changelog:
                                                  • v2.3
                                                  trace(bool $inclContext = false[, string $caption = trace]): Debug

                                                  Log a stack trace

                                                  Description

                                                  Essentially PHP's debug_backtrace(), but displayed as a table

                                                  Params may be passed in any order

                                                  Parameters
                                                  inclContext
                                                  (false) Include code snippet
                                                  caption
                                                  ('trace') Specify caption for the trace table
                                                  Return Value
                                                  Debug
                                                  Example Source
                                                  function func1() {
                                                      call_user_func('func2');
                                                  }
                                                  
                                                  function func2() {
                                                      $closure = function () {
                                                          \bdk\Debug::trace(); // use _ prefix if using < v3.1
                                                      };
                                                      $closure();
                                                  }
                                                  
                                                  $debug->alert('This example is pretty weak', 'info');
                                                  func1();
                                                  $debug->info('sorting is disabled for trace tables');
                                                  Example Output

                                                    • trace
                                                       filelinefunction
                                                      0/path/to/mypage.inc.php7
                                                      1/path/to/mypage.inc.php9{closure}
                                                      2/path/to/mypage.inc.php2func2
                                                      3/path/to/mypage.inc.php13func1
                                                    • sorting is disabled for trace tables
                                                    Changelog:
                                                    • v3.3: added limit argument
                                                    varDump(mixed …$arg)

                                                    Dump values to output

                                                    Description

                                                    Similar to php's var_dump(). Dump values immediately

                                                    Parameters
                                                    arg
                                                    message / values
                                                    Example Source
                                                    echo '<p>Addicted to spuds</p>';
                                                    $result = $oven->bake('potato');
                                                    \bdk\Debug::varDump('result', $result);
                                                    echo '<p>can\'t get enough</p>';
                                                    Example Output

                                                    Addicted to spuds

                                                    "result" = array(
                                                        [food] => "potato"
                                                        [temperature] => 400
                                                        [buttery] => true
                                                    )

                                                    can't get enough

                                                    Changelog:
                                                    • v3.1
                                                    warn(mixed …$arg): Debug

                                                    Log a warning

                                                    Parameters
                                                    arg
                                                    message / values
                                                    Return Value
                                                    Debug
                                                    Example Source
                                                    $debug->log('the four basic methods', 'log', 'info', 'warn', 'error');
                                                    $debug->info('User logged in', false);
                                                    $debug->warn('DROP TABLE', 'Students');
                                                    $debug->error('No Such Table', 'Students');
                                                    Example Output

                                                      • the four basic methods, log, info, warn, error
                                                      • User logged in = false
                                                      • DROP TABLE = Students
                                                      • No Such Table = Students
                                                      Supports substitution & formatting, see log() for examples
                                                      Changelog:
                                                      • v3.0: first param now gets htmlspecialchar()'d by default
                                                        use meta('sanitizeFirst', false) to allow html

                                                      Config & Utility methods

                                                      addPlugin(AssetProviderInterface|SubscriberInterface $plugin[, string $name = null]): Debug

                                                      Extend debug with a plugin

                                                      Parameters
                                                      plugin
                                                      Object implementing SubscriberInterface and/or AssetProviderInterface
                                                      name
                                                      Optional plugin name
                                                      Return Value
                                                      Debug
                                                      phpDoc
                                                      throws: InvalidArgumentException
                                                      getCfg(string $path = null): mixed

                                                      Retrieve a configuration value

                                                      Parameters
                                                      path
                                                      what to get
                                                      Return Value
                                                      mixed
                                                      value
                                                      Example Source
                                                      $debug->log('output', $debug->getCfg('output'));
                                                      $debug->log('route', $debug->getCfg('route'));
                                                      $debug->log('errorHandler.emailer.emailMin', $debug->getCfg('errorHandler.emailer.emailMin'));
                                                      Example Output

                                                        • output = true
                                                        • route = html
                                                        • errorHandler.emailer.emailMin = 240
                                                        getChannel(string|array $name[, array $config = array()]): Debug

                                                        Return a named sub-instance... if channel does not exist, it will be created

                                                        Parameters
                                                        name
                                                        channel name (or channel path)
                                                        config
                                                        channel specific configuration
                                                        Return Value
                                                        Debug
                                                        new or existing Debug instance
                                                        • Initial config inherited from parent
                                                        • HTML output: channel toggle checkboxes will be available if more than one channel is output
                                                        • Channels get a new eventManager instance\bdk\Debug::EVENT_LOG, \bdk\Debug::EVENT_OBJ_ABSTRACT_START, and \bdk\Debug::EVENT_OBJ_ABSTRACT_END events "bubble" up ancestor channels.
                                                        Example Source
                                                        $seinfeld = $debug->getChannel('seinfeld');
                                                        $debug->log('This is Unix. I know this!');
                                                        $seinfeld->log('I always wanted to pretend I was an architect');
                                                        $debug->info('note that log entries nested inside a different channel\'s groups will not be hidden when the parent channel is hidden');
                                                        $seinfeld->group('The Bizarro Jerry');
                                                            $seinfeld->log('You got a question? You ask the 8-ball.');
                                                            $debug->log('Use SQL to corrupt their databases.');
                                                        $seinfeld->groupEnd();
                                                        $debug->group('Swordfish');
                                                            $seinfeld->log('just remember, it\'s not a lie if you believe it.');
                                                            $debug->log('Where I can hook up my modem?');
                                                        $debug->groupEnd();
                                                        Example Output
                                                        • The above channel toggles are rendered much more attractively in the full debug output. See the main example attached to bottom of viewport

                                                        • This is Unix. I know this!
                                                        • I always wanted to pretend I was an architect
                                                        • note that log entries nested inside a different channel's groups will not be hidden when the parent channel is hidden
                                                        • The Bizarro Jerry
                                                          • You got a question? You ask the 8-ball.
                                                          • Use SQL to corrupt their databases.
                                                        • Swordfish
                                                          • just remember, it's not a lie if you believe it.
                                                          • Where I can hook up my modem?
                                                        Changelog:
                                                        • v2.3
                                                        getHeaders(): array

                                                        Get and clear debug headers that need to be output

                                                        Return Value
                                                        array
                                                        headerName => value array

                                                        By default, response headers (ie generated by chromeLogger, FirePHP, or serverLog) are automatically set.

                                                        When working with frameworks or a PSR-7 implementation, you may want to deal with headers differently.

                                                        To use this method:

                                                        • set outputHeaders = false. This will prevent headers from being set automatically
                                                        • After output(), you can call getHeaders()
                                                        Example Source
                                                        $debug = new \bdk\Debug(array(
                                                            // use collect/output combo or key
                                                            'collect' => true,  // turn logging on
                                                            'output' => true,   // output() should process / return the log
                                                            'route' => 'chromeLogger',
                                                            'outputHeaders' => false, // we'll need to deal with headers manually
                                                        ));
                                                        /*
                                                            either call output() manually and then call getHeaders()
                                                            or, subscribe to \bdk\Debug::EVENT_OUTPUT (as we're doing here) with a low priority
                                                            (needs to execute after other subscribers so that headers have been created)
                                                            and get the headers from within the subscriber
                                                        */
                                                        $debug->eventManager->subscribe(\bdk\Debug::EVENT_OUTPUT, function(\bdk\PubSub\Event $event) {
                                                            $debug = $event->getSubject();
                                                            $headers = $debug->getHeaders(); // get and clear headers
                                                            // var dumping headers for example... (debug already output)
                                                            \bdk\Debug::varDump($headers);
                                                            var_dump($headers);
                                                        
                                                            foreach ($headers as $nameAndValue) {
                                                                header($nameAndValue[0].': '.$nameAndValue[1]);
                                                            }
                                                        }, -1);
                                                        $debug->log('hello world');
                                                        Example Output
                                                        array(
                                                            [0] => array(
                                                                [0] => "X-ChromeLogger-Data"
                                                                [1] => "eyJ2ZXJzaW9uIjoiMy4zIiwiY29sdW1ucyI6WyJsb2ciLCJiYWNrdHJhY2UiLCJ0eXBlIl0sInJvd3MiOltbWyJQSFAiLCJHRVQgaHR0cHM6Ly9sb2NhbC5icmFka2VudC5jb20vcGhwL2RlYnVnLzMuMj9j[112 more bytes (not logged)]"
                                                            )
                                                        )
                                                        Changelog:
                                                        • v2.3
                                                        static meta(mixed …$arg = null): array

                                                        "metafy" value/values

                                                        Accepts:

                                                        • meta(array $values): static
                                                        • meta(string $key[, mixed $value = true]): static
                                                        • meta(cfg, array $values): static
                                                        • meta(cfg, string $cfgKey[, mixed $cfgValue = true]): static

                                                        This "utility" method can be used to pass "meta" or config information to methods

                                                        Meta arguments can be passed to debug methods in any argument position (first/last/somewhere in the middle)

                                                        Meta arguments are used internally to specify information such as what file/line an error occured on

                                                        Example usage:

                                                        • Create a group that will be hidden (as opposed to collapsed) if empty
                                                        • Specifying (overriding) the file & line of error/warn
                                                        • Specifying custom icon, css-class, or style
                                                        • Setting a config value for a single call
                                                        Universal options
                                                        attribs (array) Html attributes to apply to the log entry
                                                        detectFiles (false) detect if strings are filepaths... for creation of editor/IDE links
                                                        icon (null) classname(s) for custom icon (ie fa fa-hand-lizard-o)
                                                        redact (false) Redact strings (see redactKeys)
                                                        sanitize (true) Whether to pass html output through htmlspecialchars()
                                                        sanitizeFirst (defaults to sanitize value) Whether to pass first argument through htmlspecialchars()
                                                        Specifying that the group should be hidden if it's empty:
                                                        $debug->group('group label', $debug->meta('hideIfEmpty'));
                                                        Specify that the object's methods should not be collected for this call
                                                        $debug->log('my object', $myObject, $debug->meta('cfg', 'collectMethods', false));
                                                        // or
                                                        $debug->log('my object', $myObject, $debug->meta('cfg', array('collectMethods' => false)));
                                                        // or
                                                        $debug->log('my object', $myObject, $debug->meta(array('cfg' => array('collectMethods' => false))));
                                                        output(array $cfg = array()): string|null

                                                        Return debug log output

                                                        Parameters
                                                        cfg
                                                        Override any config values
                                                        Return Value
                                                        string|null
                                                        Description

                                                        Publishes Debug::EVENT_OUTPUT event and returns event's 'return' value

                                                        If output config value is false, null will be returned.

                                                        Note: Log output is handled automatically, and calling output is generally not necessary.

                                                        Log will only be output if either of the following conditions are met

                                                        • output option set to true (default: false)
                                                        • key option set (default: null) and key passed to page as request param (or cookie)
                                                        Example Source
                                                        // initialize PHPDebugConsole
                                                        require '/path/to/Debug.php'; // or via autoloader
                                                        $debug = new \bdk\Debug(array(
                                                            'collect' => true,  // turn logging on
                                                            'output' => true,   // if left false (default), the output() method will return null
                                                        ));
                                                        $debug->log('hello world');
                                                        echo $debug->output();
                                                        Example Output

                                                          • hello world
                                                          Changelog:
                                                          • v2.3: $config parameter
                                                          • v1.2: explicitly calling output() is no longer necessary.. log will be output automatically via shutdown function
                                                          removePlugin(string|SubscriberInterface $plugin): Debug

                                                          Remove plugin

                                                          Parameters
                                                          plugin
                                                          Plugin name or object implementing SubscriberInterface
                                                          Return Value
                                                          Debug
                                                          phpDoc
                                                          throws: InvalidArgumentException
                                                          setCfg(string|array $path[, mixed $value = null[, int $options = 0]]): mixed

                                                          Set one or more config values

                                                          Description

                                                          setCfg('key', 'value') setCfg('level1.level2', 'value') setCfg(array('k1'=&gt;'v1', 'k2'=&gt;'v2'))

                                                          Parameters
                                                          path
                                                          path
                                                          value
                                                          value
                                                          options
                                                          bitmask of CONFIG_NO_PUBLISH, CONFIG_NO_RETURN
                                                          Return Value
                                                          mixed
                                                          previous value(s)
                                                          Example
                                                          $debug->setCfg('collect', true);
                                                          $debug->setCfg('output', true);
                                                          $debug->setCfg('errorHandler/emailMask', E_ERROR);  // only email error notice for E_ERROR
                                                          // or set multiple values via an array.. values not passed will remain as their current value
                                                          $debug->setCfg(array(
                                                              'collect' => 'true',
                                                              'output' => 'true',
                                                              'errorHandler' => array(
                                                                  'emailMask' => E_ERROR,
                                                              ),
                                                          ));
                                                          setErrorCaller(array $caller = null)

                                                          A wrapper for errorHandler->setErrorCaller

                                                          Example: you deprecate a function and trigger a E_USER_DEPRECATED error within the function. Rather than reporting that an error occurred on the file/line of trigger_error(), you can use setErrorCaller() to report the error occurring from the file/line that called the function.

                                                          This is is the file/line that will be written to server's error log

                                                          This override will apply until cleared, error occurs, or groupEnd()

                                                          Example Source
                                                          trustyOldFunction();
                                                          
                                                          /*
                                                              PHP's error_get_last doesn't play nice with set_error_handler
                                                                https://bugs.php.net/bug.php?id=60575
                                                                use $debug->errorHandler->get('lastError') to get last error
                                                          */
                                                          
                                                          $debug->log('lastError', $debug->errorHandler->get('lastError'));
                                                          function trustyOldFunction() {
                                                              \bdk\Debug::setErrorCaller();  // or \bdk\Debug::getInstance()-> // use _ prefix if using < v3.1setErrorCaller()
                                                              trigger_error('trustyOldFunction\'s days are numbered.  Use superNewFunction instead.', E_USER_DEPRECATED);
                                                          }
                                                          Example Output

                                                            • User Deprecated: trustyOldFunction's days are numbered. Use superNewFunction instead., /path/to/mypage.inc.php (line 137, eval'd line 1)
                                                            • lastError =
                                                              bdk\ErrorHandler\Error
                                                              extends
                                                              bdk\ErrorHandler\AbstractError
                                                              bdk\PubSub\Event
                                                              bdk\PubSub\ValueStore
                                                              implements
                                                              • Serializable
                                                              • JsonSerializable
                                                              • ArrayAccess
                                                              • IteratorAggregate
                                                                • Traversable
                                                              constants
                                                              Inherited from bdk\ErrorHandler\AbstractError
                                                              public CAT_DEPRECATED = deprecated
                                                              public CAT_ERROR = error
                                                              public CAT_FATAL = fatal
                                                              public CAT_NOTICE = notice
                                                              public CAT_STRICT = strict
                                                              public CAT_WARNING = warning
                                                              properties (via __debugInfo)
                                                              magic array context
                                                              magic array trace
                                                              Inherited from bdk\ErrorHandler\AbstractError
                                                              protected array|false|null backtrace = null
                                                              protected static array<string,list<int>> errCategories = array(
                                                              • deprecated=>array(
                                                                • 0=>8192
                                                                • 1=>16384
                                                                )
                                                              • error=>array(
                                                                • 0=>256
                                                                • 1=>4096
                                                                )
                                                              • fatal=>array(
                                                                • 0=>1
                                                                • 1=>4
                                                                • 2=>64
                                                                • 3=>16
                                                                )
                                                              • notice=>array(
                                                                • 0=>8
                                                                • 1=>1024
                                                                )
                                                              • strict=>array(
                                                                • 0=>2048
                                                                )
                                                              • warning=>array(
                                                                • 0=>2
                                                                • 1=>32
                                                                • 2=>128
                                                                • 3=>512
                                                                )
                                                              )
                                                              protected static array<int,string> errTypes = array(
                                                              • 32767=>E_ALL
                                                              • 64=>Compile Error
                                                              • 128=>Compile Warning
                                                              • 16=>Core Error
                                                              • 32=>Core Warning
                                                              • 8192=>Deprecated
                                                              • 1=>Fatal Error
                                                              • 8=>Notice
                                                              • 4=>Parsing Error
                                                              • 4096=>Recoverable Error
                                                              • 2048=>Strict
                                                              • 16384=>User Deprecated
                                                              • 256=>User Error
                                                              • 1024=>User Notice
                                                              • 512=>User Warning
                                                              • 2=>Warning
                                                              )
                                                              protected static list<int> userErrors = array(
                                                              • 0=>16384
                                                              • 1=>256
                                                              • 2=>1024
                                                              • 3=>512
                                                              )
                                                              protected array values = array(
                                                              • type=>16384
                                                              • message=>trustyOldFunction's days are numbered. Use superNewFunction instead.
                                                              • evalLine=>1
                                                              • file=>/path/to/mypage.inc.php
                                                              • line=>137
                                                              • vars=>array(
                                                                • 0=>typically this array contains variables defined at scope of error
                                                                • 1=>omitted from examples
                                                                )
                                                              • category=>deprecated
                                                              • continueToNormal=>false
                                                              • continueToPrevHandler=>true
                                                              • exception=>null
                                                              • hash=>0ebafcdb73f3c8a488f5a418fb5e1bad
                                                              • isFirstOccur=>true
                                                              • isHtml=>false
                                                              • isSuppressed=>false
                                                              • throw=>false
                                                              • typeStr=>User Deprecated
                                                              • stats=>array(
                                                                • email=>array(
                                                                  • countSince=>0
                                                                  • emailedTo=>null
                                                                  • timestamp=>null
                                                                  )
                                                                • count=>1
                                                                • tsAdded=>1726171671
                                                                • tsLastOccur=>null
                                                                )
                                                              • email=>false
                                                              • inConsole=>true
                                                              )
                                                              Inherited from bdk\PubSub\Event
                                                              protected Subject subject = bdk\ErrorHandler
                                                              private bool propagationStopped = true
                                                              methods
                                                              public __construct(ErrorHandler $errHandler, array $values)
                                                              public asException(): Exception|ErrorException
                                                              public getBacktrace(bool|auto $withContext = auto): array|false|null
                                                              public getContext(): array|false
                                                              public getFileAndLine(): string
                                                              public getMessage(): string
                                                              public getMessageHtml(): string
                                                              public getMessageText(): string
                                                              public getTrace(bool|auto $withContext = auto): array|false|null
                                                              public log(): bool
                                                              public offsetGet(TKey $key): TValue|null
                                                              Inherited from bdk\ErrorHandler\AbstractError
                                                              public isFatal(): bool
                                                              public setValues(array<TKey,TValue> $values = array()): $this
                                                              public static typeStr(int $type): string
                                                              protected onSet(array<TKey,TValue> $values = array()): void
                                                              Inherited from bdk\PubSub\Event
                                                              public __debugInfo(): array{ propagationStopped: bool, subject: class-string|mixed, values: array<TKey, TValue>, }
                                                              public getSubject(): Subject
                                                              public isPropagationStopped(): bool
                                                              public stopPropagation(): void
                                                              Inherited from bdk\PubSub\ValueStore
                                                              public __serialize(): array<TKey,TValue>
                                                              public __unserialize(array<TKey,TValue> $data): void
                                                              public getIterator(): ArrayIterator<TKey,TValue>
                                                              public getValue(TKey $key): TValue|null
                                                              public getValues(): array<TKey,TValue>
                                                              public hasValue(TKey $key): bool
                                                              public jsonSerialize(): array<TKey,TValue>
                                                              public offsetExists(TKey $key): bool
                                                              public offsetSet(TKey $offset, TValue $value): void
                                                              public offsetUnset(TKey $key): void
                                                              public serialize(): string
                                                              public setValue(TKey $key, TValue $value): $this
                                                              public unserialize(string $data): void
                                                            writeToResponse(ResponseInterface|HttpFoundationResponse $response): ResponseInterface|HttpFoundationResponse

                                                            Appends debug output (if applicable) and/or adds headers (if applicable)

                                                            Description

                                                            You should call this at the end of the request/response cycle in your PSR-7 project, e.g. immediately before emitting the Response.

                                                            Parameters
                                                            response
                                                            PSR-7 or HttpFoundation response
                                                            Return Value
                                                            ResponseInterface|HttpFoundationResponse
                                                            See Also: Middleware

                                                            Configuration / Options

                                                            At a minimum, you must configure either key or both collect and output for the log to be collected & output
                                                            Options may be set when instantiating or when getting the instance:
                                                            $debug = new \bdk\Debug(array(
                                                                'key' => 'Joshua',
                                                                'emailTo' => 'sfalken@wargames.com',
                                                            ));
                                                            and/or via the setCfg() method:
                                                            $debug->setCfg('key', 'Joshua');
                                                            $debug->setCfg('emailTo', 'sfalken@wargames.com');
                                                            general options
                                                            channels

                                                            array()

                                                            Provide configuration for yet-to-be-created channels

                                                            example:

                                                            array(
                                                                'channelName' => array(
                                                                    'channelIcon' => 'fa fa-bolt',
                                                                )
                                                            )
                                                            collect

                                                            false

                                                            Whether the debugger is "on" or not. When false, debug calls are essentially "no-op"

                                                            It is not necessary to explicitly set to true if using the key config setting

                                                            emailFrom

                                                            null

                                                            Specify From address

                                                            If non-null, will be passed to emailFunc in $additionalHeaders param.

                                                            PHP's mail() will default to value defined to php.ini's sendmail_from value

                                                            emailFunc

                                                            email

                                                            A callable that receives 4 parameters: $to, $subject, $body, & string $additionalHeaders

                                                            emailLog

                                                            false

                                                            Whether to email a debug log.

                                                            Values may be:
                                                            • false - log not sent
                                                            • 'onError' log sent if there was an error masked by the errorHandler.emailMask config value
                                                            • true (or 'always') - log always sent (if not being output)

                                                            See email route for more information

                                                            • Raw log data will be serialized & base64-encoded
                                                            • Unserialize with \bdk\Debug\Utility\Utility\SerializeLog::unserialize()
                                                            • Import the data with \bdk\Debug::setData($unserialized)
                                                            requires collect to also be true
                                                            (we can't email what we don't collect)
                                                            ChangeLog:
                                                            • v3.0: true is now synonymous with "always" (was "onError")
                                                            emailTo

                                                            $_SERVER['SERVER_ADMIN']

                                                            Specify where to email logs and error reports

                                                            enableProfiling

                                                            false

                                                            If you will be using profile()/profileEnd() methods, you should set this to true as early as possible.

                                                            PHPDebugConsole will only be able to profile methods/functions that have been included/loaded after this has been set to true.

                                                            Under the hood: profile() works via PHP's register_tick_function(). This function requires a declare(ticks=1) statement in each file with code that will potentially be profiled… To achieve this requirement, PHPDebugConsole will register a stream wrapper (if/when both collect = true and enableProfiling = true). This streamWrapper will inject declare(ticks=1) on-the-fly. This is done when reading the files - no modification will be written.

                                                            See this "how to natively profile scripts" question on stackOverflow

                                                            ChangeLog:
                                                            • v2.3
                                                            headerMaxAll

                                                            250000

                                                            Maximum size of all headers combined. (Chrome has a limit of 256KB)

                                                            ChangeLog:
                                                            • v3.0
                                                            headerMaxPer

                                                            null

                                                            If defined, the maximum size any individual header should be.

                                                            Primarily for ChromeLogger… behind a proxy/load-balancer.

                                                            Many proxies/load-balancers have a hard limit on header size and may throw a 500 error if they receive a large header.

                                                            If you run into an issue, try setting this value to "16K", "8K", "8000", etc

                                                            ChangeLog:
                                                            • v3.0
                                                            key

                                                            null

                                                            Set a "password/key" to enable/view debug info. This key should be passed to the page as a request parameter ($_GET['debug'] or $_COOKIE['debug']).

                                                            Example:
                                                            key set to "bosco":
                                                            • If we visit our page with the correct debug param (ie http://mysite.com/path/mypage.php?debug=bosco)
                                                              collect will be set to true and
                                                              output will be set to true
                                                            • If we don't pass the debug parameter, or pass the incorrect value, collect and output will both be set to false

                                                            key takes precedence over collect and output

                                                            ChangeLog:
                                                            • v3.0: No effect for scripts called from the command line
                                                            logEnvInfo
                                                            array(
                                                                'errorReporting' => true, // notice if not `E_ALL | E_STRICT`
                                                                'files' => true,          // files included during request
                                                                'gitInfo' => true,        // git branch if applicable
                                                                'phpInfo' => true,        // PHP_VERSION, ini file locations, memoryLimit, etc
                                                                'serverVals' => true,     // $_SERVER values specified by logServerKeys
                                                                'session' => true,        // session data
                                                            )

                                                            Specify "environment" information to automatically log.

                                                            Also accepts true (all), or false (none), or string[].

                                                            Example
                                                            Example Source
                                                            $debug = new \bdk\Debug(array(
                                                            	'collect' => true,
                                                            	'output' => true,
                                                            	'logEnvInfo' => true, // this is the default (all other examples use `false`)
                                                            ));
                                                            $debug->info('Not all $_SERVER values are output -> only those included in `logServerKeys', $debug->meta('channel', 'php'));
                                                            Example Output
                                                            PHPDebugConsole


                                                                  • 17 files required
                                                                  • 12 files logged
                                                                  • array(
                                                                    • /var/www=>array(
                                                                      • 0=>controllers/php/Debug.php
                                                                      • vendor=>array(
                                                                        • 0=>5 omitted
                                                                        )
                                                                      • views/php/debug=>array(
                                                                        • 0=>index.php
                                                                        • 1=>changelog.php
                                                                        • 2=>config.php
                                                                        • 3=>events.php
                                                                        • 4=>framework.php
                                                                        • 5=>index.php
                                                                        • 6=>methods.php
                                                                        • 7=>overview.php
                                                                        • 8=>route.php
                                                                        )
                                                                      • 1=>bootstrap.php
                                                                      • 2=>index.php
                                                                      )
                                                                    )

                                                                    • PHP Version = 8.3.10
                                                                    • ini files = array(
                                                                      • /path/to/php.ini
                                                                      • /usr/local/etc/php/8.3/conf.d/20-xdebug.ini
                                                                      • /usr/local/etc/php/8.3/conf.d/ext-opcache.ini
                                                                      )
                                                                    • date.timezone = America/Chicago
                                                                    • memory_limit = redacted MB
                                                                    • expose_php: should be disabled
                                                                    • Xdebug v3.3.0 is installed (mode: debug,coverage,develop)
                                                                    • $_SERVER = array(
                                                                      • HTTP_HOST=>local.bradkent.com
                                                                      • REMOTE_ADDR=>127.0.0.1
                                                                      • REQUEST_TIME=>1726171669
                                                                      • REQUEST_URI=>/php/debug/3.2
                                                                      • SERVER_ADDR=>127.0.0.1
                                                                      • SERVER_NAME=>local.bradkent.com
                                                                      )
                                                                    • Not all $_SERVER values are output -> only those included in `logServerKeys

                                                                      • session.cookie_httponly: should be enabled
                                                                      • session.cache_limiter = nocache
                                                                      • session save_path = /var/tmp/
                                                                      • session name = SESSIONID
                                                                      • session id = dv4ekvip4c56ir34ujq4g7qsk3
                                                                      • $_SESSION = array()
                                                                      • git branch: master

                                                                        ChangeLog:
                                                                        • v3.0: errorReporting, gitInfo, & session added
                                                                          cookies, headers, & post removed (moved to logRequestInfo)
                                                                        • v2.3: accepts array in addition to boolean
                                                                        • v2.0
                                                                        logRequestInfo
                                                                        array(
                                                                            'cookies' => true,
                                                                            'files' => true,   // $_FILES
                                                                            'headers' => true, // request headers
                                                                            'post' => true,    // $_POST (or request body)
                                                                        )

                                                                        Specify request information to automatically log.

                                                                        Also accepts true (all), or false (none).

                                                                        Example
                                                                        Example Source
                                                                        $debug = new \bdk\Debug(array(
                                                                        	'collect' => true,
                                                                        	'output' => true,
                                                                        	'logRequestInfo' => true, // this is the default (all other examples use `false`),
                                                                        	'logResponse' => true, // this is the default (other other examples use `false`),
                                                                        ));
                                                                        Example Output
                                                                        PHPDebugConsole

                                                                          • Response
                                                                          • response headers
                                                                             value
                                                                            Content-Typetext/html
                                                                            CookieSESSIONID=5umr2d3e392f6idhvpadiqs7r0
                                                                          • Not logging response body for Content-Type "text/html"
                                                                          • Content-Length = 0




                                                                                          ChangeLog:
                                                                                          • v3.0
                                                                                          logResponse

                                                                                          auto

                                                                                          Whether to begin buffering output & potentialy log response

                                                                                          auto
                                                                                          (default) We will begin buffering output if ajax request, have SoapAction header, or have a Accepts header that does not contain "html"
                                                                                          true
                                                                                          Begin buffering output
                                                                                          false
                                                                                          Don't buffer output. Response will not be logged

                                                                                          If output is being buffered, we will log the output upon shutdown if response Content-Type is json or xml.

                                                                                          See also writeToResponse()

                                                                                          ChangeLog:
                                                                                          • v3.0
                                                                                          logResponseMaxLen

                                                                                          1 MB

                                                                                          Set a size limit to logging response

                                                                                          If size is exceeded, response will not be output

                                                                                          integer or string

                                                                                          0 / null : No Limit

                                                                                          logRuntime

                                                                                          true

                                                                                          Log script duration and memory usage.

                                                                                          ChangeLog:
                                                                                          • v3.0
                                                                                          logServerKeys

                                                                                          array("REMOTE_ADDR","REQUEST_TIME","REQUEST_URI","SERVER_ADDR","SERVER_NAME")

                                                                                          Specified $_SERVER values will be logged if logEnvInfo.serverVals == true

                                                                                          • HTTP_HOST will be included if logEnvInfo doesn't include "headers"
                                                                                          • CONTENT_LENGTH & CONTENT_TYPE will be included if applicable
                                                                                          • REQUEST_METHOD will be included if REQUEST_METHOD != 'GET'
                                                                                          ChangeLog:
                                                                                          • v2.0
                                                                                          maxDepth

                                                                                          0

                                                                                          Controls how many nested levels of array elements and object properties are traversed.

                                                                                          A value <= 0 does not enforce a maximum depth

                                                                                          onBootstrap

                                                                                          null

                                                                                          A callable to be invoked when debug instance is created.

                                                                                          If setting onBootstrap on an existing instance, it will be called immediately

                                                                                          ChangeLog:
                                                                                          • v2.0
                                                                                          onLog

                                                                                          null

                                                                                          • A callable to be invoked before entry added to log.
                                                                                          • Callback will receive a single param: \bdk\Debug\LogEntry $logEntry.
                                                                                          • Shortcut for subscribing to \bdk\Debug::EVENT_LOG event
                                                                                          ChangeLog:
                                                                                          • v2.0
                                                                                          • v2.0.1: replaces previous onLog value (rather than add additional subscriber)
                                                                                          • v3.0: callable receives a \bdk\Debug\LogEntry object (extends \bdk\PubSub\Event)
                                                                                          onMiddleware

                                                                                          null

                                                                                          • A Callable to be invoked before our middleware writes to response
                                                                                          • Callback will receive a single param: \bdk\PubSub\Event $event. Event object contains request and response objects
                                                                                          • Shortcut for subscribing to \bdk\Debug::EVENT_MIDDLEWARE event.
                                                                                          ChangeLog:
                                                                                          • v3.0
                                                                                          onOutput

                                                                                          null

                                                                                          • A callable to be invoked before log is output.
                                                                                          • Callback will receive a single param: \bdk\PubSub\Event $event.
                                                                                          • Shortcut for subscribing to \bdk\Debug::EVENT_OUTPUT event.
                                                                                          • Given default subscriber priority of 0 (will get called before log is output)
                                                                                          • Able to modify log, but not do post-output actions such as getHeaders()
                                                                                          ChangeLog:
                                                                                          • v2.0: passed param changed from (string) $outputAs to \bdk\PubSub\Event
                                                                                          • v2.0.1: replaces previous onOutput value (rather than add additional subscriber) (this is the pre v2.0 behavior)
                                                                                          output

                                                                                          false

                                                                                          Should output() actually output the log?

                                                                                          It is not necessary to explicitly set to true if using the key config setting

                                                                                          redactKeys

                                                                                          array("password")

                                                                                          A list of keys that should be redacted when redact meta option is passed.

                                                                                          Keys will also be found and redacted in url-encoded strings, xml, & json

                                                                                          The string (or portion thereof) that needs redacted will be passed to the callable defined by redactReplace

                                                                                          Examples:

                                                                                          Perform redaction on xml
                                                                                          $debug->log('response', $xml, $debug->meta('redact'));
                                                                                          Perform redaction on an array
                                                                                          $debug->log('api params', $params, $debug->meta('redact'));
                                                                                          • Redaction is not performed on all log entries.
                                                                                          • Redcation is only performed when redact meta option is passed.

                                                                                          Redaction is performed on out-of-the-box logging of input/$_POST, $_COOKIE, request headers, $_SERVER values, & response

                                                                                          ChangeLog:
                                                                                          • v3.0
                                                                                          redactReplace

                                                                                          callable

                                                                                          A callable that receives the string being redacted and the key

                                                                                          Default callable returns "█████████"

                                                                                          See also redactKeys

                                                                                          ChangeLog:
                                                                                          • v3.0
                                                                                          serviceProvider

                                                                                          array()

                                                                                          \bdk\Container\ServiceProviderInterface, array, or callable that receives \bdk\Container as param.

                                                                                          Used to specify dependencies

                                                                                          sessionName

                                                                                          null

                                                                                          If logging session data (see logEnvInfo), optionally specify session name

                                                                                          If not specified, we will try "PHPSESSID" (php's default, but not recommended), "SESSIONID", "SESSION_ID", "SESSID", and "SESS_ID"

                                                                                          stream

                                                                                          null

                                                                                          A valid filepath, stream-url, or resource, to write the log. This will supplement the log that is output via output()

                                                                                          ChangeLog:
                                                                                          • v3.0 replaces "file" option
                                                                                          stringMaxLen
                                                                                          array(
                                                                                              'base64' => 154, // only 1st 154 chars of base-64 string will be shown
                                                                                              'binary' => array(
                                                                                                  128 => 0,    // if over 128 bytes don't capture / store
                                                                                              ),
                                                                                              'other' => 8192,
                                                                                          )

                                                                                          Controls the maximum string length (in bytes) that is collected/shown for string values

                                                                                          specifying an int (vs array) will set the "other" value

                                                                                          -1 = no maximum

                                                                                          ChangeLog:
                                                                                          • v3.0
                                                                                          stringMinLen
                                                                                          array(
                                                                                              'contentType' => 256, // try to determine content-type of binary string
                                                                                              'encoded' => 16, // test if base64, json, or serialized (-1 = don't check)
                                                                                          )

                                                                                          Specify the minimum length of a string before we inspect it to determine the content-type or check if json/base64/serialized

                                                                                          ChangeLog:
                                                                                          • v3.0
                                                                                          output related options

                                                                                          These options deal with how the log is output

                                                                                          outputHeaders

                                                                                          true

                                                                                          Should PHPDebugConsole output headers (ie, ChromeLogger, FirePHP, & ServerLog headers) on output?

                                                                                          ChangeLog:
                                                                                          • v3.0: output buffering automatically invoked if using route that outputs headers
                                                                                          • v2.3
                                                                                          route

                                                                                          auto

                                                                                          • With the default value ("auto"), output "route" will be determined based on request / response
                                                                                            • "html" if non-ajax, Content-Type: html is being output
                                                                                            • routeNonHtml for other http requests (which defaults to "serverLog")
                                                                                            • "stream" from command line
                                                                                          • route specifies the "primary" route. Additional routes may be added with addPlugin().
                                                                                          • Options:

                                                                                            chromeLogger
                                                                                            • Outputs the log via special http headers.
                                                                                            • Requires browser extension to view.
                                                                                            • Details
                                                                                            discord
                                                                                            • Send critical errors to Discord
                                                                                            • Details
                                                                                            email
                                                                                            file
                                                                                            • Writes the log to a file specified by the file option
                                                                                            • Details
                                                                                            firephp
                                                                                            • Outputs the log via special http headers
                                                                                            • Requires browser extension to view.
                                                                                            • Details
                                                                                            html
                                                                                            • Outputs the log as HTML, along with css and javascript
                                                                                            • Details
                                                                                            serverLog
                                                                                            • Writes the log to a file which is retrieved by browser extension.
                                                                                            • Outputs header which specifies url for browser extension to retrieve the log
                                                                                            • Requires browser extension to view.
                                                                                            • Details
                                                                                            script
                                                                                            • Outputs the log as <script></script> containing console.xxx calls
                                                                                            • Details
                                                                                            slack
                                                                                            • Send critical errors to Slack
                                                                                            • Details
                                                                                            stream
                                                                                            • Writes log entries to a file/resource/url specified by the stream option
                                                                                            • Details
                                                                                            teams
                                                                                            • Send critical errors to Teams
                                                                                            • Details
                                                                                            text
                                                                                            • Outputs the log as plain text
                                                                                            • Details
                                                                                            wamp
                                                                                            • Sends logging in realtime to a WAMP router
                                                                                            • works with ajax, CLI, html, API server, everything
                                                                                            • True console-like logging.
                                                                                            • "Advanced"
                                                                                            • Details
                                                                                            OTHER
                                                                                            Any object implementing \bdk\Debug\RouteInterface
                                                                                          ChangeLog:
                                                                                          • v3.0 replaces "outputAs" option
                                                                                          routeNonHtml

                                                                                          chromeLogger

                                                                                          If route is "auto", this value will be used for http requests that are ajax or non-html response

                                                                                          ChangeLog:
                                                                                          • v3.0 replaces "outputAsDefaultNonHtml" option
                                                                                          html related options
                                                                                          css

                                                                                          Supplemental CSS to output

                                                                                          drawer

                                                                                          true

                                                                                          Place output in dockable "drawer"

                                                                                          ChangeLog:
                                                                                          • v3.0
                                                                                          filepathCss

                                                                                          ./css/Debug.css

                                                                                          Filepath to base CSS.

                                                                                          • (need not be publicly accessible)
                                                                                          filepathScript

                                                                                          ./js/Debug.jquery.min.js

                                                                                          Filepath to javascript to include.

                                                                                          • (need not be publicly accessible)
                                                                                          jqueryUrl

                                                                                          //ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js

                                                                                          Only loaded if window.jQuery is undefined

                                                                                          outputCss

                                                                                          true

                                                                                          Output filepathCss contents with the log?

                                                                                          outputScript

                                                                                          true

                                                                                          Output filepathScript contents with the log?

                                                                                          sidebar

                                                                                          true

                                                                                          Display filter sidebar?

                                                                                          ChangeLog:
                                                                                          • v3.0
                                                                                          object logging & output options

                                                                                          These options deal specifically with debugging objects

                                                                                          caseCollect

                                                                                          true

                                                                                          Whether to collect enum cases

                                                                                          caseOutput

                                                                                          true

                                                                                          Whether to output enum cases

                                                                                          caseAttributeCollect

                                                                                          true

                                                                                          Whether to collect attributes attached to enum cases

                                                                                          caseAttributeOutput

                                                                                          true

                                                                                          Whether to output enum case attributes

                                                                                          constCollect

                                                                                          true

                                                                                          Whether to collect object constants

                                                                                          ChangeLog:
                                                                                          • v3.0b2: renamed from collectConstants
                                                                                          constOutput

                                                                                          true

                                                                                          Whether to output objects constants

                                                                                          ChangeLog:
                                                                                          • v3.0b2: renamed from outputConstants
                                                                                          constAttributeCollect

                                                                                          true

                                                                                          Whether to collect attributes attached to class constants

                                                                                          constAttributeOutput

                                                                                          true

                                                                                          Whether to output constant attributes

                                                                                          interfacesCollapse

                                                                                          array("ArrayAccess","BackedEnum","Countable","Iterator","IteratorAggregate","UnitEnum")

                                                                                          Methods implementing these interfaces will be initially hidden

                                                                                          objAttributeCollect

                                                                                          true

                                                                                          Whether to collect attributes attached to class

                                                                                          objAttributeOutput

                                                                                          true

                                                                                          Whether to output class attributes

                                                                                          objectsExclude

                                                                                          array("DOMNode","bdk\\Debug\\Abstraction","bdk\\Debug")

                                                                                          Array of classes that will not be recursed into if encountered as a property or array value

                                                                                          Object will be listed as "(not inspected)"

                                                                                          objectSectionOrder

                                                                                          array("attributes","extends","implements","constants","cases","properties","methods","phpDoc")

                                                                                          Specify The order to output object information

                                                                                          objectSort

                                                                                          inheritance visibility name

                                                                                          How to sort properties and methods.

                                                                                          ChangeLog:
                                                                                          • v3.2: now a space or comma-separated string
                                                                                          phpDocCollect

                                                                                          true

                                                                                          Whether to collect PhpDoc description & summary (for obj, constants, properties, methods, & method params)

                                                                                          phpDocOutput

                                                                                          true

                                                                                          Whether to output PhpDoc description & summary (for obj, constants, properties, methods, & method params)

                                                                                          toStringOutput

                                                                                          true

                                                                                          Whether to output the __toString() return value

                                                                                          useDebugInfo

                                                                                          true

                                                                                          Whether to utilize object's __debugInfo magic method when debuging object

                                                                                          Although __debugInfo is introduced in PHP 5.6, PHPDebugConsole will call the method (if it exists) regardless of PHP version.

                                                                                          • if __debugInfo value differs from regular value, the property will be listed with icon .
                                                                                          • If the value came exclusively from __debugInfo, it will be listed with "debug" visibility
                                                                                          methodCollect

                                                                                          true

                                                                                          Whether to collect object methods, return types, parameter information, etc

                                                                                          ChangeLog:
                                                                                          • v3.0b2: renamed from collectMethods
                                                                                          methodOutput

                                                                                          true

                                                                                          Whether to output object's methods

                                                                                          ChangeLog:
                                                                                          • v3.0b2: renamed from outputMethods
                                                                                          methodAttributeCollect

                                                                                          true

                                                                                          Whether to collect attributes attached to methods

                                                                                          methodAttributeOutput

                                                                                          true

                                                                                          Whether to output method attributes

                                                                                          methodDescOutput

                                                                                          true

                                                                                          Whether to output method's long phpDoc description

                                                                                          ChangeLog:
                                                                                          • v3.0: renamed from "outputMethodDescription"
                                                                                          methodStaticVarCollect

                                                                                          true

                                                                                          Whether to collect static variables within methods

                                                                                          methodStaticVarOutput

                                                                                          true

                                                                                          Whether to output method static variables

                                                                                          paramAttributeCollect

                                                                                          true

                                                                                          Whether to collect attributes attached to method parameters

                                                                                          paramAttributeOutput

                                                                                          true

                                                                                          Whether to output method parameters attributes

                                                                                          propAttributeCollect

                                                                                          true

                                                                                          Whether to collect attributes attached to properties

                                                                                          propAttributeOutput

                                                                                          true

                                                                                          Whether to output attributes attached to properties

                                                                                          errorEmailer options
                                                                                          • configure how error notifications are emailed
                                                                                          • this feature is disabled by default as of v3.0
                                                                                          • errors are only emailed if not captured by debugger (capture = false at time of error)
                                                                                          • errorEmailer options may be set via the Debug object for convenience
                                                                                          emailMask

                                                                                          E_ERROR | E_PARSE | E_COMPILE_ERROR | E_WARNING | E_USER_ERROR | E_USER_NOTICE

                                                                                          Specify which types of errors should send an email notice

                                                                                          emailMin

                                                                                          60

                                                                                          Number of minutes that must elapse before resending an email notice for unique errors

                                                                                          ChangeLog:
                                                                                          • v3.0 default changed to 60 (was 15)
                                                                                          emailThrottledSummary

                                                                                          true

                                                                                          Whether to send an email summary of throttled errors on trash-collection

                                                                                          emailTraceMask

                                                                                          E_ERROR | E_WARNING | E_USER_ERROR | E_USER_NOTICE

                                                                                          Specify which types of errors should include a backtrace

                                                                                          enableEmailer

                                                                                          false

                                                                                          Send error notifications via email

                                                                                          ChangeLog:
                                                                                          • v3.0 introduced. formerly enabled/disabled solely via emailMask setting
                                                                                          errorStatsFile

                                                                                          __DIR__ . '/error_emails.json'

                                                                                          A file used to maintain details of recent errors.

                                                                                          Warning: emailThrottleFile should be set to a path outside the document root or .htaccess should be configured to prevent access / return a 404

                                                                                          ChangeLog:
                                                                                          • v3.0: renamed. formerly "emailThrottleFile"
                                                                                          errorHandler options
                                                                                          • errorHandler options may be set via the Debug object for convenience
                                                                                          continueToPrevHandler

                                                                                          true

                                                                                          • PHP only supports one error handler defined at a time (our handler publishes a event / unlimited subscribers).
                                                                                          • If this is set true, this handler will pass the error off to the previously set handler (chaining).
                                                                                          • Stopping error event's propagation will also prevent continuation to prev handler
                                                                                          errorLogNormal

                                                                                          false

                                                                                          Whether to log the error to the error_log as "normal" when the debugger is capturing errors

                                                                                          errorReporting

                                                                                          E_ALL | E_STRICT

                                                                                          What errors the errorHandler should handle.

                                                                                          Bitmask of error types (or "system", which will use the currently configured php value)

                                                                                          If we're not handling error and continueToPrevHandler is true, the error will be passed to prev handler (if there was one).

                                                                                          onEUserError

                                                                                          log

                                                                                          • This library changes the default behavior of E_USER_ERROR and E_RECOVERABLE_ERROR from terminate to continue
                                                                                            Unless we're continuing to a previous error handler. In which case, this behavior will be dictated by prev handler.
                                                                                          • For default behavior, use the "normal" value
                                                                                          Using an error handler affects the behavior of E_USER_ERROR and E_RECOVERABLE_ERROR.
                                                                                          The More You Know
                                                                                          no custom error handler
                                                                                          treated as fatal / script terminates
                                                                                          custom error handler that returns false
                                                                                          treated as fatal / script terminates
                                                                                          custom error handler that does not return false
                                                                                          not treated fatal / script continues

                                                                                          This config option gives you control

                                                                                          If error is being passed to a previous error handler:
                                                                                          • We pass-the-buck & this option has no effect
                                                                                          • The behavior is controlled by the previous handler.

                                                                                          allowed values:

                                                                                          "continue"
                                                                                          • Script will continue
                                                                                          • Error will not be logged by PHP
                                                                                          "log"
                                                                                          (default)
                                                                                          • Script will continue
                                                                                          • Error will be logged if error event's propagation not stopped and if $error['continueToNormal'] == true
                                                                                          "normal"
                                                                                          Continue to "normal" error handler.
                                                                                          PHP will log error
                                                                                          Script will terminate.
                                                                                          null|false
                                                                                          Behavior based on the value of $error['continuetoNormal'].
                                                                                          • continueToNormal true: log the error
                                                                                          • continueToNormal false: continue without logging
                                                                                          See errorHandler.error event
                                                                                          ChangeLog:
                                                                                          • v2.1
                                                                                          onError

                                                                                          null

                                                                                          A callable to be invoked when error occurs.

                                                                                          • Shortcut for subscribing to errorHandler.error event
                                                                                          • Will also get called on fatal errors.
                                                                                          • Callback will receive a single param: \bdk\ErrorHandler\Error $error
                                                                                          ChangeLog:
                                                                                          • v1.2: callable receives array of error info
                                                                                          • v2.0: callable receives a \bdk\PubSub\Event object
                                                                                          • v2.0.1: Replace previous onError value (2.0 added an additional subscriber)
                                                                                          • v3.0: callable receives a \bdk\ErrorHandler\Error object (extends \bdk\PubSub\Event)

                                                                                          Events

                                                                                          \bdk\Debug::EVENT_BOOTSTRAP

                                                                                          published when debug is instantiated

                                                                                          Primarily used internally. This event is published after the debug instance is created. This event can be subscribed to by passing the onBootstrap config option to the debug constructor. If the debug instance has already been instantiated, setting onBootstrap via setCfg will invoke the handler immediately.
                                                                                          \bdk\Debug::EVENT_CONFIG

                                                                                          published when config is updated

                                                                                          • Call $event->getSubject() to get the debug object
                                                                                          • $event->getValues() to get changed config values
                                                                                          Changelog:
                                                                                          • v3.0 - 'config' value removed in favor of $event->getValues()
                                                                                          • v2.1 - 'config' value added
                                                                                          • v2.0
                                                                                          \bdk\Debug::EVENT_CUSTOM_METHOD

                                                                                          published when a non-core method is called

                                                                                          Set $event['handled'] = true if "handled". If not "handled" the log-entry will trigger \bdk\Debug::EVENT_LOG event with meta value 'isCustomMethod' = true
                                                                                          Changelog:
                                                                                          • v3.0 - added
                                                                                          \bdk\Debug::EVENT_DUMP_CUSTOM

                                                                                          published when dumping an unknown "abstraction" object;

                                                                                          Changelog:
                                                                                          • v3.0 - added
                                                                                          \bdk\Debug::EVENT_LOG

                                                                                          published when a debug method is called

                                                                                          • Only published when "collect" is true
                                                                                          • Call $event->getSubject() to get the debug object
                                                                                          • $event['method'] contains the called debug method
                                                                                          • $event['args'] contains the arguments passed
                                                                                          • $event['meta'] contains meta information
                                                                                          • Set $event['appendLog'] = false to prevent the log-entry from being logged

                                                                                          Custom methods

                                                                                          Create custom methods by subscribing to this event.

                                                                                          For example you can call $debug->myMethod("arg1") (which isn't a core method). Rather than error out, this event will be published (just as it is for core methods).

                                                                                          $event['meta']['isCustomMethod'] will exist with a value of true

                                                                                          This event "bubbles" up its ancestor channels.
                                                                                          Calling stopPropagation() will prevent this
                                                                                          Changelog:
                                                                                          • v3.0 - $event['appendLog'] instead of $event->stopPropagation() to control whether to log
                                                                                          • v2.1 - publish when calling inaccessible method (custom methods)
                                                                                          • v2.0
                                                                                          \bdk\Debug::EVENT_MIDDLEWARE

                                                                                          published before middleware writes to response

                                                                                          This event only applies if using PHPDebugConsole's middleware

                                                                                          • Call $event->getSubject() to get debug instance
                                                                                          • $event['request'] contains the ServerRequestInterface
                                                                                          • $event['response'] contains the ResponseInterface
                                                                                          Changelog:
                                                                                          • v3.0
                                                                                          \bdk\Debug::EVENT_OBJ_ABSTRACT_END

                                                                                          published after object is inspected

                                                                                          This event gives access to the object abstraction after the heavy lifting took place

                                                                                          subscribers to this event have complete control to modify the abstraction values:

                                                                                          Call $event->getSubject() to get the inspected object
                                                                                          This event "bubbles" up its ancestor channels.
                                                                                          Calling stopPropagation() will prevent this
                                                                                          \bdk\Debug::EVENT_OBJ_ABSTRACT_START

                                                                                          published before object is inspected

                                                                                          This event gives access to the object abstraction before the heavy lifting takes place

                                                                                          Subscribers to this event may:
                                                                                          • set `isExcluded`
                                                                                          • set `collectPropertyValues` (boolean)
                                                                                          • set `collectMethods` (boolean)
                                                                                          • set `propertyOverrideValues`
                                                                                          • set `stringified`
                                                                                            set this value in lieu of a __toString method..
                                                                                            example: DateTime objects don't have a __toString() method, so PHPDebugConsole uses its \bdk\Debug::EVENT_OBJ_ABSTRACT_START subscriber to set stringified to a human readable format
                                                                                          • set `traverseValues`
                                                                                          Call $event->getSubject() to get the object being inspected
                                                                                          This event "bubbles" up its ancestor channels.
                                                                                          Calling stopPropagation() will prevent this
                                                                                          Changelog:
                                                                                          • v2.3 - added `propertyOverrideValues`
                                                                                          \bdk\Debug::EVENT_OUTPUT

                                                                                          published when it's time to output the log

                                                                                          Published on current and all descendant channels

                                                                                          Subscriber with high priority can append log and modify the log before it's output

                                                                                          Subscriber with low priority modify the generated $event['output']

                                                                                          Call $event->getSubject() to get the debug instance

                                                                                          \bdk\Debug::EVENT_OUTPUT_LOG_ENTRY

                                                                                          For each enabled output plugin, published as each individual log entry is output

                                                                                          Use this event to customize how a particular method is displayed / or to handle custom methods (unhandled methods will be handled the same as a plain 'ol log() call).

                                                                                          • \bdk\Debug::EVENT_LOG is published when you call a debug method.
                                                                                          • \bdk\Debug::EVENT_OUTPUT_LOG_ENTRY is published when that log entry is output
                                                                                          • Call $event->getSubject() to get debug instance
                                                                                          • Call $event->stopPropagation() to prevent the default output
                                                                                          • $event['method'] contains the called debug method
                                                                                          • $event['args'] contains the arguments passed
                                                                                          • $event['meta'] contains meta information
                                                                                          • $event['return'] = null set to non-null to override
                                                                                          • $event['route'] = output "plugin" instance (ie the Route/Html object)
                                                                                          Changelog:
                                                                                          • v3.0 - getSubject() returns debug instance, previously returned output plugin
                                                                                            added $event['route'] value
                                                                                          • v2.1.1 - add the return value
                                                                                          • v2.1
                                                                                          \bdk\Debug::EVENT_PLUGIN_INIT

                                                                                          Published exclusively to the plugin being added

                                                                                          Use this event to do any initialization a plugin may require.

                                                                                          • Call $event->getSubject() to get debug instance
                                                                                          Changelog:
                                                                                          • v3.0 - added
                                                                                          \bdk\Debug::EVENT_PRETTIFY

                                                                                          Prettify php://input, Guzzle message bodies, and curl response body

                                                                                          We will prettify html, json, & xml. Use this event to customize, or to handle other content-types

                                                                                          • Call $event->stopPropagation() if handling
                                                                                          • $event['contentType'] contains the content/mime type
                                                                                          • $event['value'] contains the string to prettify
                                                                                          Changelog:
                                                                                          • v3.0 - added
                                                                                          \bdk\Debug::EVENT_STREAM_WRAP

                                                                                          Modify PHP code as it's loaded

                                                                                          If enableProfiling is enabled, \bdk\Debug::EVENT_STREAM_WRAP will be published when a file gets required/included.

                                                                                          Internally we use this event to inject declare(ticks=1); - necessary for our profile method.

                                                                                          • $event->getSubject() returns the php://memory resource that will contain the modified PHP code
                                                                                          • $event['content'] contains file contents
                                                                                          • $event['filepath'] contains the filepath being required
                                                                                          \bdk\ErrorHandler::EVENT_ERROR

                                                                                          published when a php error occurs

                                                                                          • Call $event->getValues() to get all error info
                                                                                          • Call $event->stopPropagation() to prevent continuation to previous error handler
                                                                                          \bdk\PubSub\Manager::EVENT_PHP_SHUTDOWN

                                                                                          Published when script execution finishes or exit() is called

                                                                                          Provided via our underlying event manager

                                                                                          This event is essentially a helper/wrapper for register_shutdown_function

                                                                                          Routes (output)

                                                                                          ChromeLogger

                                                                                          ChromeLogger outputs your log via http headers. The log is viewed in your browser's console via extension/addon

                                                                                          No PHP/server-side dependency required

                                                                                          Browser Support:

                                                                                          ChromeLogger website

                                                                                          AJAX Example

                                                                                          Non text/html example

                                                                                          Note: ChromeLogger output is sent via headers…
                                                                                          Headers must be sent before any other output sent to browser.
                                                                                          Debug generates the headers via output()
                                                                                          ob_start() is one way to hold script output until the end of the script.

                                                                                          See also:

                                                                                          ChromeLogger uses a single header which can get quite large.

                                                                                          If there's a proxy or load-balancer between you and the server being debugged, the large header is an issue.

                                                                                          Some shared hosting will 500 if a large header is attempted.

                                                                                          As a workaround you can set the headerMaxPer option to limit the output

                                                                                          Discord

                                                                                          Send error notification to Discord webhook

                                                                                          Options

                                                                                          errorMask
                                                                                          (E_ERROR | E_PARSE | E_COMPILE_ERROR | E_WARNING | E_USER_ERROR) What errors should plugin handle
                                                                                          onClientInit
                                                                                          (null) Callable that will receive the curl client
                                                                                          throttleMin
                                                                                          (60) how many minutes should elapse before resending the same error
                                                                                          webhookUrl
                                                                                          (DISCORD_WEBHOOK_URL env var) Discord webhook url
                                                                                          Example Source
                                                                                          // enable via plugins config array
                                                                                          $debug = new \bdk\Debug(array(
                                                                                              'plugins' => array(
                                                                                                  'discord' => array(
                                                                                                      'class' => 'bdk\\Debug\\Route\\Discord',
                                                                                                      'webhookUrl' => 'https://discord.com/api/webhooks/123456789/abcdefg-hijklmnop-qrstuv-wx_yz',
                                                                                                  ),
                                                                                              ),
                                                                                          ));
                                                                                          
                                                                                          // OR add to debug via addPlugins
                                                                                          $discordPlugin = $debug->getRoute('discord')->setCfg(array(
                                                                                              'webhookUrl' => 'https://discord.com/api/webhooks/123456789/abcdefg-hijklmnop-qrstuv-wx_yz',
                                                                                          ));
                                                                                          $debug->addPlugin($discordPlugin);
                                                                                          Example Output Screenshot
                                                                                          screenshot

                                                                                          Email

                                                                                          Email the log!

                                                                                          It may be useful to email the log if an error occured…

                                                                                          There are two ways to go about collecting and emailing log info

                                                                                          • See the emailLog configuration option
                                                                                            • This option does not require output to be true
                                                                                          • Set route to "email" conditionally.. say for a specific user performing a specific action
                                                                                            • output must also be set to true
                                                                                          • Raw log data will be serialized & base64-encoded
                                                                                          • Unserialize with \bdk\Debug\Utility\SerializeLog::unserialize()
                                                                                          • Import the data with \bdk\Debug\Utility\SerializeLog::import($unserialized)
                                                                                          Remember:
                                                                                          collect must be set true for there to be any log entries to email!

                                                                                          Firephp

                                                                                          No PHP/server-side dependency required

                                                                                          Browser Support:

                                                                                          FirePHP website

                                                                                          AJAX Example

                                                                                          Non text/html example

                                                                                          Note: FirePHP output is sent via headers…
                                                                                          Headers must be sent before any other output sent to browser.
                                                                                          Debug generates the headers via output()
                                                                                          ob_start() is one way to hold script output until the end of the script.

                                                                                          See also:

                                                                                          Html

                                                                                          The default route

                                                                                          Script

                                                                                          Log is output as <script> tag with console.xxx calls

                                                                                          <script type="text/javascript">
                                                                                          console.log("hello world");
                                                                                          console.log("etc.");
                                                                                          </script>
                                                                                          Example Source
                                                                                          $debug = new \bdk\Debug(array(
                                                                                              'key' => 'example_password',
                                                                                              'route' => 'script',
                                                                                          ));
                                                                                          
                                                                                          $debug->alert('This is the script route example');
                                                                                          $debug->info('this is a script test');
                                                                                          $debug->table(array(
                                                                                              array('city' => 'Atlanta', 'state'=>'GA', 'population'=>472522,),
                                                                                              array('city' => 'Buffalo', 'state'=>'NY', 'population'=>256902,),
                                                                                              array('city' => 'Chicago', 'state'=>'IL', 'population'=>2704958,),
                                                                                              array('city' => 'Denver', 'state'=>'CO', 'population'=>693060,),
                                                                                              array('city' => 'Seattle', 'state'=>'WA', 'population'=>704352,),
                                                                                              array('city' => 'Tulsa', 'state'=>'OK', 'population'=>403090,),
                                                                                          ), 'Table');
                                                                                          
                                                                                          echo 'This example output can be found in your browser console!';
                                                                                          Example Output
                                                                                          This example output can be found in your browser console!

                                                                                          ServerLog

                                                                                          ServerLog writes your log to a temporary JSON file. A url to this file is output via a header. A browser extension/addon retrieves the log and displays it in your browser's console

                                                                                          No PHP/server-side dependency required

                                                                                          Browser Support:

                                                                                          Config:

                                                                                          There are a handful of config options for ServerLog. Here are the two important ones

                                                                                          logDir
                                                                                          default value: DOCUMENT_ROOT . '/log'
                                                                                          This is the directory that will temporarily store the log file
                                                                                          If this directory does not exist, an attempt will be made to create it.
                                                                                          urlTemplate
                                                                                          default value: '/log/{filename}'
                                                                                          This is the template for the url sent to the browser as a header
                                                                                          filename is the only "token" avail
                                                                                          Example Source
                                                                                          $debug = new \bdk\Debug(array(
                                                                                              'routeServerLog' => array(
                                                                                                  'logDir' => '/tmp/',
                                                                                                  'urlTemplate' => '/serverLog/{filename}',
                                                                                              ),
                                                                                              'route' => 'serverLog',
                                                                                              // 'collect' and / or 'key' must also be configured
                                                                                          ));

                                                                                          AJAX Example

                                                                                          Non text/html example

                                                                                          If you're unable to view the log:
                                                                                          • Ensure the X-ServerLog-Location is being output. (Use your browser's developer console / network tab to inspect the request/response.)
                                                                                          • Ensure you've installed and enable a ServerLog browser extension
                                                                                          • Ensure you've instantiated and enabled PHPDebugConsole. See the minimum callout under Configuration

                                                                                          Slack

                                                                                          Send error notification to Slack

                                                                                          Options

                                                                                          channel
                                                                                          (SLACK_CHANNEL env var) If using Slack api, specify channel to post to
                                                                                          errorMask
                                                                                          (E_ERROR | E_PARSE | E_COMPILE_ERROR | E_WARNING | E_USER_ERROR) What errors should plugin handle
                                                                                          onClientInit
                                                                                          (null) Callable that will receive the curl client
                                                                                          throttleMin
                                                                                          (60) how many minutes should elapse before resending the same error
                                                                                          token
                                                                                          (SLACK_TOKENL env var) If using Slack api, specify token
                                                                                          use
                                                                                          (auto) "auto", "api", or "webhook"
                                                                                          If channel and token are set we will use the api. Otherwise we will use webhook.
                                                                                          webhookUrl
                                                                                          (SLACK_WEBHOOK_URL env var) Slack webhook url
                                                                                          Example Source
                                                                                          // enable via plugins config array
                                                                                          $debug = new \bdk\Debug(array(
                                                                                              'plugins' => array(
                                                                                                  'slack' => array(
                                                                                                      'class' => 'bdk\\Debug\\Route\\Slack',
                                                                                                      'webhookUrl' => 'https://hooks.slack.com/services/QWERTY/DVORAK/PCMCIA',
                                                                                                  ),
                                                                                              ),
                                                                                          ));
                                                                                          
                                                                                          // OR add to debug via addPlugins
                                                                                          $slackPlugin = $debug->getRoute('slack')->setCfg(array(
                                                                                              'webhookUrl' => 'https://hooks.slack.com/services/QWERTY/DVORAK/PCMCIA',
                                                                                          ));
                                                                                          $debug->addPlugin($slackPlugin);
                                                                                          Example Output Screenshot
                                                                                          screenshot

                                                                                          Stream

                                                                                          Stream to STDERR or file pointer

                                                                                          CLI scripts

                                                                                          This is the default route for command line scripts.

                                                                                          When used in command-line context:

                                                                                          • default stream: STDERR
                                                                                          • this route abides by the global output value (logs only pushed to stream when true).
                                                                                          • key config has no effect in console context
                                                                                          • pretty ANSI color output
                                                                                          // begin outputting log entries to specified filepath
                                                                                          // primary route is unaffected / this will supplement
                                                                                          $debug->setCfg('stream', '/some/filepath.txt');
                                                                                          
                                                                                          // only output log to filepath
                                                                                          // 'output' will need to be true or 'key' set & matching
                                                                                          $debug->setCfg(array(
                                                                                              'route' => 'stream',
                                                                                              'stream' => '/some/filepath.txt',
                                                                                          ));
                                                                                          

                                                                                          Teams

                                                                                          Send error notification to MS Teams

                                                                                          Options

                                                                                          errorMask
                                                                                          (E_ERROR | E_PARSE | E_COMPILE_ERROR | E_WARNING | E_USER_ERROR) What errors should plugin handle
                                                                                          onClientInit
                                                                                          (null) Callable that will receive the curl client
                                                                                          throttleMin
                                                                                          (60) how many minutes should elapse before resending the same error
                                                                                          webhookUrl
                                                                                          (TEAMS_WEBHOOK_URL env var) Teams webhook url
                                                                                          Example Source
                                                                                          // enable via plugins config array
                                                                                          $debug = new \bdk\Debug(array(
                                                                                              'plugins' => array(
                                                                                                  'teams' => array(
                                                                                                      'class' => 'bdk\\Debug\\Route\\Teams',
                                                                                                      'webhookUrl' => 'https://wxyz8.webhook.office.com/webhookb2/supercalifragilisticexpialidocious/IncomingWebhook/blablah/blah-blah-blah',
                                                                                                  ),
                                                                                              ),
                                                                                          ));
                                                                                          
                                                                                          // OR add to debug via addPlugins
                                                                                          $teamsPlugin = $debug->getRoute('teams')->setCfg(array(
                                                                                              'webhookUrl' => 'https://wxyz8.webhook.office.com/webhookb2/supercalifragilisticexpialidocious/IncomingWebhook/blablah/blah-blah-blah',
                                                                                          ));
                                                                                          $debug->addPlugin($teamsPlugin);
                                                                                          Example Output Screenshot
                                                                                          screenshot

                                                                                          Text

                                                                                          Plain / boring text output

                                                                                          Example Source
                                                                                          $debug = new \bdk\Debug(array(
                                                                                              'collect' => true,
                                                                                              'output' => true,
                                                                                              'route' => 'script',
                                                                                          ));
                                                                                          
                                                                                          $debug->alert('this is an alert!');
                                                                                          $debug->info('you have 30 minutes to move your car');
                                                                                          $debug->warn('your car has been impounded');
                                                                                          $debug->error('your car has been crushed into a cube');
                                                                                          $debug->table(array(
                                                                                              array('city' => 'Denver', 'state'=>'CO', 'population'=>693060,),
                                                                                              array('city' => 'Seattle', 'state'=>'WA', 'population'=>704352,),
                                                                                              array('city' => 'Tulsa', 'state'=>'OK', 'population'=>403090,),
                                                                                          ), 'Table');
                                                                                          
                                                                                          Example Output
                                                                                          》[Alert ⦻ error] this is an alert!《
                                                                                          ℹ you have 30 minutes to move your car
                                                                                          ⚠ your car has been impounded
                                                                                          ⦻ your car has been crushed into a cube
                                                                                          Table = array(
                                                                                              [0] => array(
                                                                                                  [city] => "Denver"
                                                                                                  [state] => "CO"
                                                                                                  [population] => 693060
                                                                                              )
                                                                                              [1] => array(
                                                                                                  [city] => "Seattle"
                                                                                                  [state] => "WA"
                                                                                                  [population] => 704352
                                                                                              )
                                                                                              [2] => array(
                                                                                                  [city] => "Tulsa"
                                                                                                  [state] => "OK"
                                                                                                  [population] => 403090
                                                                                              )
                                                                                          )
                                                                                          

                                                                                          Wamp check this out

                                                                                          Log entries are published immediately to a WAMP (Web Application Messaging Protocol) router

                                                                                          A "client" web-page listening to the WAMP router renders the log in "real-time".

                                                                                          Debug without adding any headers/text/markup to the output.

                                                                                          Great for debugging

                                                                                          • AJAX calls
                                                                                          • Command Line Applications
                                                                                          • API requests
                                                                                          • Any request returning something other than HTML (css, javascript, json, xml, binary, whatever)
                                                                                          • Plain 'ol html web pages

                                                                                          Requires:

                                                                                          How-To Guides & Integrations

                                                                                          Use PHPDebugConsole with the frameworks and tools you already use.

                                                                                          Frameworks

                                                                                          How-To Guides and plugins for common frameworks

                                                                                          CakePHP v4

                                                                                          CakePHP

                                                                                          Add debug configuration options to app.php or app_local.php

                                                                                          'PHPDebugConsole' => array(
                                                                                              'key' => 'dingus',
                                                                                          ),

                                                                                          Register plugin in Application::bootstrap()

                                                                                          $this->addPlugin(new \bdk\Debug\Framework\Cake4());

                                                                                          CodeIgniter (coming soon)

                                                                                          Laravel

                                                                                          Laravel

                                                                                          Setup & Configure

                                                                                          • Require bdk/debug via composer (how)
                                                                                          • Edit your laravel .env file and add PHPDEBUGCONSOLE_KEY = somePassword
                                                                                          • "publish" (ie copy) the config file and customize the config

                                                                                            run php artisan vendor:publish --tag=config

                                                                                            You should now have a config/phpDebugConsole.php config file

                                                                                            This file can be used to set all PHPDebugConsole config options including some Laravel-specific options

                                                                                            • laravel is a list of laravel-specific information that you would like to collect / output
                                                                                            • options contains collector-specific options for the above

                                                                                          Using

                                                                                          Access your Laravel site with ?debug=somePassword (where "somePassword" is the password/key set in config/phpDebugConsole.php… likely the PHPDEBUGCONSOLE_KEY value)

                                                                                          Slim2 Framework

                                                                                          Slim Framework v2

                                                                                          Example Source
                                                                                          /*
                                                                                              create slim v2 app
                                                                                          */
                                                                                          $app = new \Slim\Slim(array(
                                                                                              'debug' => false,
                                                                                          ));
                                                                                          /*
                                                                                              Add logging via PHPDebugConsole
                                                                                          */
                                                                                          $app->hook('slim.before', function () use ($app) {
                                                                                              $app->log->setWriter(new \bdk\Debug\Framework\Slim2());
                                                                                          });
                                                                                          /*
                                                                                              Add Routes & Run
                                                                                          */
                                                                                          $app->get('/hello/:name', function ($name) {
                                                                                              echo 'Slim, '.$name.'<br />';
                                                                                          });
                                                                                          $app->run();

                                                                                          Symfony

                                                                                          Symfony

                                                                                          1. Add PhpDebugConole to your project via composer (how)
                                                                                          2. Update bundles.php / add this line
                                                                                            bdk\Debug\Framework\Symfony\DebugBundle\BdkDebugBundle::class => ['all' => true],
                                                                                          3. Add config/packages/dev/bdk_debug.yaml
                                                                                            bdk_debug:
                                                                                              collect: true
                                                                                              output: true

                                                                                          Yii 1.1

                                                                                          Yii 1.1 framework

                                                                                          Our Yii 1.1 component will

                                                                                          • Add a Yii log route
                                                                                          • decorate Yii::app()->db with \bdk\Debug\Collector\Pdo (log PDO queries)
                                                                                          • pass errors through our ErrorHandler
                                                                                          • Add Yii::app()->debug

                                                                                          Require bdk/debug via composer (how)

                                                                                          Edit your Yii config

                                                                                          array(
                                                                                            // add to components
                                                                                            'components' => array (
                                                                                              'phpDebugConsole' => array (
                                                                                                'class' => '\\bdk\\Debug\\Framework\\Yii1_1\\Component',
                                                                                                // debug config values
                                                                                                // best to replace 'collect' & 'output' with 'key'
                                                                                                'collect' => true,
                                                                                                'output' => true,
                                                                                                // optional yii specific options
                                                                                                'yii' => array(
                                                                                                  'ignoredErrors' => true, // yii 1.1 framework throws a lot of deprecation and notices
                                                                                                                        // we "ignore" these errors
                                                                                                                        // this setting will show a summary of these ignored errors
                                                                                                  'log' => true, // whether to set up a yii log route and capture Yii log messsaegs
                                                                                                  'pdo' => true, // capture database queries
                                                                                                  'session' => true, // log session info / data
                                                                                                  'user' => true, // log current user info
                                                                                                )
                                                                                              ),
                                                                                            ),
                                                                                            // add to preload
                                                                                            'preload' => array('phpDebugConsole'),
                                                                                            // may need to add an alias
                                                                                            'aliases' => array(
                                                                                              'bdk.Debug.Framework' => 'path/to/Debug/Framework/Yii1_1',
                                                                                            ),
                                                                                          );

                                                                                          You may also want to define YII_DEBUG when bootstraping your app

                                                                                          define('YII_DEBUG', true);
                                                                                          

                                                                                          Yii 2.x

                                                                                          Yii 2.0

                                                                                          Require bdk/debug via composer (how)

                                                                                          Edit your Yii config

                                                                                          /*
                                                                                              Add to bootstrao and modules arrays
                                                                                              Make sure that 'phpDebugConsole' comes first in the boostrap array
                                                                                                to ensure we intercept the instantiation of the database connection
                                                                                          */
                                                                                          $config['bootstrap'][] = 'phpDebugConsole';
                                                                                          $config['modules']['phpDebugConsole'] = [
                                                                                              'class' => 'bdk\Debug\Framework\Yii2\Module',
                                                                                              // debug config values
                                                                                              // best to replace 'collect' & 'output' with 'key'
                                                                                              'collect' => true,
                                                                                              'output' => true,
                                                                                              // optional yii specific options
                                                                                              'yii' => [
                                                                                                  'events' => true, // summary of all dispatched events
                                                                                                  'log' => true, // whether to set up a yii log target and capture Yii log messsaegs
                                                                                                  'pdo' => true, // capture database queries
                                                                                                  'session' => true, // log session info / data
                                                                                                  'user' => true, // log current user info
                                                                                              ],
                                                                                          ];
                                                                                          

                                                                                          Decorators

                                                                                          PHPDebugConsole includes Adaptors / Decorators / Helpers / Proxies / Wrappers for common "components"

                                                                                          Doctrine DB Abstraction Layer

                                                                                          Doctrine Database Abstraction Layer
                                                                                          Example Source
                                                                                          /*
                                                                                              Get the Doctrine connection obj
                                                                                          */
                                                                                          $conn = \Doctrine\DBAL\DriverManager::getConnection(array(
                                                                                              'url' => 'mysql://user:secret@localhost/mydb',
                                                                                          ));
                                                                                          
                                                                                          /*
                                                                                              Instantiate PHPDebugConsole's Doctrine Logger and set Doctrine's logger
                                                                                          */
                                                                                          $logger = new \bdk\Debug\Collector\DoctrineLogger($conn);
                                                                                          $conn->getConfiguration()->setSQLLogger($logger);
                                                                                          
                                                                                          $statement = $conn->prepare('SELECT *
                                                                                              FROM `users`
                                                                                              WHERE `username` = :username');
                                                                                          $username = 'james.bond';
                                                                                          $statement->bindParam(':username', $username, PDO::PARAM_STR);
                                                                                          $statement->execute();
                                                                                          Example Output
                                                                                          • Doctrine: sqlite:///:memory:
                                                                                            • logged operations: 1
                                                                                            • total time: 120.163 μs
                                                                                            • max memory usage = 1.32 kB
                                                                                            • connection info = array(
                                                                                              • url=>sqlite:///:memory:
                                                                                              • driver=>pdo_sqlite
                                                                                              • host=>localhost
                                                                                              • memory=>true
                                                                                              )

                                                                                          • SELECT * FROM `users` WHERE `username` = 'james.bond'
                                                                                            • SELECT * FROM `users` WHERE `username` = :username
                                                                                            • parameters
                                                                                               valuetype
                                                                                              :usernamejames.bondPDO::PARAM_STR
                                                                                            • duration: 120.163 μs
                                                                                            • memory usage = 1.32 kB
                                                                                            • Use SELECT * only if you need all columns from table

                                                                                          Guzzle

                                                                                          Guzzle
                                                                                          Initiate a guzzle client with PHPDebugConsole middleware
                                                                                          $stack = \GuzzleHttp\HandlerStack::create();
                                                                                          $stack->push(
                                                                                              new \bdk\Debug\Collector\GuzzleMiddleware(array(
                                                                                                  'inclRequestBody' => true,  // default is false
                                                                                                  'inclResponseBody' => true, // default is false
                                                                                              ))
                                                                                          );
                                                                                          
                                                                                          $client = new \GuzzleHttp\Client(array(
                                                                                              'cookies' => true,
                                                                                              'handler' => $stack,
                                                                                          ));
                                                                                          
                                                                                          $response = $client->request('GET', 'http://example.com/');
                                                                                          Example Output
                                                                                          • Doctrine: sqlite:///:memory:
                                                                                            • logged operations: 1
                                                                                            • total time: 120.163 μs
                                                                                            • max memory usage = 1.32 kB
                                                                                            • connection info = array(
                                                                                              • url=>sqlite:///:memory:
                                                                                              • driver=>pdo_sqlite
                                                                                              • host=>localhost
                                                                                              • memory=>true
                                                                                              )

                                                                                          • Guzzle(GET, http://example.com/)
                                                                                            • request headers = GET / HTTP/1.1 User-Agent: GuzzleHttp/7 Host: example.com
                                                                                            • time: 88.1729 ms
                                                                                            • response headers = HTTP/1.1 200 OK Age: 407272 Cache-Control: max-age=604800 Content-Type: text/html; charset=UTF-8 Date: Thu, 12 Sep 2024 20:07:55 GMT Etag: "3147526947+gzip+ident" Expires: Thu, 19 Sep 2024 20:07:55 GMT Last-Modified: Thu, 17 Oct 2019 07:18:26 GMT Server: ECAcc (chd/07A5) Vary: Accept-Encoding X-Cache: HIT Content-Length: 1256
                                                                                            • response body = <!doctype html> <html> <head> <title>Example Domain</title> <meta charset="utf-8" /> <meta http-equiv="Content-type" content="text/html; charset=utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <style type="text/css"> body { background-color: #f0f0f2; margin: 0; padding: 0; font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; } div { width: 600px; margin: 5em auto; padding: 2em; background-color: #fdfdff; border-radius: 0.5em; box-shadow: 2px 3px 7px 2px rgba(0,0,0,0.02); } a:link, a:visited { color: #38488f; text-decoration: none; } @media (max-width: 700px) { div { margin: 0 auto; width: auto; } } </style> </head> <body> <div> <h1>Example Domain</h1> <p>This domain is for use in illustrative examples in documents. You may use this domain in literature without prior coordination or asking for permission.</p> <p><a href="https://www.iana.org/domains/example">More information...</a></p> </div> </body> </html>
                                                                                          Add PHPDebugConsole middleware to existing Guzzle client
                                                                                          $guzzleClient->getConfig('handler')->push(
                                                                                              new \bdk\Debug\Collector\GuzzleMiddleware(array(
                                                                                                  'inclRequestBody' => true,  // default is false
                                                                                                  'inclResponseBody' => true, // default is false
                                                                                              ))
                                                                                          );
                                                                                          
                                                                                          $response = $guzzleClient->request('GET', 'http://example.com/');
                                                                                          Example Output
                                                                                          • Doctrine: sqlite:///:memory:
                                                                                            • logged operations: 1
                                                                                            • total time: 120.163 μs
                                                                                            • max memory usage = 1.32 kB
                                                                                            • connection info = array(
                                                                                              • url=>sqlite:///:memory:
                                                                                              • driver=>pdo_sqlite
                                                                                              • host=>localhost
                                                                                              • memory=>true
                                                                                              )

                                                                                          • Guzzle(GET, http://example.com/)
                                                                                            • request headers = GET / HTTP/1.1 User-Agent: GuzzleHttp/7 Host: example.com
                                                                                            • time: 87.4839 ms
                                                                                            • response headers = HTTP/1.1 200 OK Age: 595038 Cache-Control: max-age=604800 Content-Type: text/html; charset=UTF-8 Date: Thu, 12 Sep 2024 20:07:55 GMT Etag: "3147526947+ident" Expires: Thu, 19 Sep 2024 20:07:55 GMT Last-Modified: Thu, 17 Oct 2019 07:18:26 GMT Server: ECAcc (chd/0794) Vary: Accept-Encoding X-Cache: HIT Content-Length: 1256
                                                                                            • response body = <!doctype html> <html> <head> <title>Example Domain</title> <meta charset="utf-8" /> <meta http-equiv="Content-type" content="text/html; charset=utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <style type="text/css"> body { background-color: #f0f0f2; margin: 0; padding: 0; font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; } div { width: 600px; margin: 5em auto; padding: 2em; background-color: #fdfdff; border-radius: 0.5em; box-shadow: 2px 3px 7px 2px rgba(0,0,0,0.02); } a:link, a:visited { color: #38488f; text-decoration: none; } @media (max-width: 700px) { div { margin: 0 auto; width: auto; } } </style> </head> <body> <div> <h1>Example Domain</h1> <p>This domain is for use in illustrative examples in documents. You may use this domain in literature without prior coordination or asking for permission.</p> <p><a href="https://www.iana.org/domains/example">More information...</a></p> </div> </body> </html>

                                                                                          Monolog

                                                                                          There are two ways to use PHPDebugConsole as a monolog "handler"

                                                                                          1. MonologHandler

                                                                                            PHPDebugConsole provides a monolog handler.

                                                                                            This handler will pass along the monolog channel.

                                                                                            Example Source
                                                                                            $monolog = new \Monolog\Logger('PHPDebugConsole');
                                                                                            $monolog->pushHandler(new \bdk\Debug\Collector\MonologHandler());
                                                                                            $monolog->info('yup, it works');
                                                                                            Example Output
                                                                                            • Doctrine: sqlite:///:memory:
                                                                                              • logged operations: 1
                                                                                              • total time: 120.163 μs
                                                                                              • max memory usage = 1.32 kB
                                                                                              • connection info = array(
                                                                                                • url=>sqlite:///:memory:
                                                                                                • driver=>pdo_sqlite
                                                                                                • host=>localhost
                                                                                                • memory=>true
                                                                                                )

                                                                                            • yup, it works
                                                                                          2. Psr-3 Logger

                                                                                            Use Monolog's PSR-3 handler with PHPDebugConsole's PSR-3 logger

                                                                                            Example Source
                                                                                            $monolog = new \Monolog\Logger('PHPDebugConsole');
                                                                                            $monolog->pushHandler(new \Monolog\Handler\PsrHandler($debug->logger));
                                                                                            $monolog->info('yup, it works');
                                                                                            Example Output
                                                                                            • Doctrine: sqlite:///:memory:
                                                                                              • logged operations: 1
                                                                                              • total time: 120.163 μs
                                                                                              • max memory usage = 1.32 kB
                                                                                              • connection info = array(
                                                                                                • url=>sqlite:///:memory:
                                                                                                • driver=>pdo_sqlite
                                                                                                • host=>localhost
                                                                                                • memory=>true
                                                                                                )

                                                                                            • yup, it works
                                                                                          PHPDebugLogger doesn't include monolog. Install separately if needed.
                                                                                          Changelog:
                                                                                          • v3.0: MonologHandler
                                                                                          • v2.3: Psr-3 Logger

                                                                                          MySqli

                                                                                          Php's mysqli extension
                                                                                          Example Source
                                                                                          /*
                                                                                              Instantiate and use PHPDebugConsole's MySqli client (in lieu of PHP's mysqli client)
                                                                                          */
                                                                                          $mysqli = new \bdk\Debug\Collector\MySqli('localhost', 'my_user', 'my_pass', 'my_db');
                                                                                          
                                                                                          $stmt = $mysqli->prepare("INSERT INTO `some_table` (`int`, `float`, `text`) VALUES (?, ?, ?)");
                                                                                          $stmt->bind_param('idds', $int, $decimal, $float, $text);
                                                                                          
                                                                                          $int = 42;
                                                                                          $float = 3.14;
                                                                                          $text = 'sweet';
                                                                                          
                                                                                          // execute prepared statement
                                                                                          $stmt->execute();

                                                                                          OAuth

                                                                                          Php's (PECL) OAuth class
                                                                                          Example Source
                                                                                          /*
                                                                                              Use the PHPDebugConsole OAuth class (extends OAuth)
                                                                                              All requests will be logged
                                                                                          */
                                                                                          $oauthClient = new \bdk\Debug\Collector\OAuth($consumerKey, $consumerSecret);

                                                                                          PDO

                                                                                          Php's PDO extension
                                                                                          Example Source
                                                                                          $pdo = new \PDO('sqlite::memory:');
                                                                                          $pdoDebug = new \bdk\Debug\Collector\Pdo($pdo);
                                                                                          
                                                                                          // use $pdoDebug just as you would
                                                                                          $stmt = $pdoDebug->prepare('SELECT *
                                                                                              FROM `bob`
                                                                                              WHERE e < :datetime');
                                                                                          $datetime = date('Y-m-d H:i:s');
                                                                                          $stmt->bindParam(':datetime', $datetime, PDO::PARAM_STR);
                                                                                          $stmt->execute();

                                                                                          PhpCurlClass

                                                                                          PHP Curl Class
                                                                                          Example Source
                                                                                          $curl = new \bdk\Debug\Collector\PhpCurlClass(array(
                                                                                              'inclResponseBody' => true,
                                                                                          ));
                                                                                          $curl->get('https://www.example.com/');

                                                                                          PSR-3 (Logger)

                                                                                          If you're using a library that uses psr/log getting up and runniing with PHPDebugConsole couldn't be easier.

                                                                                          logger method maps to
                                                                                          $logger->emergency() $debug->error()
                                                                                          $logger->alert() $debug->alert()
                                                                                          $logger->critical() $debug->error()
                                                                                          $logger->error() $debug->error()
                                                                                          $logger->warning() $debug->warn()
                                                                                          $logger->notice() $debug->warn()
                                                                                          $logger->info() $debug->info()
                                                                                          $logger->debug() $debug->log()
                                                                                          psr/log (PSR-3) example
                                                                                          $debug = new \bdk\Debug(array(
                                                                                              'collect' => true,
                                                                                              'output' => true,
                                                                                          ));
                                                                                          
                                                                                          $logger = $debug->logger;   // implements Psr\Log\LoggerInterface
                                                                                          
                                                                                          $logger->debug('This thing does {what}', array('what'=>'it all'));
                                                                                          $logger->critical('I literally can\'t even');
                                                                                          psr/log example output
                                                                                          • Doctrine: sqlite:///:memory:
                                                                                            • logged operations: 1
                                                                                            • total time: 120.163 μs
                                                                                            • max memory usage = 1.32 kB
                                                                                            • connection info = array(
                                                                                              • url=>sqlite:///:memory:
                                                                                              • driver=>pdo_sqlite
                                                                                              • host=>localhost
                                                                                              • memory=>true
                                                                                              )

                                                                                          • This thing does it all
                                                                                          • I literally can't even
                                                                                          PHPDebugLogger doesn't include psr/log. Install separately if needed.
                                                                                          Changelog:
                                                                                          • v2.3

                                                                                          PSR-16 (SimpleCache)

                                                                                          psr/simple-cache
                                                                                          Example Source
                                                                                          $cache = new \bdk\Debug\Collector\SimpleCache($someSimpleCacheImplementation);
                                                                                          $cache->get('twitterFeed');

                                                                                          SoapClient

                                                                                          Php's SoapClient class
                                                                                          Example Source
                                                                                          /*
                                                                                              Use the PHPDebugConsole SoapClient class (extends SoapClient)
                                                                                          */
                                                                                          $wsdl = 'http://www.SoapClient.com/xml/SQLDataSoap.wsdl';
                                                                                          $soapClient = new \bdk\Debug\Collector\SoapClient($wsdl);

                                                                                          SwiftMailer

                                                                                          Swift Mailer
                                                                                          Example Source
                                                                                          /*
                                                                                              Initialize Swift Mailer
                                                                                          */
                                                                                          $transport = new Swift_SendmailTransport('/usr/sbin/sendmail -bs');
                                                                                          $mailer = new Swift_Mailer($transport);
                                                                                          /*
                                                                                              After initializing Swift Mailer, add Logger Plugin
                                                                                          */
                                                                                          $logger = new \bdk\Debug\Collector\SwiftMailerLogger();
                                                                                          $mailer->registerPlugin($logger);
                                                                                          /*
                                                                                              Send a message
                                                                                          */
                                                                                          $message = (new Swift_Message('Definitely Not Spam'))
                                                                                              ->setFrom(['bkfake-github@ryahoo.com' => 'Brad Kent'])
                                                                                              ->setTo(['randyr@domain.org' => 'Randy Recipient'])
                                                                                              ->setBody('Here is the message itself');
                                                                                          $result = $mailer->send($message);

                                                                                          Twig Templates

                                                                                          Twig
                                                                                          Example Source
                                                                                          /*
                                                                                              Instantiate Twig
                                                                                          */
                                                                                          $loader = new Twig_Loader_Filesystem(__DIR__);
                                                                                          $twig = new Twig_Environment($loader);
                                                                                          
                                                                                          /*
                                                                                              Add PHPDebugConsole's TwigExtension
                                                                                          */
                                                                                          $twig->addExtension(new \bdk\Debug\Collector\TwigExtension());
                                                                                          
                                                                                          echo $twig->render('test.twig', array(
                                                                                              'name' => 'Test',
                                                                                          ));

                                                                                          PSR-7 & PSR-15

                                                                                          Response (PSR-7)

                                                                                          Debug object provides a writeToResponse method for outputting debug to PSR-7 response or HttpFoundation response object.

                                                                                          See writeToResponse for more info.

                                                                                          Middleware (PSR-15)

                                                                                          PHPDebugConsole provides a PSR-15 Middleware you may use in your projects.

                                                                                          Example Source
                                                                                          /** @var Psr\Http\Server\MiddlewareInterface;*/
                                                                                          $middleware = $debug->middleware;

                                                                                          Changelog

                                                                                          v3.3 – Coming soon

                                                                                          • usage without composer no longer officially supported.
                                                                                            • bdk/http-message no longer bundled and is now a dependency
                                                                                            • Autoloader class given two new methods: addClass($className, $filepath) & addPsr4($namespace, $dir)
                                                                                          • Php 8.4
                                                                                          • Confusable characters now highlighted (as whitespace / control chars are)
                                                                                          • PDO / mysqli transaction methods no longer open / close a group. Now create an info logEntry
                                                                                          • PhpDoc
                                                                                            • descriptions and summaries are now sanitized
                                                                                            • Full phpDoc now captured for properties and constants (formerly only the descritpion)
                                                                                            • @deprecated, @since, & version tags now parsed into version & desc values
                                                                                          • alert() method now accepts multiple arguments (like log, info, error, & warn)
                                                                                          • trace() method - new limit argument. Arguments may be passed in any order
                                                                                          • properties: collect 'isDeprecated'
                                                                                          • Response not always getting captured
                                                                                          • Code quality / maintainability improvements

                                                                                          v3.2 – 2024-01-03

                                                                                          • objectSort config is now a space separated list with (default = "inheritance visibility name")
                                                                                          • Implements now stored as a structure that conveys interface inheritance
                                                                                          • What interfaces a method implements are now collected for every implemented interface (prev a select few such as ArrayAccess)
                                                                                          • new config options: methodStaticVarCollect & methodStaticVarOutput
                                                                                          • anonymous objects now collected & stored like other objects… collecting attributes, phpDoc, & interfaces in the process
                                                                                          • html output :
                                                                                            • display icon on methods implementing an interface (hover for more info)
                                                                                            • display phpDoc @throws info
                                                                                            • no longer add "inherited" classname to methods/properties/constants (redundant to data-inherited-from attribute)
                                                                                            • properties/methods now grouped by inheritance by default. (dependent on "objectSort" first sorted by 'inheritance')
                                                                                            • new interfacesCollapse config
                                                                                            • new objectSectionOrder config.
                                                                                              defaults to ['attributes', 'extends', 'implements', 'constants', 'cases', 'properties', 'methods', 'phpDoc']

                                                                                          v3.1.2 – 2023-12-19

                                                                                          • Debug::varDump() not escaping special chars
                                                                                          • Utility/Php::getIniFiles() not properly handling empty return from php_ini_scanned_files()
                                                                                          • ErrorHandler::handleException() - check headers_sent() before calling http_response_code(500)

                                                                                          v3.1.1 – 2023-12-06

                                                                                          • LogRequest - not "parsing" content-type correctly / not displaying $_POST values (ie for multipart/form-data)
                                                                                          • ReqRes::getResponseHeaders() merging default headers without regards to header case insensitivity leading to default Content-Type being added in addition to "Content-type" etc ... ReqRes::getResponseHeader('Content-Type') getting the default value. (only affects debug output)
                                                                                          • HttpMessage\ServerRequest::fromGlobals() now has $parseStrOpts param
                                                                                          • HttpMessage\Uri::fromGlobals() is now a public static method

                                                                                          v3.1 – 2023-11-18

                                                                                          • New Discord route (for errors)
                                                                                          • New Slack route (for errors)
                                                                                          • New Teams route (for errors)
                                                                                          • New varDump static method for in-place var_dump-like debugging
                                                                                          • Objects
                                                                                            • Overhaul object abstraction for more efficient collection / storage / serialization / transmission of data
                                                                                            • Collect (and display) php 8.2's class-level readOnly modifier
                                                                                            • Added visual callouts to dynamic properties
                                                                                            • Added visual callouts to constants/properties/methods that override ancestor
                                                                                          • New maxDepth option
                                                                                          • New Utility/Reflection class
                                                                                          • Internals
                                                                                            • Move more functionality / features / methods to plugins
                                                                                              all debug methods, "auto route", runtime-values
                                                                                            • Cleanup bootstrap process
                                                                                            • Move phpdoc type resolution to phpdoc parser.
                                                                                          • Underscore prefix no longer required to call most methods statically
                                                                                            \bdk\Debug::log('this is new') and \bdk\Debug::_log('still works')

                                                                                          v3.0.7 – 2023-11-18

                                                                                          • official PHP 8.3 support
                                                                                          • small javascript ui fixes

                                                                                          v3.0.5 / v3.0.6 – 2023-10-11

                                                                                          • Error may occur in certain scenarios when setting config via meta param / Abstracter not yet initialized
                                                                                          • Monolog handler - now compatible with monolog v1 - v3

                                                                                          v3.0.4 – 2023-05-29

                                                                                          • Add more redaction to collectors (Guzzle Request Target / Oauth signature)
                                                                                          • StatementInfo (MySqli, Doctrine, PDO) - don't truncate SQL statement (ignore stringMaxLen)
                                                                                          • improve UriUtils::parseUrl()
                                                                                          • wamp route sending null meta values
                                                                                          • bump bundled PrismJS to latest
                                                                                          • other minor fixes
                                                                                          • coding standards

                                                                                          v3.0.3 – 2023-02-04

                                                                                          • Non-composer autoloader doesn't load main Debug class! (facepalm)
                                                                                          • nested channels ignore their output config value.
                                                                                          • restore non-sidebar channel filter/toggles functionality (used by documentation)
                                                                                          • minor regression with base64-encoded strings' flat-tab html output
                                                                                          • Add unit tests for MonologHandler, & PhpCurlClass collector

                                                                                          v3.0.2 – 2023-01-13

                                                                                          • Guzzle middleware tweaks
                                                                                          • SoapClient collector improvements
                                                                                          • Yii 1.1 tweaks
                                                                                          • Declare closures as static when possible
                                                                                          • Tweak phpcs rules
                                                                                          • Encoded strings.. Don't nest tabs / refactor w/ new HtmlStringEncoded class
                                                                                          • Redact basic password from URLs

                                                                                          v3.0.1 – 2022-11-14

                                                                                          • HttpMessage\Uri::withScheme -> allow empty value
                                                                                          • bdk\Debug\Psr3\Logger (psr3 implemenation) is now compatible with psr/log v1, v2, & v3
                                                                                          • FindExit error when exit/Fatal from static method
                                                                                          • Don't attempt to resolve complex array doctypes
                                                                                          • GuzzleMiddleware tweaks
                                                                                          • new HttpMessage\UriUtils class

                                                                                          v3.0 – 2022-10-14

                                                                                          • Much improved HTML UI/UX
                                                                                            • new drawer + filter sidebar
                                                                                            • syntax highlighted json, xml, sql, php
                                                                                            • first argument now sanitized (htmlspecialchars) by default
                                                                                            • editor links (click on error to open relevant file/line in your editor/IDE)
                                                                                            • objects - ability to toggle inherited methods
                                                                                            • fatal error backtraces get context (file-snippets)
                                                                                            • output log-entry divs replaced with more semantic ul/li
                                                                                            • included files output as file tree
                                                                                          • PHP 8.0 : Attributes logged
                                                                                          • PHP 8.1 : Enum support
                                                                                          • PHP 8.2 : #[\SensitiveParameter] support
                                                                                          • ErrorHandler v3
                                                                                            • New Error class (extends generic Event) replaces array
                                                                                            • Error notifications no longer emailed by default (see new enableEmailer config option)
                                                                                          • Included decorators/helpers for logging PDO, mysqli, Doctrine, Guzzle, Curl, OAuth, SimpleCache, Soap, Twig, SwiftMailer
                                                                                          • MiddlewareInterface (PSR-15), & new writeToResponse() method (PSR-7)
                                                                                          • New AssetProviderInterface / addPLugin / removePlugin methods
                                                                                          • New LogEntry object replaces array
                                                                                          • New Abstraction object replaces array
                                                                                          • rewritten javascript / css built from SCSS
                                                                                          • Tons of small enhancements

                                                                                          v2.3 – 2020-01-03

                                                                                          • PSR-3 implementation
                                                                                          • "Channels" (akin to monolog's channels) - see getChannel()
                                                                                          • New methods:
                                                                                          • New config options
                                                                                            • outputHeaders (default true) Whether headers should be output (ie with chromeLogger and firePHP) this provides flexibility with frameworks, PSR7 responseInterface, etc
                                                                                            • enableProfiling set to true if you will be using profile and profileEnd methods
                                                                                          • value not shown for protected/private property that also has magic phpDoc annotation
                                                                                          • ErrorHandler\ErrorEmailer throttle file not being created if doesn't exist
                                                                                          • undefined variable throttleData in ErrorEmailer.php
                                                                                          • Objects
                                                                                            • Properties not returned by __debugInfo are now output with ability to show/hide (like private/protected)
                                                                                            • debug.objAbstractStart : new event value : propertyOverrideValues. Similar to having a __debugInfo() method
                                                                                            • debug.objAbstractEnd : properties have a new flag - forceShow: initially show the property/value (even if protected or private)
                                                                                            • __debugInfo() is no longer called if collectPropertyValues is false
                                                                                            • objects now check if a instanceof objects listed in objectExclude rather than exact class match
                                                                                          • Request headers now logged by default (see config logEnvInfo)
                                                                                          • HTML output :
                                                                                            • clicking on strings/floats/ints will copy their values to the clipboard
                                                                                            • Long strings are now initially collapsed / given "view-all" toggle
                                                                                          • assert() - support for styling/substitutions
                                                                                          • groupEnd() now accepts a single value. This value represents the group's return value and will be displayed when the group is both expanded and collapsed.
                                                                                          • output() now accepts a config array.
                                                                                          • Handle html_errors and docref_root php settings. Don't double htmlspecialchars() error message
                                                                                          • Internal
                                                                                            • OutputInterface : $path parameter removed from dump() method
                                                                                            • tests for ErrorHandler & PubSub moved to their own repos
                                                                                            • Wamp plugin now only base64-encodes strings that are not UTF-8

                                                                                          v2.2 – 2018-06-18

                                                                                          • Added clear() method
                                                                                          • Custom methods can now be called statically
                                                                                          • Issues when leaving summary groups open and outputting as HTML
                                                                                          • Internal autoloader only registered if necessary
                                                                                          • some \bdk\Debug\Utilities methods beefed up & now more useful outside debugger: arrayPathGet, arrayMergeDeep, & getCallerInfo

                                                                                          v2.1.1 – 2018-05-21

                                                                                          • setCfg('string', newValue) not properly returning previous value -> collect is always on. Bug introduced in v2.1. Unit-test added.
                                                                                          • Chromelogger - invalid javascript console methods need to be mapped to log()
                                                                                          • Script - invalid javascript console methods need to be be mapped to log()
                                                                                          • return value added to debug.outputLogEntry event. Event is no longer worthless
                                                                                          • alert() now publishes debug.outputLogEntry when being output
                                                                                          • \bdk\Debug\Utilities::buildAttribString() - now with more utility
                                                                                          • Can now instantiate via static method call, ie \bdk\Debug::_setConfig(), \bdk\Debug::_log('collect is false, so this is pointless'), etc. Because why not

                                                                                          v2.1.0 – 2018-05-04

                                                                                          • Custom methods: add your own custom methods by subscribing to the debug.log and/or debug.outputLogEntry events
                                                                                          • Remove internal frames from fatal error trace (2.0.2 Regression)
                                                                                          • Notice thrown when handling a fatal error with xdebug enabled & no backtrace frames
                                                                                          • count()
                                                                                            • optional 2nd param : Disable increment and/or output
                                                                                            • when not using a label, file & line logged as meta data - output as title attribute for html
                                                                                          • groupSummary() calls can now be nested & other groupSummary improvements
                                                                                          • table()
                                                                                            • Now accepts a Traversable object as param. Array-o-traversable was already a thing, but top-level Traversable had been overlooked
                                                                                            • Just display stringified or __toString value if applicable
                                                                                          • setting outputAs now clears previous value (unsubscribes events)
                                                                                            (to use multiple output plugins/routes, use $debug->addPlugin())
                                                                                          • POST requests : display php://input and content-type if $_POST is empty
                                                                                          • debug.objAbstractStart event : reflector, hist, & debugMethod values now avail to subscribers
                                                                                          • ChromeLogger & Script output now get stylish alerts
                                                                                          • New config option: onEUserError gives control of E_USER_ERROR behavior
                                                                                          • Internal
                                                                                            • ErrorHandler and ErrorEmailer moved outside of bdk\Debug namespace / have no dependencies
                                                                                            • Output classes now in Output namespace & implement OutputInterface
                                                                                            • separate method & args in data.log
                                                                                            • store some args as meta for alert(), table(), & groupSummary()
                                                                                            • debug.output event now only published if cfg.output == true
                                                                                            • moderate performance gains by using absolute function references (ie \func_get_args())
                                                                                            • more unit tests

                                                                                          v2.0.2 – Oops – 2018-02-02

                                                                                          • Regression: 2.0.1 didn't output fatal errors as HTML
                                                                                            (error captured after output took place)
                                                                                          • static methods can now be called before instance created
                                                                                            ie \bdk\Debug::_setCfg(array('collect'=>true, 'output'=>true));
                                                                                          • Unit tests for fatal errors! (It's magic)

                                                                                          v2.0.1 – 2018-01-22

                                                                                          • emailLog feature broken. Fix and make better than new
                                                                                          • Abstracter: initializing with a `objectsExclude` value, not adding default "\bdk\Debug" exclusion
                                                                                          • Utilities::arrayMergeDeep: add condition for array(object, 'string') (callable)
                                                                                            "edge case" where updating cfg callable twice munges the stored callable
                                                                                          • onLog, onError, & onOutput config values : now replace existing subscriber set via setCfg, rather than add new subscriber (doesn't not affect adding subscribers via eventManager)
                                                                                          • PubSub\Manager now publishes a "php.shutdown" convenience event - subscribe and unsubscribe to shutdown!
                                                                                          • Some internal tweaks and variable name changes
                                                                                          • Unit-tests for emailing log & errors
                                                                                          • HHVM Travis build now works!

                                                                                          v2.0 – The Refactoring – 2017-12-26

                                                                                          • fully quallified classname is now \bdk\Debug (was \bdk\Debug\Debug)
                                                                                          • get() & set() methods renamed to getCfg() & setCfg() respectfully.
                                                                                          • All instance methods can now be called staticly by prefixing "_" to the method name.
                                                                                            ie \bdk\Debug::_log('I was logged statically');
                                                                                          • HUGE HTML rendering performance improvement
                                                                                            • Pages with lots-o-debug output could take quite some for domReady.
                                                                                            • Furthermore, it could take a very significant amount of time to enhance the output with collapsibles and icons and whatnot.
                                                                                            • Could result in unresponsive script / unresponse browser.
                                                                                          • Object enhancements / fixes:
                                                                                            • private methods from parent object no longer listed
                                                                                            • methods used to implement PHP's ArrayAccess, Countable, Iterator, and IteratorAggregate interfaces are now initially hidden. (Visibility toggled via the object's list of implemented interfaces)
                                                                                            • inherited constants now shown
                                                                                            • debugging a mysqli instance when not connected would throw "property access is not allowed yet" errors
                                                                                            • more docBlock parsing.
                                                                                              • Support for {@inheritdoc}
                                                                                              • properties and methods defined via @method & @property tags incoporated into object's property & method list
                                                                                              • links created for @link & @see (when url)
                                                                                            • displayed __toString value is now limited to 100 chars
                                                                                            • deprecated methods designated as such via muted color and icon
                                                                                            • ancestor private properties designated as such via muted color and icon
                                                                                            • if a method param's default-value is a constant, the constant's name, rather than value is displayed (php >= 5.4.6)
                                                                                          • String debugging: Unicode "Separator" and other "special" characters are now highlighted
                                                                                            previously:
                                                                                            Thanks Obama&copy;
                                                                                            now:
                                                                                            Thanks\u00a0Obama&copy;
                                                                                            That non-break-space character was very easy to miss.
                                                                                            Htmlentities (ie &nbsp; & &copy;) will still appear as html entities
                                                                                          • New output options:
                                                                                            chromeLogger
                                                                                            ajax and non-html output now defaults to ChromeLogger (was FirePHP)
                                                                                            Firefox has built-in support, Chrome has an extension
                                                                                            wamp
                                                                                            sends log to wamp router in realtime for true console-like logging
                                                                                          • table()
                                                                                            • now works on arrays of objects (which may implement Traversable)
                                                                                            • Sortable in HTML output
                                                                                            • now supports additional argument to specify which columns are displayed
                                                                                          • log, error, info, & warn methods now support substitution/formatting
                                                                                          • secondary Debug instances were – in part – still referencing the initial (singleton) instance
                                                                                          • config() not always setting all values when passing nested arrays
                                                                                            • Integrated fatal "alert" with error summary.
                                                                                            • if xdebug installed/enabled:
                                                                                              • Fatal now displays backtrace
                                                                                              • Fatal backtrace included in error email
                                                                                          • New methods
                                                                                          • New utility method: getIncludedFiles() - get_included_files() plus logical sorting
                                                                                          • group() and groupCollapsed()
                                                                                            • default label is now current function's name (or "group" if outside of a function)
                                                                                            • can now pass "hideIfEmpty" "option"
                                                                                          • Arrays matching array(Object, 'string') now interpreted & displayed as a callable
                                                                                          • Better handling of single param passed to log, error, info, & warn (whether htmlspecialchars & visual whitespace applied)
                                                                                          • FirePHP
                                                                                            • No more dependancy on FirePHP.class.php (aka firephp core library)
                                                                                              configuration options removed from \bdk\Debug (options were passed to FirePHP.class.php)
                                                                                            • Check if headers sent before attempting to output
                                                                                            • File & line information now properly passed with error & warn methods
                                                                                            • ajax and non-html output now defaults to chromeLogger output rather than FirePHP
                                                                                          • Internal:
                                                                                            • error notification email functionality separated from errorHandler.
                                                                                              errorHandler is now a lean, mean, stand-alone, error-dispatching machine.
                                                                                            • events/callbacks:
                                                                                              "callbacks" are now handled via an "event manager" pattern.
                                                                                              • Multiple "subscribers" can now listen to each event.
                                                                                              • "Subscriber" can modify event properties, stop propagation, etc.
                                                                                              • onError and onOutput callbacks now receive \bdk\PubSub\Event object (onError received an array, onOutput received the debug instance)
                                                                                              • onError: stats array is now populated with current data
                                                                                              • New event/callback onLog - "published" before data appended to log
                                                                                                call stopPropagation() on the passed event object to prevent logging
                                                                                            • microtime stored as float rather than string

                                                                                          v1.3.2 2015-08-24

                                                                                          • PHPDoc comment parsing - fixed PREG overflow issue on long comments
                                                                                          • plain-text output method added
                                                                                          • CLI debugging defaults to text
                                                                                          • HTTP_REFERER now included in error email
                                                                                          • request uri and method now included debug-log email body
                                                                                          • extends and implements info now output for objects
                                                                                          • added special case for debugging DOMNodeList objects... now displays the public yet "hidden" length property
                                                                                          • improved toUtf8 utility method
                                                                                          • minor css tweaks
                                                                                          • get() and set() now only have access to configuration
                                                                                          • added dataGet() and dataSet() methods for directly interacting with the log data
                                                                                          • timeEnd() and timeGet() accept a template. default: "%label: %time"
                                                                                          • moved code to "src" folder
                                                                                          • Utilizing Travis-CI for PHPUnit tests
                                                                                          • Added and organized unit tests..
                                                                                          • moved configuration to new Config class
                                                                                          • removed protected property "collect"... simply use cfg['collect']

                                                                                          v1.3.1 2015-05-05

                                                                                          • nested arrays weren't being output via the table() method
                                                                                          • HTML output now has a checkbox to toggle passing the debug param via cookie
                                                                                          • setErrorCaller may fail to resolve calling file/line if call_user_func was in the stack trace
                                                                                          • emailThrottledSummary : new option to disable email summary of throttled errors
                                                                                            Scenario:
                                                                                            1. error a occurs… which fires off an error alert email. The error continues to occur but the error is emailed no more than once every emailMin minutes.
                                                                                            2. error b occurs… which fires off an error alert email. "Trash Collection" is performed on the throttle log. If there is a record of error a (or any other error) having occured more than emailMin minutes ago (and which did not trigger an email notice), a summary of these errors will be emailed

                                                                                          v1.3 2015-04-01

                                                                                          • objectExclude option - specify classNames to exclude from inspecting if found nested in array or object properties
                                                                                          • objectSort option - sort object's properties, methods, & constants by 'name', 'visibility', or unsorted

                                                                                          v1.3b2 2015-03-17

                                                                                          • bug #13. Affected debugging objects with properties that weren't declared in the class - PHP bug #69249
                                                                                          • Object constants are now output
                                                                                          • Object's __debugInfo method now used if defined
                                                                                          • Collapsed groups get an indicator if they contain an error or warning
                                                                                          • New config options useDebugInfo, collectConstants, outputConstants

                                                                                          v1.3b 2015-02-27

                                                                                          • Much more detailed output for objects.
                                                                                            Uses PHP's reflection class - which in turn may read PHPDoc comments - to provide details such as method parameters, return type, visibility, and descriptions.
                                                                                          • New config settings:
                                                                                            • emailfunc (default value = "mail")
                                                                                              Accepts a callable that receivies to, subject, and body. Email's generated by the debugger are passed to this function.
                                                                                            • collectMethods (default value = true)
                                                                                            • outputMethods (default value = true)
                                                                                          • New outputAs option: "script"
                                                                                            Generates <script> with console calls
                                                                                          • CSS: Added "m_" prefix to method classnames (.log, .info, .error, .warn, etc)
                                                                                          • Removed deprecated method setCfg()
                                                                                          • Removed Utilities::isRecursive()
                                                                                          • Renamed & shuffled many internal / protected methods

                                                                                          v1.2 2014-12-03

                                                                                          • Installable via Composer as bdk/Debug
                                                                                          • Explicitly calling output() is no longer necessary
                                                                                          • Param passed to onError function changed from boolean to array
                                                                                            New Param
                                                                                            array $error - an array containing all sorts of useful error details.
                                                                                            If the error is fatal, $error['category'] will be "fatal"
                                                                                            This is the same array returned by get('lastError')
                                                                                            Previous
                                                                                            boolean $isFatal
                                                                                          • if emailLog is set to "onError", an error matching the ErrorHandler/emailMask mask option must have occured for email to be sent. Previously, any error (incl deprecated) would have qualified.
                                                                                          • moved errorMask option from ErrorHandler to Debug
                                                                                          • ErrorHandler class (introduced in v1.1) is now a stand-alone class (no dependencies) and can used completely independently of the debug class.

                                                                                            Documentation coming soon, but a few core ErrorHandler methods include:

                                                                                            • getInstance - get the instance of ErrorHandler
                                                                                            • get and set - get and set config values
                                                                                            • register & unregister - register/unregister the error handler
                                                                                            • registerOnErrorFunction($callable) - register an onError "callback"
                                                                                              • onError function gets passed a single param - array $error
                                                                                              • Multiple callbacks may be registered
                                                                                              • Yes, even fatal errors!
                                                                                            • unregisterOnErrorFunction($callable) - unregister an onError function
                                                                                            • setErrorCaller - Debug's setErrorCaller() simply calls this
                                                                                          • Ton of internal reorganization

                                                                                          v1.1 2014-10-10

                                                                                          • Dropped PHP4 support
                                                                                          • Now namespaced namespace bdk\Debug;
                                                                                          • Internal: now follows PSR-2 coding standard
                                                                                          • Internal: error-handling methods and functionality now in separate classes
                                                                                          • Internal: base css moved to Debug.css
                                                                                          • cfg and data properties are now protected
                                                                                          • added singleton getInstance method - which is the preferred way to instantiate the class: $debug = \bdk\Debug::getInstance();
                                                                                          • the javascript is now output with the log (by default) - no need to output/include separately
                                                                                          • New config options
                                                                                            • firephpOptions (array)
                                                                                            • outputScript (boolean) true
                                                                                            • filepathCss (string) "./Debug.css"
                                                                                            • filepathScript (string) "./Debug.jquery.min.js"
                                                                                          • deprecated setCfg(). Use set() (which semantically matches "get()")
                                                                                          • FirePHP options are now configurable
                                                                                          • FirePHP's default path changed from ./FirePHP/FirePHP.class.php to ./FirePHP.class.php
                                                                                          Fork me on GitHub
                                                                                          PHPDebugConsole

                                                                                            • Request
                                                                                            • request headers
                                                                                               value
                                                                                              Accepttext/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
                                                                                              Accept-Encodinggzip, deflate, br, zstd
                                                                                              Accept-Languageen-US,en;q=0.9,fr;q=0.8
                                                                                              Cache-Controlno-cache
                                                                                              Connectionkeep-alive
                                                                                              Cookiedebug=backdoor; SESSIONID=dv4ekvip4c56ir34ujq4g7qsk3
                                                                                              Dnt1
                                                                                              Hostlocal.bradkent.com
                                                                                              Pragmano-cache
                                                                                              Sec-Ch-Ua"Chromium";v="128", "Not;A=Brand";v="24", "Google Chrome";v="128"
                                                                                              Sec-Ch-Ua-Mobile?0
                                                                                              Sec-Ch-Ua-Platform"macOS"
                                                                                              Sec-Fetch-Destdocument
                                                                                              Sec-Fetch-Modenavigate
                                                                                              Sec-Fetch-Sitenone
                                                                                              Sec-Fetch-User?1
                                                                                              Sec-Gpc1
                                                                                              Upgrade-Insecure-Requests1
                                                                                              User-AgentMozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36
                                                                                            • $_COOKIE
                                                                                               value
                                                                                              SESSIONIDdv4ekvip4c56ir34ujq4g7qsk3
                                                                                              debugbackdoor
                                                                                            • Response
                                                                                            • response headers
                                                                                               value
                                                                                              Content-Typetext/html
                                                                                              CookieSESSIONID=5umr2d3e392f6idhvpadiqs7r0
                                                                                            • Not logging response body for Content-Type "text/html"
                                                                                            • Content-Length = 0

                                                                                              • 17 files required
                                                                                              • 12 files logged
                                                                                              • array(
                                                                                                • /var/www=>array(
                                                                                                  • 0=>controllers/php/Debug.php
                                                                                                  • vendor=>array(
                                                                                                    • 0=>5 omitted
                                                                                                    )
                                                                                                  • views/php/debug=>array(
                                                                                                    • 0=>index.php
                                                                                                    • 1=>changelog.php
                                                                                                    • 2=>config.php
                                                                                                    • 3=>events.php
                                                                                                    • 4=>framework.php
                                                                                                    • 5=>index.php
                                                                                                    • 6=>methods.php
                                                                                                    • 7=>overview.php
                                                                                                    • 8=>route.php
                                                                                                    )
                                                                                                  • 1=>bootstrap.php
                                                                                                  • 2=>index.php
                                                                                                  )
                                                                                                )

                                                                                                • PHP Version = 8.3.10
                                                                                                • ini files = array(
                                                                                                  • /usr/local/etc/php/8.3/php.ini
                                                                                                  • /usr/local/etc/php/8.3/conf.d/20-xdebug.ini
                                                                                                  • /usr/local/etc/php/8.3/conf.d/ext-opcache.ini
                                                                                                  )
                                                                                                • date.timezone = America/Chicago
                                                                                                • memory_limit = redacted MB
                                                                                                • expose_php: should be disabled
                                                                                                • Xdebug v3.3.0 is installed (mode: debug,coverage,develop)
                                                                                                • $_SERVER = array(
                                                                                                  • REMOTE_ADDR=>127.0.0.1
                                                                                                  • REQUEST_TIME=>1726171669
                                                                                                  • REQUEST_URI=>/php/debug/3.2?clearCache
                                                                                                  • SERVER_ADDR=>127.0.0.1
                                                                                                  • SERVER_NAME=>local.bradkent.com
                                                                                                  )

                                                                                                  • session.cookie_httponly: should be enabled
                                                                                                  • session.cache_limiter = nocache
                                                                                                  • session save_path = /var/tmp/
                                                                                                  • session name = SESSIONID
                                                                                                  • session id = dv4ekvip4c56ir34ujq4g7qsk3
                                                                                                  • $_SESSION = array()
                                                                                                  • git branch: master
                                                                                                  • Built In 233.314 ms
                                                                                                  • Peak Memory Usage ?⃝: 8 MB / redacted MB
                                                                                                  • PDO info: mysql, Localhost via UNIX socket
                                                                                                    • logged operations: 1
                                                                                                    • total time: 0.05432
                                                                                                    • max memory usage = 28.12 kB
                                                                                                    • server info = array(
                                                                                                      • Flush tables=>1
                                                                                                      • Open tables=>1224
                                                                                                      • Opens=>5657
                                                                                                      • Queries per second avg=>0.382
                                                                                                      • Questions=>254442
                                                                                                      • Slow queries=>0
                                                                                                      • Threads=>3
                                                                                                      • Uptime=>665846
                                                                                                      • Version=>5.7.19
                                                                                                      )

                                                                                                  • SELECT * FROM `user`…
                                                                                                    • SELECT * FROM `user` WHERE `id` = '1' LIMIT 1
                                                                                                    • duration: 600 μs
                                                                                                    • memory usage = 21.21 kB
                                                                                                    • rowCount = 1
                                                                                                  • get("exampleDebugOutput") took 0.00070sec
                                                                                                  • Notice: Undefined variable: foo, /path/to/myController.php (line 34)