이 기능은 누리고에서 사내에 사용되는 XE에 적용된 코드입니다.

제가 열심히 검토하면서 만들어봤고, 사내 직원들도 좋아하네요. 직관성이 좋아졌다고.

 

그래서 공개합니다!!! 

 

라이믹스를 기반으로 공부하면서 제작된 기능이기 때문에 GPL v2 라이선스가 따를수 있습니다..? (라고 해놓고 뭐라는지 모른다..ㅠㅠ)

 

현재 XE의 디버그 기능은 뭔가 반쪽 짜리에 가독성이 떨어진다는 아주아주 큰 단점을 가지고 있습니다.

이 디버그 기능을 가독성은 높이고, 편의 기능을 넣어볼려고 합니다.

 

이 코드는 https://github.com/xpressengine/xe-core/pull/1872 를 기반으로 제작됩니다. 이 PR도 제가 작성한거긴 하지만..

 

여러분들은 이 글을 따라함으로써 다음부터는 아래사진과 동일한 디버그 화면을 볼 수 있습니다.

 

참고로 일부 웹호스팅에 따라 작동이 안될 수 있으며, 최소 php5.3.6이상에서만 사용가능합니다. 해놓고 안된다고 징징대면 때려줄(쿨럭)..

 

스크린샷_061816_112944_AM.jpg

 

스크린샷_061816_113043_AM.jpg

 

이렇게 가독성은 높이고 파일의 실행순서까지 나오게 할 수 있습니다!!

 

그럼 잘 따라오세요. 그냥 소스 코드 공개입니다. 소스코드를 붙여넣으세요.

 

우선 워닝에러 부터 잡아봅시다.

워닝에러는 위에 언급한 제 PR에서도 적용되어있지만, 정리가 되지 않은 채로 보여지기 때문에 문제가 있습니다.

그래서 이 항목을 잡아줘야죠.

 

classes/module/ModuleHandler.class.php 파일입니다. 104번째줄 언저리 보면..

 

ModuleHandler::triggerCall('moduleHandler.init', 'before', $this);

이렇게 트리거를 호출하고 있을 겁니다. 그럼 그 아래 이렇게 만들어주면 됩니다.

// call a trigger before moduleHandler init
ModuleHandler::triggerCall('moduleHandler.init', 'before', $this);
if(__DEBUG__ == 1 && __DEBUG_OUTPUT__ == 0)
{
   if(__DEBUG_PROTECT__ === 1 && __DEBUG_PROTECT_IP__ == $_SERVER['REMOTE_ADDR'])
   {
      set_error_handler(array($this, 'xeErrorLog'), E_WARNING);
   }
   else if(__DEBUG_PROTECT__ === 0)
   {
      set_error_handler(array($this, 'xeErrorLog'), E_WARNING);
   }
}

그리고 그 아래 메소드를 하나 추가해줍시다.

function xeErrorLog($errnumber, $errormassage, $errorfile, $errorline, $errorcontext)
{
   if($errnumber != E_WARNING)
   {
      return false;
   }
   else
   {
      $errorname = 'Warrning';
   }
   $debug_file = _XE_PATH_ . 'files/_debug_message.php';
   $debug_file_exist = file_exists($debug_file);
   if(!$debug_file_exist)
   {
      $print[] = '<?php exit() ?>';
   }
   $buff =  $errorname . " : ";
   $buff .= $errormassage . "\n";
   $buff .= "- line : " . $errorline . "\n";
   $buff .= "- file : " . $errorfile;
   $backtrace_args = defined('\DEBUG_BACKTRACE_IGNORE_ARGS') ? \DEBUG_BACKTRACE_IGNORE_ARGS : 0;

   $backtrace = debug_backtrace($backtrace_args);

   if(count($backtrace) > 1 && $backtrace[1]['function'] === 'xeErrorLog' && !$backtrace[1]['class'])
   {
      array_shift($backtrace);
   }
   foreach($backtrace as $val)
   {
      $buff .= "\n" . '- ' . $val['file'] . ' line ' . $val['line'];
   }
   $buff = sprintf("\n[%s]\n\n%s\n\n", date('Y-m-d H:i:s'), print_r($buff, true));

   if(!@file_put_contents($debug_file, $buff, FILE_APPEND | LOCK_EX))
   {
      return;
   }

   return true;
}

이러면 워닝에러는 끝납니다.

그리고 debugPrint를 잡아봅시다!

 

config/func.inc.php 파일이 있습니다.

해당 파일안에 보시면 대놓고 debugPrint 메소드가 있습니다.

이 메소드를 고쳐주기만 하면됩니다. 통째로 고치세요. 설명이 너무 복잡합니다..ㅠㅠ

function debugPrint($debug_output = NULL, $display_option = TRUE, $file = '_debug_message.php')
{
   static $debug_file;
   static $debug_file_exist;

   if(!(__DEBUG__ & 1))
   {
      return;
   }

   static $firephp;
   $bt = debug_backtrace();
   if(is_array($bt))
   {
      $bt_debug_print = array_shift($bt);
      $bt_called_function = array_shift($bt);
   }
   $file_name = str_replace(_XE_PATH_, '', $bt_debug_print['file']);
   $line_num = $bt_debug_print['line'];
   $function = $bt_called_function['class'] . $bt_called_function['type'] . $bt_called_function['function'];

   if(__DEBUG_OUTPUT__ == 2 && version_compare(PHP_VERSION, '6.0.0') === -1)
   {
      if(!isset($firephp))
      {
         $firephp = FirePHP::getInstance(TRUE);
      }
      $type = FirePHP::INFO;

      $label = sprintf('[%s:%d] %s() (Memory usage: current=%s, peak=%s)', $file_name, $line_num, $function, FileHandler::filesize(memory_get_usage()), FileHandler::filesize(memory_get_peak_usage()));

      // Check a FirePHP option
      if($display_option === 'TABLE')
      {
         $label = $display_option;
      }
      if($display_option === 'ERROR')
      {
         $type = $display_option;
      }
      // Check if the IP specified by __DEBUG_PROTECT__ option is same as the access IP.
      if(__DEBUG_PROTECT__ === 1 && __DEBUG_PROTECT_IP__ != $_SERVER['REMOTE_ADDR'])
      {
         $debug_output = 'The IP address is not allowed. Change the value of __DEBUG_PROTECT_IP__ into your IP address in config/config.user.inc.php or config/config.inc.php';
         $label = NULL;
      }

      $firephp->fb($debug_output, $label, $type);
   }
   else
   {
      if(__DEBUG_PROTECT__ === 1 && __DEBUG_PROTECT_IP__ != $_SERVER['REMOTE_ADDR'])
      {
         return;
      }

      $print = array();
      if(!$debug_file) $debug_file =  _XE_PATH_ . 'files/' . $file;
      $debug_file_exist = file_exists($debug_file);
      if(!$debug_file_exist) $print[] = '<?php exit() ?>';

      if($display_option === TRUE || $display_option === 'ERROR')
      {
         $print[] = '['.date('Y-m-d H:i:s').']'.PHP_EOL;
         $print[] = 'DEBUG Eenties';
         $print[] = str_repeat('=', 80);
      }
      $type = gettype($debug_output);
      if(!in_array($type, array('array', 'object', 'resource')))
      {
         $print[] = 'DEBUG : ' . var_export($debug_output, TRUE);
      }
      else
      {
         $print[] = print_r($debug_output, TRUE);
      }
      $backtrace_args = defined('\DEBUG_BACKTRACE_IGNORE_ARGS') ? \DEBUG_BACKTRACE_IGNORE_ARGS : 0;
      $backtrace = debug_backtrace($backtrace_args);

      if(count($backtrace) > 1 && $backtrace[1]['function'] === 'debugPrint' && !$backtrace[1]['class'])
      {
         array_shift($backtrace);
      }
      foreach($backtrace as $val)
      {
         $print[] = '- ' . $val['file'] . ' line ' . $val['line'];
      }
      $print[] = PHP_EOL;
      @file_put_contents($debug_file, implode(PHP_EOL, $print), FILE_APPEND|LOCK_EX);
   }
}

 

혹시나 아래와 같은 질문 남기실분 계실것 같아서..

Q : 디버그 파일을 실제로 아파치나 Nginx에서 호출하게 되면 내용이 노출되지 않나요?

A : 노출되지 않습니다. 파일이 있는지 없는지 여부를 확인한다음 <php exit; ?> 으로 미리 나가버리게 하기 때문에 내용이 나오지 않고 빈화면만 출력합니다. 안심하세요~~

 

그리고 즐거운 코딩을 해주면 됩니다!!!

하하핫! 

 

이거의 장점은 많은 파일을 호출하거나, 위젯의 출력 경로 및 등등을 알아보기에 정말 직관성이 좋다는 점이죠!

 

덕분에 사내개발직원들도 개발속도도 오른것 같은 그런 느낌적인느낌..(@_@)

람보

profile
람보입니다.
  • profile
    훌륭해요
  • profile
    무슨말인지는 모르겠지만... @_@
    라이믹스에는 개선될테니 춫현!
  • profile profile
    이미됨
  • profile profile
    컹;;