Pull to refresh

Альтернатива firePHP

Reading time 6 min
Views 4.7K
Пару недель решил взяться за изучение PHP и спустя какое-то количество времени отлаживать скрипты через echo стало неудобно. Вспомнил о существовании такой вещи как firePHP, почитал документацию, скачал, поставил, обрадовался. Ведь так классно отлаживать скрипты через консоль!
Но увы, по непонятным мне причинам («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}})();


А в консоли фаербаг мы увидим
image

ЗЫ
Замечания, предложения по скрипту — в комментарии

ЗЗЫ
Чтобы все это работало нужен firefox и firebug
Tags:
Hubs:
+35
Comments 132
Comments Comments 132

Articles