commit 2972ea49c83aa4e752cd075d8966b78e889eb166 Author: maximebf Date: Thu Jun 13 18:47:17 2013 +0800 first commit diff --git a/all.html b/all.html new file mode 100644 index 0000000..ac34146 --- /dev/null +++ b/all.html @@ -0,0 +1,554 @@ + + + + + PHP Debug Bar + + + + + + + + + + + + +
+ + + + +

PHP Debug Bar

+

Displays a debug bar in the browser with information from php. +No more var_dump() in your code! + +

+

Screenshot + +

+

Features: + +

+
    +
  • Generic debug bar with no other dependencies
  • +
  • Easy to integrate with any project
  • +
  • Clean, fast and easy to use interface
  • +
  • Handles AJAX request
  • +
  • Includes generic data collectors and collectors for well known libraries
  • +
  • The client side bar is 100% coded in javascript
  • +
  • Easily create your own collectors and their associated view in the bar
  • +
+

Installation

+

The easiest way to install DebugBar is using Composer +with the following requirement: + +

+
{
+    "require": {
+        "maximebf/debugbar": ">=1.0.0"
+    }
+}
+

Alternatively, you can download the archive +and add the src/ folder to PHP's include path: + +

+
set_include_path('/path/to/src' . PATH_SEPARATOR . get_include_path());
+

DebugBar does not provide an autoloader but follows the PSR-0 convention.
You can use the following snippet to autoload ConsoleKit classes: + +

+
spl_autoload_register(function($className) {
+    if (substr($className, 0, 8) === 'DebugBar') {
+        $filename = str_replace('\\', DIRECTORY_SEPARATOR, trim($className, '\\')) . '.php';
+        require_once $filename;
+    }
+});
+

Quick start

+

DebugBar is very easy to use and you can add it to any of your projets in no time. +The easiest way is using the render() functions + +

+
<?php
+use DebugBar\StandardDebugBar;
+use DebugBar\Renderer\JavascriptRenderer;
+
+$debugbar = new StandardDebugBar();
+$debugbarRenderer = $debugbar->getJavascriptRenderer();
+
+$debugbar["messages"]->addMessage("hello world!");
+?>
+<html>
+    <head>
+        <?php echo $debugbarRenderer->renderHead() ?>
+    </head>
+    <body>
+        ...
+        <?php echo $debugbarRenderer->render() ?>
+    </body>
+</html>
+

The DebugBar uses DataCollectors to collect data from your PHP code. Some of them are +automated but others are manual. Use the DebugBar like an array where keys are the +collector names. In our previous example, we add a message to the MessagesCollector: + +

+
$debugbar["messages"]->addMessage("hello world!");
+

StandardDebugBar activates all bundled collectors: + +

+
    +
  • MemoryCollector (memory)
  • +
  • MessagesCollector (messages)
  • +
  • PhpInfoCollector (php)
  • +
  • RequestDataCollector (request)
  • +
  • TimeDataCollector (time)
  • +
+

Learn more about DebugBar in the docs. +

+ +

PHP Debug Bar

+

Displays a debug bar in the browser with information from php. +No more var_dump() in your code! + +

+

Screenshot + +

+

Features: + +

+
    +
  • Generic debug bar with no other dependencies
  • +
  • Easy to integrate with any project
  • +
  • Clean, fast and easy to use interface
  • +
  • Handles AJAX request
  • +
  • Includes generic data collectors and collectors for well known libraries
  • +
  • The client side bar is 100% coded in javascript
  • +
  • Easily create your own collectors and their associated view in the bar
  • +
+

Installation

+

The easiest way to install DebugBar is using Composer +with the following requirement: + +

+
{
+    "require": {
+        "maximebf/debugbar": ">=1.0.0"
+    }
+}
+

Alternatively, you can download the archive +and add the src/ folder to PHP's include path: + +

+
set_include_path('/path/to/src' . PATH_SEPARATOR . get_include_path());
+

DebugBar does not provide an autoloader but follows the PSR-0 convention.
You can use the following snippet to autoload ConsoleKit classes: + +

+
spl_autoload_register(function($className) {
+    if (substr($className, 0, 8) === 'DebugBar') {
+        $filename = str_replace('\\', DIRECTORY_SEPARATOR, trim($className, '\\')) . '.php';
+        require_once $filename;
+    }
+});
+

Quick start

+

DebugBar is very easy to use and you can add it to any of your projets in no time. +The easiest way is using the render() functions + +

+
<?php
+use DebugBar\StandardDebugBar;
+use DebugBar\Renderer\JavascriptRenderer;
+
+$debugbar = new StandardDebugBar();
+$debugbarRenderer = $debugbar->getJavascriptRenderer();
+
+$debugbar["messages"]->addMessage("hello world!");
+?>
+<html>
+    <head>
+        <?php echo $debugbarRenderer->renderHead() ?>
+    </head>
+    <body>
+        ...
+        <?php echo $debugbarRenderer->render() ?>
+    </body>
+</html>
+

The DebugBar uses DataCollectors to collect data from your PHP code. Some of them are +automated but others are manual. Use the DebugBar like an array where keys are the +collector names. In our previous example, we add a message to the MessagesCollector: + +

+
$debugbar["messages"]->addMessage("hello world!");
+

StandardDebugBar activates all bundled collectors: + +

+
    +
  • MemoryCollector (memory)
  • +
  • MessagesCollector (messages)
  • +
  • PhpInfoCollector (php)
  • +
  • RequestDataCollector (request)
  • +
  • TimeDataCollector (time)
  • +
+

Learn more about DebugBar in the docs. +

+ +

Collecting Data

+

Using collectors

+

Collectors can be added to your debug bar using addCollector(). + +

+
$debugbar = new DebugBar();
+$debugbar->addCollector(new DataCollector\RequestDataCollector());
+

Each collector as a unique name as defined by its getName() method. You can +access collectors using getCollector($name). + +

+
$debugbar->addCollector(new DataCollector\MessagesCollector());
+$debugbar->getCollector('messages')->addMessage("foobar");
+// or:
+$debugbar['messages']->addMessage("foobar");
+

Data will be collected from them when the debug bar is rendered. You can however +collect the data earlier using collect(). + +

+
$debugbar->collect();
+

Creating collectors

+

Collectors must implement the DebugBar\DataCollector\DataCollectorInterface. They +may subclass DebugBar\DataCollector\DataCollector which provides utility methods. + +

+

Collectors must provide a getName() function returning their unique name and a +collect() function returning some json-encodable data. The latter will be called at the +same time the DebugBar::collect() method is called. + +

+
class MyDataCollector extends DebugBar\DataCollector\DataCollector
+{
+    public function collect()
+    {
+        return array("uniqid" => uniqid());
+    }
+
+    public function getName()
+    {
+        return 'mycollector';
+    }
+}
+
+$debugbar->addCollector(new MyDataCollector());
+

This however won't show anything in the debug bar as no information are provided +on how to display these data. You could do that manually as you'll see in later chapter +or implement the DebugBar\DataSource\Renderable interface. + +

+

To implement it, you must define a getWidgets() function which returns an array +of key/value pairs where key are control names and values control options as defined +in JavascriptRenderer::addControl($name, $options) (see Rendering chapter). + +

+
class MyDataCollector extends DebugBar\DataCollector\DataCollector implements DebugBar\DataCollector\Renderable
+{
+    // ...
+
+    public function getWidgets()
+    {
+        return array(
+            "mycollector" => array(
+                "icon" => "cogs",
+                "tooltip" => "uniqid()",
+                "map" => "uniqid",
+                "default" => "''"
+            )
+        );
+    }
+}
+

This will have the result of adding a new indicator to the debug bar. + +

+

Included collectors

+
    +
  • MemoryCollector (memory)
  • +
  • MessagesCollector (messages)
  • +
  • PhpInfoCollector (php)
  • +
  • RequestDataCollector (request)
  • +
  • TimeDataCollector (time)
  • +
+ +

Rendering

+

Rendering is performed using the `DebugBar\JavascriptRenderer̀ class. It contains +all the useful functions to included the needed assets and generate a debug bar. + +

+
$renderer = $debugbar->getJavascriptRenderer();
+

Assets

+

The debug bar relies on some css and javascript files which needs to be included +into your webpage. This can be done in two ways: + +

+
    +
  • Using JavascriptRenderer::renderHead() which will returns a string with +the needed script and link tags
  • +
  • Using Assetic and +JavascriptRenderer::getAsseticCollection()
  • +
+

I would recommend using the second method as Assetic is a very powerful asset +manager but the first method is provided to quickly integrate the debug bar +into any projets. + +

+

You can define the base url of your assets using setBaseUrl(). This is needed +in 99% of cases. If you are using Assetic, you may have to change the base path +of the assets if you moved the folder. This can be done using setBasePath(). + +

+

Using renderHead(): + +

+
<html>
+    <head>
+        ...
+        <?php echo $renderer->renderHead() ?>
+        ...
+    </head>
+    ...
+</html>
+

Using Assetic: + +

+
list($cssCollection, $jsCollection) = $renderer->getAsseticCollection();
+

Note that you can only use the debug bar assets and manage the dependencies by yourself +using $renderer->setIncludeVendors(false). + +

+

The javascript object

+

The renderer will generate all the needed code for your debug bar. This means +initializing the DebugBar js object, adding tabs and indicators, defining a data map, etc... + +

+

Data collectors can provide their own controls when implementing the +DebugBar\DataCollector\Renderable interface as explained in the Collecting Data chapter. + +

+

Thus in almost all cases, you should only have to use render() right away: + +

+
<html>
+    ...
+    <body>
+        <?php echo $renderer->render() ?>
+    </body>
+</html>
+

This will print the initilization code for the toolbar and the dataset for the request. +When you are performing AJAX requests, you do not want to initialize a new toolbar but +add the dataset to the existing one. You can disable initialization using ̀false as +the first argument of ̀render(). + +

+
<p>my ajax content</p>
+<?php echo $renderer->render(false) ?>
+

Controlling object initialization

+

You can further control the initialization of the javascript object using setInitialization(). +It takes a bitwise value made out of the constants ̀INITIALIZE_CONSTRUCTOR and INITIALIZE_CONTROLS. +The first one controls whether to initialize the variable (ie. var debugbar = new DebugBar()`). The +second one whether to initialize all the controls (ie. adding tab and indicators as well as data mapping). + +

+

You can also control the class name of the object using setJavascriptClass() and the name of +the instance variable using setVariableName(). + +

+

Let's say you have subclassed PhpDebugBar.DebugBar in javascript to do your own initilization. +Your new object is called MyDebugBar. + +

+
$renderer->setJavascriptClass("MyDebugBar");
+$renderer->setInitialization(JavascriptRenderer::INITIALIZE_CONSTRUCTOR);
+// ...
+echo $renderer->render();
+

This has the result of printing: + +

+
<script type="text/javascript">
+var phpdebugbar = new MyDebugBar();
+phpdebugbar.addDataSet({ ... });
+</script>
+

Using setInitialization(0) will only render the addDataSet part. + +

+

Defining controls

+

Controls can be manually added to the debug bar using addControl($name, $options). You should read +the Javascript bar chapter before this section. + +

+

$name will be the name of your control and $options is a key/value pair array with these +possible values: + +

+
    +
  • icon: icon name
  • +
  • tooltip: string
  • +
  • widget: widget class name
  • +
  • map: a property name from the data to map the control to
  • +
  • default: a js string, default value of the data map
  • +
+

At least icon or widget are needed. If widget is specified, a tab will be created, otherwise +an indicator. + +

+
$renderer->addControl('messages', array(
+    "widget" => "PhpDebugBar.Widgets.MessagesWidget",
+    "map" => "messages",
+    "default" => "[]"
+));
+ +

Javascript Bar

+

The default client side implementation of the debug bar is made +entirely in Javascript and is located in the debugbar.js file. + +

+

It adds a bottom-anchored bar which can have tabs and indicators. +The bar can be in an open or close state. When open, the tab panel is +visible. +An indicator is a piece of information displayed in the always-visible +part of the bar. + +

+

The bar handles multiple datasets by displaying a select box +which allows you to switch between them. + +

+

The state of the bar (height, visibilty, active panel) can be saved +between requests (enabled in the standard bar). + +

+

Each panel is composed of a widget which is used to display the +data from a data collector. Some common widgets are provided in +the widgets.js file. + +

+

The PhpDebugBar namespace is used for all objects and the only +dependencies are jQuery, jquery-drag and FontAwesome (css). + +

+

The main class is PhpDebugBar.DebugBar. It provides the infrastructure +to manage tabs, indicators and datasets. + +

+

When initialized, the DebugBar class adds itself to the <body> of the +page. It is empty by default. + +

+

Tabs and indicators

+

Controls (ie. tabs and indicators) are uniquely named. You can check if +a control exists using isControl(name). + +

+

Tabs can be added using the createTab(name, widget, title) function. +The third argument is optional and will be computed from the name if not +provided. + +

+
var debugbar = new PhpDebugBar.DebugBar();
+debugbar.createTab("messages", new PhpDebugBar.Widgets.MessagesWidget());
+

Indicators can be added using createIndicator(name, icon, tooltip, position). +Only name is required in this case. icon should be the name of a FontAwesome +icon. position can either by right (default) or left. + +

+
debugbar.createIndicator("time", "cogs", "Request duration");
+

You may have noticed that the data to use inside these controls is not +specified at the moment. Although it could be specified when initialized, it +is better to use data mapping to support dynamically changing the data set. + +

+

Data mapping

+

To enable dynamically changing the data sets, we need to specify which values +should be feed into which controls. This can be done using setDataMap(map) +which takes as argument an object where properties are control names. Values +should be arrays where the first item is the property from the data set and +the second a default value. + +

+
debugbar.setDataMap({
+    "messages": ["messages", []],
+    "time": ["time.duration_str", "0ms"]
+});
+

You can notice that nested properties can also be accessed using the dot +notation. + +

+

In this mapping, data["messages"] will be fed to the messages tab +and data["time"]["duration_str"] will be fed to the time indicator. + +

+

Note: you can append mapping info using addDataMap(map) + +

+

Datasets

+

Although you shouldn't have to do anything regarding managing datasets, +it is interesting to know a few functions related to them. + +

+

addDataSet(data, id) adds a dataset to the bar. The select box that +allows to swtich between sets is only displayed if more than one are added. +id is optional and will be auto-generated if not specified. + +

+

showDataSet(id) allows you to switch to a specific dataset. + +

+

Widgets

+

A widget is a javascript object which must contain at least an element +property. element's value will be appended to the tab panel. + +

+

Widgets should provide a setData() function so they can be used with +the data mapper. + +

+
var MyWidget = function() {
+    this.element = $('<div class="mywidget" />');
+};
+
+MyWidget.prototype.setData = function(text) {
+    this.element.text(text);
+};
+
+// ----
+
+debugbar.createTab("mytab", new MyWidget());
+debugbar.addDataMap({"mytab": ["mydata", ""]});
+

Widgets for bundled data collectors are included as well as more generic +widgets that you can build on top of. They are located in widgets.js in +the PhpDebugBar.Widgets namespace. + +

+

Generic widgets: + +

+
    +
  • ListWidget: renders an array as a UL list
  • +
  • KVListWidget: renders a hash as a DL list
  • +
  • VariablesListWidget: an extension of KVListWidget to display a list of variables
  • +
  • IFrameWidget: renders an iframe
  • +
+

Data collectors related widgets: + +

+
    +
  • MessagesWidget: for the MessagesCollector
  • +
  • TimelineWidget: for the TimeDataCollector
  • +
+ +
+ +
+ + diff --git a/css/docs.css b/css/docs.css new file mode 100644 index 0000000..ab432c4 --- /dev/null +++ b/css/docs.css @@ -0,0 +1,195 @@ +body { + font-family: Helvetica, Arial, sans-serif; + font-size: 14px; + line-height: 1.4em; + min-width: 1100px; +} +#header { + background: #f7f7f7; + background: -moz-linear-gradient(top, #f7f7f7 0%, #e0e0e0 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #f7f7f7), color-stop(100%, #e0e0e0)); + border-bottom: 3px solid #bbbbbb; + display: block; + position: relative; + padding: 20px; +} +#header h1 { + font-family: 'Droid Sans', arial, serif; + font-size: 45px; + line-height: 50px; + text-shadow: #444 1px 1px 2px; +} +#header h1 a { + color: #333333; + text-decoration: none; +} +#header #menu { + position: absolute; + top: 25px; + right: 20px; +} +#header #menu a { + background: #f78d1d; + background: -webkit-gradient(linear, left top, left bottom, from(#faa51a), to(#f47a20)); + background: -moz-linear-gradient(top, #faa51a, #f47a20); + border: 1px solid #da7c0c; + -moz-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2); + -moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2); + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2); + color: #444; + cursor: pointer; + display: inline-block; + font-size: 16px; + margin: 0; + padding: 5px 10px; + position: relative; + top: -1px; + text-shadow: 0 1px 1px rgba(0, 0, 0, 0.3); + text-decoration: none; +} +#sidebar { + border-right: 1px solid #cccccc; + float: left; + padding: 30px; + width: 230px; +} +#sidebar input#search { + border: 1px solid #ccc; + border-radius: 4px; + -moz-border-radius: 4px; + font-size: 16px; + margin-bottom: 20px; + padding: 4px 0; + width: 100%; +} +#sidebar #toc li { + font-size: 16px; + margin: 14px 0px; +} +#sidebar #toc li a { + color: #555; + text-decoration: none; +} +#sidebar #toc > ol > li { + font-weight: bold; + margin-bottom: 20px; +} +#sidebar #toc > ol > li li { + font-weight: normal; + margin-left: 15px; +} +#sidebar #toc > ol > li li a { + color: #777; +} +#content { + border-left: 1px solid #cccccc; + color: #444; + float: left; + margin-left: -1px; + padding: 10px 40px 80px 30px; + width: 700px; +} +#content h1 { + font-size: 32px; + line-height: 35px; + margin: 15px 0 25px 0; +} +#content h2 { + border-bottom: 2px solid #ccc; + font-size: 24px; + margin: 30px 0 15px 0; + padding-bottom: 7px; +} +#content p { + margin: 15px 0; +} +#content a { + color: #d08708; + text-decoration: none; +} +#content a:hover { + text-decoration: underline; +} +#content ul, +#content ol { + list-style: disc; + margin-left: 30px; +} +#content ul li, +#content ol li { + margin: 5px 0; +} +#content ol { + list-style: decimal; +} +#content pre { + margin: 15px 0; +} +#content code { + overflow: auto; +} +#content .note { + background: #f3f3f3; + border: 2px solid #ccc; + padding: 5px; + margin: 20px 0; +} +#content .warning { + background: #fdeeee; + border: 2px solid #d24d4d; + padding: 5px; + margin: 20px 0; +} +#content .tip { + background: #fffbe2; + border: 2px solid #e5cc24; + padding: 5px; + margin: 20px 0; +} +#content img { + max-width: 100%; +} +#content table { + width: 100%; + margin: 20px auto; +} +#content table th { + color: #555; + background: #efefef; + padding: 4px; + border-bottom: 1px solid #bbb; + border-left: 1px solid #bbb; +} +#content table th:first-child { + border-left: 0; +} +#content table td { + padding: 4px; + border-bottom: 1px solid #ccc; + border-left: 1px solid #ccc; +} +#content table td:first-child { + border-left: 0; +} +#footer { + border-top: 1px solid #cccccc; + clear: both; + color: #999; + display: block; + padding: 10px; +} +#footer a { + color: #999; +} +#fork-me-on-github { + display: block; + position: absolute; + top: 0; + right: 0; + width: 149px; + height: 149px; + text-indent: -9999px; + background: url(../img/github_forkme.png) no-repeat; +} diff --git a/css/print.css b/css/print.css new file mode 100644 index 0000000..ab1a660 --- /dev/null +++ b/css/print.css @@ -0,0 +1,16 @@ +#header { + background: none; + border: 0; +} +#switch { + display: none; +} +#sidebar { + display: none; +} +#content { + border: 0; +} +#footer { + display: none; +} diff --git a/css/reset.css b/css/reset.css new file mode 100644 index 0000000..28d76f8 --- /dev/null +++ b/css/reset.css @@ -0,0 +1,105 @@ +/* v1.0 | 20080212 */ +html, +body, +div, +span, +applet, +object, +iframe, +h1, +h2, +h3, +h4, +h5, +h6, +p, +blockquote, +pre, +a, +abbr, +acronym, +address, +big, +cite, +code, +del, +dfn, +em, +font, +img, +ins, +kbd, +q, +s, +samp, +small, +strike, +strong, +sub, +sup, +tt, +var, +b, +u, +i, +center, +dl, +dt, +dd, +ol, +ul, +li, +fieldset, +form, +label, +legend, +table, +caption, +tbody, +tfoot, +thead, +tr, +th, +td { + margin: 0; + padding: 0; + border: 0; + outline: 0; + font-size: 100%; + vertical-align: baseline; + background: transparent; +} +body { + line-height: 1; +} +ol, +ul { + list-style: none; +} +blockquote, +q { + quotes: none; +} +blockquote:before, +blockquote:after, +q:before, +q:after { + content: ''; + content: none; +} +/* remember to define focus styles! */ +:focus { + outline: 0; +} +/* remember to highlight inserts somehow! */ +ins { + text-decoration: none; +} +del { + text-decoration: line-through; +} +/* tables still need 'cellspacing="0"' in the markup */ +table { + border-collapse: collapse; + border-spacing: 0; +} diff --git a/data-collectors.html b/data-collectors.html new file mode 100644 index 0000000..d303624 --- /dev/null +++ b/data-collectors.html @@ -0,0 +1,230 @@ + + + + + PHP Debug Bar + + + + + + + + + + + + +
+ + + + + + + + + +
+

Collecting Data

+

Using collectors

+

Collectors can be added to your debug bar using addCollector(). + +

+
$debugbar = new DebugBar();
+$debugbar->addCollector(new DataCollector\RequestDataCollector());
+

Each collector as a unique name as defined by its getName() method. You can +access collectors using getCollector($name). + +

+
$debugbar->addCollector(new DataCollector\MessagesCollector());
+$debugbar->getCollector('messages')->addMessage("foobar");
+// or:
+$debugbar['messages']->addMessage("foobar");
+

Data will be collected from them when the debug bar is rendered. You can however +collect the data earlier using collect(). + +

+
$debugbar->collect();
+

Creating collectors

+

Collectors must implement the DebugBar\DataCollector\DataCollectorInterface. They +may subclass DebugBar\DataCollector\DataCollector which provides utility methods. + +

+

Collectors must provide a getName() function returning their unique name and a +collect() function returning some json-encodable data. The latter will be called at the +same time the DebugBar::collect() method is called. + +

+
class MyDataCollector extends DebugBar\DataCollector\DataCollector
+{
+    public function collect()
+    {
+        return array("uniqid" => uniqid());
+    }
+
+    public function getName()
+    {
+        return 'mycollector';
+    }
+}
+
+$debugbar->addCollector(new MyDataCollector());
+

This however won't show anything in the debug bar as no information are provided +on how to display these data. You could do that manually as you'll see in later chapter +or implement the DebugBar\DataSource\Renderable interface. + +

+

To implement it, you must define a getWidgets() function which returns an array +of key/value pairs where key are control names and values control options as defined +in JavascriptRenderer::addControl($name, $options) (see Rendering chapter). + +

+
class MyDataCollector extends DebugBar\DataCollector\DataCollector implements DebugBar\DataCollector\Renderable
+{
+    // ...
+
+    public function getWidgets()
+    {
+        return array(
+            "mycollector" => array(
+                "icon" => "cogs",
+                "tooltip" => "uniqid()",
+                "map" => "uniqid",
+                "default" => "''"
+            )
+        );
+    }
+}
+

This will have the result of adding a new indicator to the debug bar. + +

+

Included collectors

+
    +
  • MemoryCollector (memory)
  • +
  • MessagesCollector (messages)
  • +
  • PhpInfoCollector (php)
  • +
  • RequestDataCollector (request)
  • +
  • TimeDataCollector (time)
  • +
+ +
+ + +
+ + diff --git a/docs/screenshot.png b/docs/screenshot.png new file mode 100644 index 0000000..adddef1 Binary files /dev/null and b/docs/screenshot.png differ diff --git a/img/github_forkme.png b/img/github_forkme.png new file mode 100644 index 0000000..146ef8a Binary files /dev/null and b/img/github_forkme.png differ diff --git a/index.html b/index.html new file mode 100644 index 0000000..3d6d539 --- /dev/null +++ b/index.html @@ -0,0 +1,234 @@ + + + + + PHP Debug Bar + + + + + + + + + + + + +
+ + + + + + + + + +
+

PHP Debug Bar

+

Displays a debug bar in the browser with information from php. +No more var_dump() in your code! + +

+

Screenshot + +

+

Features: + +

+
    +
  • Generic debug bar with no other dependencies
  • +
  • Easy to integrate with any project
  • +
  • Clean, fast and easy to use interface
  • +
  • Handles AJAX request
  • +
  • Includes generic data collectors and collectors for well known libraries
  • +
  • The client side bar is 100% coded in javascript
  • +
  • Easily create your own collectors and their associated view in the bar
  • +
+

Installation

+

The easiest way to install DebugBar is using Composer +with the following requirement: + +

+
{
+    "require": {
+        "maximebf/debugbar": ">=1.0.0"
+    }
+}
+

Alternatively, you can download the archive +and add the src/ folder to PHP's include path: + +

+
set_include_path('/path/to/src' . PATH_SEPARATOR . get_include_path());
+

DebugBar does not provide an autoloader but follows the PSR-0 convention.
You can use the following snippet to autoload ConsoleKit classes: + +

+
spl_autoload_register(function($className) {
+    if (substr($className, 0, 8) === 'DebugBar') {
+        $filename = str_replace('\\', DIRECTORY_SEPARATOR, trim($className, '\\')) . '.php';
+        require_once $filename;
+    }
+});
+

Quick start

+

DebugBar is very easy to use and you can add it to any of your projets in no time. +The easiest way is using the render() functions + +

+
<?php
+use DebugBar\StandardDebugBar;
+use DebugBar\Renderer\JavascriptRenderer;
+
+$debugbar = new StandardDebugBar();
+$debugbarRenderer = $debugbar->getJavascriptRenderer();
+
+$debugbar["messages"]->addMessage("hello world!");
+?>
+<html>
+    <head>
+        <?php echo $debugbarRenderer->renderHead() ?>
+    </head>
+    <body>
+        ...
+        <?php echo $debugbarRenderer->render() ?>
+    </body>
+</html>
+

The DebugBar uses DataCollectors to collect data from your PHP code. Some of them are +automated but others are manual. Use the DebugBar like an array where keys are the +collector names. In our previous example, we add a message to the MessagesCollector: + +

+
$debugbar["messages"]->addMessage("hello world!");
+

StandardDebugBar activates all bundled collectors: + +

+
    +
  • MemoryCollector (memory)
  • +
  • MessagesCollector (messages)
  • +
  • PhpInfoCollector (php)
  • +
  • RequestDataCollector (request)
  • +
  • TimeDataCollector (time)
  • +
+

Learn more about DebugBar in the docs. +

+ +
+ + +
+ + diff --git a/javascript-bar.html b/javascript-bar.html new file mode 100644 index 0000000..6a90464 --- /dev/null +++ b/javascript-bar.html @@ -0,0 +1,287 @@ + + + + + PHP Debug Bar + + + + + + + + + + + + +
+ + + + + + + + + +
+

Javascript Bar

+

The default client side implementation of the debug bar is made +entirely in Javascript and is located in the debugbar.js file. + +

+

It adds a bottom-anchored bar which can have tabs and indicators. +The bar can be in an open or close state. When open, the tab panel is +visible. +An indicator is a piece of information displayed in the always-visible +part of the bar. + +

+

The bar handles multiple datasets by displaying a select box +which allows you to switch between them. + +

+

The state of the bar (height, visibilty, active panel) can be saved +between requests (enabled in the standard bar). + +

+

Each panel is composed of a widget which is used to display the +data from a data collector. Some common widgets are provided in +the widgets.js file. + +

+

The PhpDebugBar namespace is used for all objects and the only +dependencies are jQuery, jquery-drag and FontAwesome (css). + +

+

The main class is PhpDebugBar.DebugBar. It provides the infrastructure +to manage tabs, indicators and datasets. + +

+

When initialized, the DebugBar class adds itself to the <body> of the +page. It is empty by default. + +

+

Tabs and indicators

+

Controls (ie. tabs and indicators) are uniquely named. You can check if +a control exists using isControl(name). + +

+

Tabs can be added using the createTab(name, widget, title) function. +The third argument is optional and will be computed from the name if not +provided. + +

+
var debugbar = new PhpDebugBar.DebugBar();
+debugbar.createTab("messages", new PhpDebugBar.Widgets.MessagesWidget());
+

Indicators can be added using createIndicator(name, icon, tooltip, position). +Only name is required in this case. icon should be the name of a FontAwesome +icon. position can either by right (default) or left. + +

+
debugbar.createIndicator("time", "cogs", "Request duration");
+

You may have noticed that the data to use inside these controls is not +specified at the moment. Although it could be specified when initialized, it +is better to use data mapping to support dynamically changing the data set. + +

+

Data mapping

+

To enable dynamically changing the data sets, we need to specify which values +should be feed into which controls. This can be done using setDataMap(map) +which takes as argument an object where properties are control names. Values +should be arrays where the first item is the property from the data set and +the second a default value. + +

+
debugbar.setDataMap({
+    "messages": ["messages", []],
+    "time": ["time.duration_str", "0ms"]
+});
+

You can notice that nested properties can also be accessed using the dot +notation. + +

+

In this mapping, data["messages"] will be fed to the messages tab +and data["time"]["duration_str"] will be fed to the time indicator. + +

+

Note: you can append mapping info using addDataMap(map) + +

+

Datasets

+

Although you shouldn't have to do anything regarding managing datasets, +it is interesting to know a few functions related to them. + +

+

addDataSet(data, id) adds a dataset to the bar. The select box that +allows to swtich between sets is only displayed if more than one are added. +id is optional and will be auto-generated if not specified. + +

+

showDataSet(id) allows you to switch to a specific dataset. + +

+

Widgets

+

A widget is a javascript object which must contain at least an element +property. element's value will be appended to the tab panel. + +

+

Widgets should provide a setData() function so they can be used with +the data mapper. + +

+
var MyWidget = function() {
+    this.element = $('<div class="mywidget" />');
+};
+
+MyWidget.prototype.setData = function(text) {
+    this.element.text(text);
+};
+
+// ----
+
+debugbar.createTab("mytab", new MyWidget());
+debugbar.addDataMap({"mytab": ["mydata", ""]});
+

Widgets for bundled data collectors are included as well as more generic +widgets that you can build on top of. They are located in widgets.js in +the PhpDebugBar.Widgets namespace. + +

+

Generic widgets: + +

+
    +
  • ListWidget: renders an array as a UL list
  • +
  • KVListWidget: renders a hash as a DL list
  • +
  • VariablesListWidget: an extension of KVListWidget to display a list of variables
  • +
  • IFrameWidget: renders an iframe
  • +
+

Data collectors related widgets: + +

+
    +
  • MessagesWidget: for the MessagesCollector
  • +
  • TimelineWidget: for the TimeDataCollector
  • +
+ +
+ + +
+ + diff --git a/js/viewer.js b/js/viewer.js new file mode 100644 index 0000000..6cea9b8 --- /dev/null +++ b/js/viewer.js @@ -0,0 +1,13 @@ +// Generated by CoffeeScript 1.4.0 +(function() { + + $(function() { + $('#content pre code').each(function(i, el) { + return hljs.highlightBlock(el); + }); + if (window.location.search.indexOf('print') !== -1) { + return window.print(); + } + }); + +}).call(this); diff --git a/readme.html b/readme.html new file mode 100644 index 0000000..3d6d539 --- /dev/null +++ b/readme.html @@ -0,0 +1,234 @@ + + + + + PHP Debug Bar + + + + + + + + + + + + +
+ + + + + + + + + +
+

PHP Debug Bar

+

Displays a debug bar in the browser with information from php. +No more var_dump() in your code! + +

+

Screenshot + +

+

Features: + +

+
    +
  • Generic debug bar with no other dependencies
  • +
  • Easy to integrate with any project
  • +
  • Clean, fast and easy to use interface
  • +
  • Handles AJAX request
  • +
  • Includes generic data collectors and collectors for well known libraries
  • +
  • The client side bar is 100% coded in javascript
  • +
  • Easily create your own collectors and their associated view in the bar
  • +
+

Installation

+

The easiest way to install DebugBar is using Composer +with the following requirement: + +

+
{
+    "require": {
+        "maximebf/debugbar": ">=1.0.0"
+    }
+}
+

Alternatively, you can download the archive +and add the src/ folder to PHP's include path: + +

+
set_include_path('/path/to/src' . PATH_SEPARATOR . get_include_path());
+

DebugBar does not provide an autoloader but follows the PSR-0 convention.
You can use the following snippet to autoload ConsoleKit classes: + +

+
spl_autoload_register(function($className) {
+    if (substr($className, 0, 8) === 'DebugBar') {
+        $filename = str_replace('\\', DIRECTORY_SEPARATOR, trim($className, '\\')) . '.php';
+        require_once $filename;
+    }
+});
+

Quick start

+

DebugBar is very easy to use and you can add it to any of your projets in no time. +The easiest way is using the render() functions + +

+
<?php
+use DebugBar\StandardDebugBar;
+use DebugBar\Renderer\JavascriptRenderer;
+
+$debugbar = new StandardDebugBar();
+$debugbarRenderer = $debugbar->getJavascriptRenderer();
+
+$debugbar["messages"]->addMessage("hello world!");
+?>
+<html>
+    <head>
+        <?php echo $debugbarRenderer->renderHead() ?>
+    </head>
+    <body>
+        ...
+        <?php echo $debugbarRenderer->render() ?>
+    </body>
+</html>
+

The DebugBar uses DataCollectors to collect data from your PHP code. Some of them are +automated but others are manual. Use the DebugBar like an array where keys are the +collector names. In our previous example, we add a message to the MessagesCollector: + +

+
$debugbar["messages"]->addMessage("hello world!");
+

StandardDebugBar activates all bundled collectors: + +

+
    +
  • MemoryCollector (memory)
  • +
  • MessagesCollector (messages)
  • +
  • PhpInfoCollector (php)
  • +
  • RequestDataCollector (request)
  • +
  • TimeDataCollector (time)
  • +
+

Learn more about DebugBar in the docs. +

+ +
+ + +
+ + diff --git a/rendering.html b/rendering.html new file mode 100644 index 0000000..e110ac7 --- /dev/null +++ b/rendering.html @@ -0,0 +1,275 @@ + + + + + PHP Debug Bar + + + + + + + + + + + + +
+ + + + + + + + + +
+

Rendering

+

Rendering is performed using the `DebugBar\JavascriptRenderer̀ class. It contains +all the useful functions to included the needed assets and generate a debug bar. + +

+
$renderer = $debugbar->getJavascriptRenderer();
+

Assets

+

The debug bar relies on some css and javascript files which needs to be included +into your webpage. This can be done in two ways: + +

+
    +
  • Using JavascriptRenderer::renderHead() which will returns a string with +the needed script and link tags
  • +
  • Using Assetic and +JavascriptRenderer::getAsseticCollection()
  • +
+

I would recommend using the second method as Assetic is a very powerful asset +manager but the first method is provided to quickly integrate the debug bar +into any projets. + +

+

You can define the base url of your assets using setBaseUrl(). This is needed +in 99% of cases. If you are using Assetic, you may have to change the base path +of the assets if you moved the folder. This can be done using setBasePath(). + +

+

Using renderHead(): + +

+
<html>
+    <head>
+        ...
+        <?php echo $renderer->renderHead() ?>
+        ...
+    </head>
+    ...
+</html>
+

Using Assetic: + +

+
list($cssCollection, $jsCollection) = $renderer->getAsseticCollection();
+

Note that you can only use the debug bar assets and manage the dependencies by yourself +using $renderer->setIncludeVendors(false). + +

+

The javascript object

+

The renderer will generate all the needed code for your debug bar. This means +initializing the DebugBar js object, adding tabs and indicators, defining a data map, etc... + +

+

Data collectors can provide their own controls when implementing the +DebugBar\DataCollector\Renderable interface as explained in the Collecting Data chapter. + +

+

Thus in almost all cases, you should only have to use render() right away: + +

+
<html>
+    ...
+    <body>
+        <?php echo $renderer->render() ?>
+    </body>
+</html>
+

This will print the initilization code for the toolbar and the dataset for the request. +When you are performing AJAX requests, you do not want to initialize a new toolbar but +add the dataset to the existing one. You can disable initialization using ̀false as +the first argument of ̀render(). + +

+
<p>my ajax content</p>
+<?php echo $renderer->render(false) ?>
+

Controlling object initialization

+

You can further control the initialization of the javascript object using setInitialization(). +It takes a bitwise value made out of the constants ̀INITIALIZE_CONSTRUCTOR and INITIALIZE_CONTROLS. +The first one controls whether to initialize the variable (ie. var debugbar = new DebugBar()`). The +second one whether to initialize all the controls (ie. adding tab and indicators as well as data mapping). + +

+

You can also control the class name of the object using setJavascriptClass() and the name of +the instance variable using setVariableName(). + +

+

Let's say you have subclassed PhpDebugBar.DebugBar in javascript to do your own initilization. +Your new object is called MyDebugBar. + +

+
$renderer->setJavascriptClass("MyDebugBar");
+$renderer->setInitialization(JavascriptRenderer::INITIALIZE_CONSTRUCTOR);
+// ...
+echo $renderer->render();
+

This has the result of printing: + +

+
<script type="text/javascript">
+var phpdebugbar = new MyDebugBar();
+phpdebugbar.addDataSet({ ... });
+</script>
+

Using setInitialization(0) will only render the addDataSet part. + +

+

Defining controls

+

Controls can be manually added to the debug bar using addControl($name, $options). You should read +the Javascript bar chapter before this section. + +

+

$name will be the name of your control and $options is a key/value pair array with these +possible values: + +

+
    +
  • icon: icon name
  • +
  • tooltip: string
  • +
  • widget: widget class name
  • +
  • map: a property name from the data to map the control to
  • +
  • default: a js string, default value of the data map
  • +
+

At least icon or widget are needed. If widget is specified, a tab will be created, otherwise +an indicator. + +

+
$renderer->addControl('messages', array(
+    "widget" => "PhpDebugBar.Widgets.MessagesWidget",
+    "map" => "messages",
+    "default" => "[]"
+));
+ +
+ + +
+ +