Пару недель решил взяться за изучение PHP и спустя какое-то количество времени отлаживать скрипты через echo стало неудобно. Вспомнил о существовании такой вещи как firePHP, почитал документацию, скачал, поставил, обрадовался. Ведь так классно отлаживать скрипты через консоль!
Но увы, по непонятным мне причинам («X-Wf-» заголовки доходят, а все равно «no messages in Firebug Console»*), не заработал. Посмотрел в интернете — безуспешно, пришлось самому решать проблему.
Решение представляет собой PHP интерфейс к консоли фаербаг, посредством генерации javascript кода.
Собственно исходник:
После вызова метода end(), в html документ добавиться следующий javascript код:
А в консоли фаербаг мы увидим
ЗЫ
Замечания, предложения по скрипту — в комментарии
ЗЗЫ
Чтобы все это работало нужен firefox и firebug
Но увы, по непонятным мне причинам («X-Wf-» заголовки доходят, а все равно «no messages in Firebug Console»*), не заработал. Посмотрел в интернете — безуспешно, пришлось самому решать проблему.
Решение представляет собой PHP интерфейс к консоли фаербаг, посредством генерации javascript кода.
Собственно исходник:
class debug {
private $code = "<script type="text/javascript" id="debug">(function(){",
$timers = array (),
$counter = 0,
$vars = array();
function debug() {
$this->allow = true;
}
/* Вывести все в консоли */
public function end() {
if ($this->allow){
if(sizeof($this->vars) > 0){
$dump = 'function dump(a,b){var c="";if(!b)b=0;var d="";for(var j=0;j++<=b;)d+=" ";if(typeof(a)==\'object\'){for(var e in a){var f=a[e];if(typeof(f)==\'object\'){c+=d+"\'"+e+"\' ...\n";c+=dump(f,b+1)}else{c+=d+"\'"+e+"\' => \""+f+"\"\n"}}}return c}';
$this->code .= $dump;
}
echo $this->code."})();</script>";
} else return null;
}
/*
* Группировка
*/
public function group($name) {
$this->code .= "console.group('".$name."');";
return $this;
}
public function groupEnd() {
$this->code .= "console.groupEnd();";
return $this;
}
/*
* Начало запуска таймера
*/
public function time($name) {
$mtime = microtime();
$mtime = explode(' ', $mtime);
$mtime = $mtime[1]+$mtime[0];
$this->timers[$name] = $mtime;
return $this;
}
/*
* Остановка таймера
*/
public function timeEnd($name) {
$timeStart = $this->timers[$name];
if ($timeStart) {
$mtime = microtime();
$mtime = explode(" ", $mtime);
$mtime = $mtime[1]+$mtime[0];
$endtime = $mtime;
$totaltime = $endtime-$timeStart;
$this->info("$name: $totaltime seconds");
$this->timers[$name] = null;
}
return $this;
}
/*
* Сообщения в консоль
*/
private function consoleType($msg, $mode) {
if (is_string($msg))
$msg = "'$msg'";
if(is_array($msg)){
$name = "o".($this->counter++);
$this->code .= $this->js_hash($msg,$name);
$this->code .= "console.".$mode."(dump(".$name."));";
}
if(!$name)
$this->code .= "console.".$mode."(".$msg.");";
}
// Стандартное сообщение в консоль
public function log($msg) {
$this->consoleType($msg, "log");
return $this;
}
// Сообщение об ошибке
public function error($msg) {
$this->consoleType($msg, "error");
return $this;
}
// Сообщение предупреждения
public function warn($msg) {
$this->consoleType($msg, "warn");
return $this;
}
// Сообщение со значком инфо
public function info($msg) {
$this->consoleType($msg, "info");
return $this;
}
/*
* Посмтроение объекта JS из PHP массива
*/
private function js_hash($arr, $name, & $code = '') {
if (!$this->vars[$this->counter]) {
$code .= "var ";
$this->vars[$this->counter] = true;
}
$code .= $name."={};";
foreach ($arr as $key=>$value) {
$outKey = (is_int($key))?'['.$key.']':".$key";
if (is_array($value)) {
$this->js_hash($value, $name.$outKey, $code);
continue ;
}
$code .= $name.$outKey."=";
if (is_string($value)) {
$code .= "'".$value."';";
} else if ($value === false) {
$code .= "false;";
} else if ($value === NULL) {
$code .= "null;";
} else if ($value === true) {
$code .= "true;";
} else {
$code .= $value.";";
}
}
return $code;
}
}
Примеры использования:
$d = new debug();
// Создаем новый таймер
$d->time('Timer');
// Пишем в консоль приветсвенное сообщение :)
$d->log("WELCOME!");
// Создаем массив
$arr = array();
for($i = 0; $i < 6; $i++){
$arr[] = "line #". $i;
}
// Выводим его в консоль
$d->log($arr);
$name = "Evgeny";
$age = 18;
// Массив посложнее
$myHobbies = array (
"films",
"music" => array("full on", "psy", "dark"),
"sports" => array(
"extreme" => array("climbing","snowboard"),
"diving",
"karting"
),
array(1,2,3,5,"sometxt")
);
// Делаем группу About
$d->group("About");
// В нее пишем имя и возраст
$d->log("Hello, my name is $name");
$d->log("and i am $age");
$d->groupEnd();
/* Или так:
* $d->group("About")
* ->log("Hello, my name is $name")
* ->log("and i am $age")
* ->groupEnd();
*/
// Делаем группу с увлечениями
$d->group("My hobbies");
// Пишем заголовок
$d->info("list of my hobbies");
// выводим массив
$d->log($myHobbies);
// закрываем группу
$d->groupEnd();
// Вывовод в консоль со знаком info времени выполнение РНР скрипта
$d->timeEnd('Timer');
// Обязательно при завершении работы с классом
$d->end();
// или $d->timeEnd('Timer')->end();
/* Примечание
* После использования метода end(), для последущего
* логирования нужно будет создавать новый объект класса,
* поэтому лучше использовать этот метод в конце скрипта.
*/
После вызова метода end(), в html документ добавиться следующий javascript код:
(function(){console.log('WELCOME!');var o0={};o0[0]='line #0';o0[1]='line #1';o0[2]='line #2';o0[3]='line #3';o0[4]='line #4';o0[5]='line #5';console.log(dump(o0));console.group('About');console.log('Hello, my name is Evgeny');console.log('and i am 18');console.groupEnd();console.group('My hobbies');console.info('list of my hobbies');var o1={};o1[0]='films';o1.music={};o1.music[0]='full on';o1.music[1]='psy';o1.music[2]='dark';o1.sports={};o1.sports.extreme={};o1.sports.extreme[0]='climbing';o1.sports.extreme[1]='snowboard';o1.sports[0]='diving';o1.sports[1]='karting';o1[1]={};o1[1][0]=1;o1[1][1]=2;o1[1][2]=3;o1[1][3]=5;o1[1][4]='sometxt';console.log(dump(o1));console.groupEnd();console.info('Timer: 0.000530004501343 seconds');function dump(a,b){var c="";if(!b)b=0;var d="";for(var j=0;j++<=b;)d+=" ";if(typeof(a)=='object'){for(var e in a){var f=a[e];if(typeof(f)=='object'){c+=d+"'"+e+"' ...\n";c+=dump(f,b+1)}else{c+=d+"'"+e+"' => \""+f+"\"\n"}}}return c}})();
А в консоли фаербаг мы увидим
ЗЫ
Замечания, предложения по скрипту — в комментарии
ЗЗЫ
Чтобы все это работало нужен firefox и firebug