Symfony 的分析器將數(shù)據(jù)采集功能委托給數(shù)據(jù)收集器。Symfony 在默認上捆綁了一些數(shù)據(jù)收集器,但是你可以很容易地按照自己的需求創(chuàng)建自定義的收集器。
創(chuàng)建一個自定義的數(shù)據(jù)收集器,所需要做的實質(zhì)工作就是實現(xiàn)數(shù)據(jù)收集器接口類 DataCollectorInterface:
interface DataCollectorInterface
{
/**
* Collects data for the given Request and Response.
*
* @param Request $request A Request instance
* @param Response $response A Response instance
* @param \Exception $exception An Exception instance
*/
function collect(Request $request, Response $response, \Exception $exception = null);
/**
* Returns the name of the collector.
*
* @return string The collector name
*/
function getName();
}
上述的 getName() 方法返回值必須是一個獨一無二的名字。這是被用來之后進行信息訪問的依據(jù)(可以在功能測試章節(jié)查看如何使用分析器文檔來獲得使用實例)。
而 collect() 方法負責(zé)存儲想要被提供給局部屬性的數(shù)據(jù)。
未探查序列化數(shù)據(jù)采集器的情況下,你不應(yīng)該存儲不可序列化的對象(如 PDO 對象),或者你需要提供自己的 serialize() 方法。
大部分的時間,擴展數(shù)據(jù)采集器和填充 $this->數(shù)據(jù)屬性(它需要序列化 $this->數(shù)據(jù)屬性)是非常方便的:
class MemoryDataCollector extends DataCollector
{
public function collect(Request $request, Response $response, \Exception $exception = null)
{
$this->data = array(
'memory' => memory_get_peak_usage(true),
);
}
public function getMemory()
{
return $this->data['memory'];
}
public function getName()
{
return 'memory';
}
}
為使一個數(shù)據(jù)收集器生效,將它添加進你的一個配置表中的常規(guī)服務(wù),并把它附屬在 data_collector 之后:
YAML:
services:
data_collector.your_collector_name:
class: Fully\Qualified\Collector\Class\Name
tags:
- { name: data_collector }
XML:
<service id="data_collector.your_collector_name" class="Fully\Qualified\Collector\Class\Name">
<tag name="data_collector" />
</service>
PHP:
$container
->register('data_collector.your_collector_name', 'Fully\Qualified\Collector\Class\Name')
->addTag('data_collector')
;
當(dāng)你想在網(wǎng)絡(luò)調(diào)試工具條或網(wǎng)絡(luò)分析器上顯示你的數(shù)據(jù)收集器收集的數(shù)據(jù),您將需要創(chuàng)建一個 Twig 模板。下面的例子可以幫助你開始:
{% extends 'WebProfilerBundle:Profiler:layout.html.twig' %}
{% block toolbar %}
{# This toolbar item may appear along the top or bottom of the screen.#}
{% set icon %}
<span class="icon"><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAcCAQAAADVGmdYAAAAAmJLR0QA/4ePzL8AAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQffAxkBCDStonIVAAAAGXRFWHRDb21tZW50AENyZWF0ZWQgd2l0aCBHSU1QV4EOFwAAAHpJREFUOMtj3PWfgXRAuqZd/5nIsIdhVBPFmgqIjCuYOrJsYtz1fxuUOYER2TQID8afwIiQ8YIkI4TzCv5D2AgaWSuExJKMIDbA7EEVhQEWXJ6FKUY4D48m7HYU/EcWZ8JlE6qfMELPDcUJuEMPxvYazYTDWRMjOcUyAEswO+VjeQQaAAAAAElFTkSuQmCC" alt=""/></span>
<span class="sf-toolbar-status">Example</span>
{% endset %}
{% set text %}
<div class="sf-toolbar-info-piece">
<b>Quick piece of data</b>
<span>100 units</span>
</div>
<div class="sf-toolbar-info-piece">
<b>Another quick thing</b>
<span>300 units</span>
</div>
{% endset %}
{# Set the "link" value to false if you do not have a big "panel"
section that you want to direct the user to. #}
{% include '@WebProfiler/Profiler/toolbar_item.html.twig' with { 'link': true } %}
{% endblock %}
{% block head %}
{# Optional, if you need your own JS or CSS files. #}
{{ parent() }} {# Use parent() to keep the default styles #}
{% endblock %}
{% block menu %}
{# This left-hand menu appears when using the full-screen profiler. #}
<span class="label">
<span class="icon"><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAcCAQAAADVGmdYAAAAAmJLR0QA/4ePzL8AAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQffAxkBCDStonIVAAAAGXRFWHRDb21tZW50AENyZWF0ZWQgd2l0aCBHSU1QV4EOFwAAAHpJREFUOMtj3PWfgXRAuqZd/5nIsIdhVBPFmgqIjCuYOrJsYtz1fxuUOYER2TQID8afwIiQ8YIkI4TzCv5D2AgaWSuExJKMIDbA7EEVhQEWXJ6FKUY4D48m7HYU/EcWZ8JlE6qfMELPDcUJuEMPxvYazYTDWRMjOcUyAEswO+VjeQQaAAAAAElFTkSuQmCC" alt=""/></span>
<strong>Example Collector</strong>
</span>
{% endblock %}
{% block panel %}
{# Optional, for showing the most details. #}
<h2>Example</h2>
<p>
<em>Major information goes here</em>
</p>
{% endblock %}
每個塊都是可選的。工具欄塊用于網(wǎng)頁調(diào)試工具,菜單和面板用于將一個面板添加到網(wǎng)絡(luò)分析器中。
所有塊都有訪問收集器對象的權(quán)限。
內(nèi)置的模板使用 Base64 編碼的圖像工具欄:
<img src="data:image/png;base64,..." />
你可以很容易利用這個小腳本計算出圖像的 base64 值:
#!/usr/bin/env php <?php echo base64_encode(file_get_contents($_SERVER['argv'][1]));
為了使模板生效,在您配置的 data_collector 標(biāo)簽中添加模板屬性。例如,假設(shè)你的模板是在一些 AcmeDebugBundle 中,那么:
YAML:
services:
data_collector.your_collector_name:
class: Acme\DebugBundle\Collector\Class\Name
tags:
- { name: data_collector, template: "AcmeDebugBundle:Collector:templatename",
XML:
<service id="data_collector.your_collector_name" class="Acme\DebugBundle\Collector\Class\Name">
<tag name="data_collector" template="AcmeDebugBundle:Collector:templatename" id="your_collector_name" />
</service>
PHP:
$container
->register('data_collector.your_collector_name', 'Acme\DebugBundle\Collector\Class\Name')
->addTag('data_collector', array(
'template' => 'AcmeDebugBundle:Collector:templatename',
'id' => 'your_collector_name',
))
;
記得確保你的 ID 屬性與用于 getname() 方法的字符串相同。