Posted By

cerxx on 10/11/18


Tagged

tools


Versions (?)

ChromePHP


 / Published in: PHP
 

URL: https://www.kobzarev.com/browser/console-logging-extension-for-google-chrome/

ChromePhp is a PHP library for the Chrome Logger Google Chrome extension. This library allows you to log variables to the Chrome console.

  1. <?php
  2. /**
  3.  * Copyright 2010-2013 Craig Campbell
  4.  *
  5.  * Licensed under the Apache License, Version 2.0 (the "License");
  6.  * you may not use this file except in compliance with the License.
  7.  * You may obtain a copy of the License at
  8.  *
  9.  * http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17.  
  18. /**
  19.  * Server Side Chrome PHP debugger class
  20.  *
  21.  * @package ChromePhp
  22.  * @author Craig Campbell <[email protected]>
  23.  */
  24. class ChromePhp
  25. {
  26. /**
  27.   * @var string
  28.   */
  29. const VERSION = '4.1.0';
  30.  
  31. /**
  32.   * @var string
  33.   */
  34. const HEADER_NAME = 'X-ChromeLogger-Data';
  35.  
  36. /**
  37.   * @var string
  38.   */
  39. const BACKTRACE_LEVEL = 'backtrace_level';
  40.  
  41. /**
  42.   * @var string
  43.   */
  44. const LOG = 'log';
  45.  
  46. /**
  47.   * @var string
  48.   */
  49. const WARN = 'warn';
  50.  
  51. /**
  52.   * @var string
  53.   */
  54. const ERROR = 'error';
  55.  
  56. /**
  57.   * @var string
  58.   */
  59. const GROUP = 'group';
  60.  
  61. /**
  62.   * @var string
  63.   */
  64. const INFO = 'info';
  65.  
  66. /**
  67.   * @var string
  68.   */
  69. const GROUP_END = 'groupEnd';
  70.  
  71. /**
  72.   * @var string
  73.   */
  74. const GROUP_COLLAPSED = 'groupCollapsed';
  75.  
  76. /**
  77.   * @var string
  78.   */
  79. const TABLE = 'table';
  80.  
  81. /**
  82.   * @var string
  83.   */
  84. protected $_php_version;
  85.  
  86. /**
  87.   * @var int
  88.   */
  89. protected $_timestamp;
  90.  
  91. /**
  92.   * @var array
  93.   */
  94. protected $_json = array(
  95. 'version' => self::VERSION,
  96. 'columns' => array('log', 'backtrace', 'type'),
  97. 'rows' => array()
  98. );
  99.  
  100. /**
  101.   * @var array
  102.   */
  103. protected $_backtraces = array();
  104.  
  105. /**
  106.   * @var bool
  107.   */
  108. protected $_error_triggered = false;
  109.  
  110. /**
  111.   * @var array
  112.   */
  113. protected $_settings = array(
  114. self::BACKTRACE_LEVEL => 1
  115. );
  116.  
  117. /**
  118.   * @var ChromePhp
  119.   */
  120. protected static $_instance;
  121.  
  122. /**
  123.   * Prevent recursion when working with objects referring to each other
  124.   *
  125.   * @var array
  126.   */
  127. protected $_processed = array();
  128.  
  129. /**
  130.   * constructor
  131.   */
  132. private function __construct()
  133. {
  134. $this->_php_version = phpversion();
  135. $this->_timestamp = $this->_php_version >= 5.1 ? $_SERVER['REQUEST_TIME'] : time();
  136. $this->_json['request_uri'] = $_SERVER['REQUEST_URI'];
  137. }
  138.  
  139. /**
  140.   * gets instance of this class
  141.   *
  142.   * @return ChromePhp
  143.   */
  144. public static function getInstance()
  145. {
  146. if (self::$_instance === null) {
  147. self::$_instance = new self();
  148. }
  149. return self::$_instance;
  150. }
  151.  
  152. /**
  153.   * logs a variable to the console
  154.   *
  155.   * @param mixed $data,... unlimited OPTIONAL number of additional logs [...]
  156.   * @return void
  157.   */
  158. public static function log()
  159. {
  160. $args = func_get_args();
  161. return self::_log('', $args);
  162. }
  163.  
  164. /**
  165.   * logs a warning to the console
  166.   *
  167.   * @param mixed $data,... unlimited OPTIONAL number of additional logs [...]
  168.   * @return void
  169.   */
  170. public static function warn()
  171. {
  172. $args = func_get_args();
  173. return self::_log(self::WARN, $args);
  174. }
  175.  
  176. /**
  177.   * logs an error to the console
  178.   *
  179.   * @param mixed $data,... unlimited OPTIONAL number of additional logs [...]
  180.   * @return void
  181.   */
  182. public static function error()
  183. {
  184. $args = func_get_args();
  185. return self::_log(self::ERROR, $args);
  186. }
  187.  
  188. /**
  189.   * sends a group log
  190.   *
  191.   * @param string value
  192.   */
  193. public static function group()
  194. {
  195. $args = func_get_args();
  196. return self::_log(self::GROUP, $args);
  197. }
  198.  
  199. /**
  200.   * sends an info log
  201.   *
  202.   * @param mixed $data,... unlimited OPTIONAL number of additional logs [...]
  203.   * @return void
  204.   */
  205. public static function info()
  206. {
  207. $args = func_get_args();
  208. return self::_log(self::INFO, $args);
  209. }
  210.  
  211. /**
  212.   * sends a collapsed group log
  213.   *
  214.   * @param string value
  215.   */
  216. public static function groupCollapsed()
  217. {
  218. $args = func_get_args();
  219. return self::_log(self::GROUP_COLLAPSED, $args);
  220. }
  221.  
  222. /**
  223.   * ends a group log
  224.   *
  225.   * @param string value
  226.   */
  227. public static function groupEnd()
  228. {
  229. $args = func_get_args();
  230. return self::_log(self::GROUP_END, $args);
  231. }
  232.  
  233. /**
  234.   * sends a table log
  235.   *
  236.   * @param string value
  237.   */
  238. public static function table()
  239. {
  240. $args = func_get_args();
  241. return self::_log(self::TABLE, $args);
  242. }
  243.  
  244. /**
  245.   * internal logging call
  246.   *
  247.   * @param string $type
  248.   * @return void
  249.   */
  250. protected static function _log($type, array $args)
  251. {
  252. // nothing passed in, don't do anything
  253. if (count($args) == 0 && $type != self::GROUP_END) {
  254. return;
  255. }
  256.  
  257. $logger = self::getInstance();
  258.  
  259. $logger->_processed = array();
  260.  
  261. $logs = array();
  262. foreach ($args as $arg) {
  263. $logs[] = $logger->_convert($arg);
  264. }
  265.  
  266. $backtrace = debug_backtrace(false);
  267. $level = $logger->getSetting(self::BACKTRACE_LEVEL);
  268.  
  269. $backtrace_message = 'unknown';
  270. if (isset($backtrace[$level]['file']) && isset($backtrace[$level]['line'])) {
  271. $backtrace_message = $backtrace[$level]['file'] . ' : ' . $backtrace[$level]['line'];
  272. }
  273.  
  274. $logger->_addRow($logs, $backtrace_message, $type);
  275. }
  276.  
  277. /**
  278.   * converts an object to a better format for logging
  279.   *
  280.   * @param Object
  281.   * @return array
  282.   */
  283. protected function _convert($object)
  284. {
  285. // if this isn't an object then just return it
  286. if (!is_object($object)) {
  287. return $object;
  288. }
  289.  
  290. //Mark this object as processed so we don't convert it twice and it
  291. //Also avoid recursion when objects refer to each other
  292. $this->_processed[] = $object;
  293.  
  294. $object_as_array = array();
  295.  
  296. // first add the class name
  297. $object_as_array['___class_name'] = get_class($object);
  298.  
  299. // loop through object vars
  300. $object_vars = get_object_vars($object);
  301. foreach ($object_vars as $key => $value) {
  302.  
  303. // same instance as parent object
  304. if ($value === $object || in_array($value, $this->_processed, true)) {
  305. $value = 'recursion - parent object [' . get_class($value) . ']';
  306. }
  307. $object_as_array[$key] = $this->_convert($value);
  308. }
  309.  
  310. $reflection = new ReflectionClass($object);
  311.  
  312. // loop through the properties and add those
  313. foreach ($reflection->getProperties() as $property) {
  314.  
  315. // if one of these properties was already added above then ignore it
  316. if (array_key_exists($property->getName(), $object_vars)) {
  317. continue;
  318. }
  319. $type = $this->_getPropertyKey($property);
  320.  
  321. if ($this->_php_version >= 5.3) {
  322. $property->setAccessible(true);
  323. }
  324.  
  325. try {
  326. $value = $property->getValue($object);
  327. } catch (ReflectionException $e) {
  328. $value = 'only PHP 5.3 can access private/protected properties';
  329. }
  330.  
  331. // same instance as parent object
  332. if ($value === $object || in_array($value, $this->_processed, true)) {
  333. $value = 'recursion - parent object [' . get_class($value) . ']';
  334. }
  335.  
  336. $object_as_array[$type] = $this->_convert($value);
  337. }
  338. return $object_as_array;
  339. }
  340.  
  341. /**
  342.   * takes a reflection property and returns a nicely formatted key of the property name
  343.   *
  344.   * @param ReflectionProperty
  345.   * @return string
  346.   */
  347. protected function _getPropertyKey(ReflectionProperty $property)
  348. {
  349. $static = $property->isStatic() ? ' static' : '';
  350. if ($property->isPublic()) {
  351. return 'public' . $static . ' ' . $property->getName();
  352. }
  353.  
  354. if ($property->isProtected()) {
  355. return 'protected' . $static . ' ' . $property->getName();
  356. }
  357.  
  358. if ($property->isPrivate()) {
  359. return 'private' . $static . ' ' . $property->getName();
  360. }
  361. }
  362.  
  363. /**
  364.   * adds a value to the data array
  365.   *
  366.   * @var mixed
  367.   * @return void
  368.   */
  369. protected function _addRow(array $logs, $backtrace, $type)
  370. {
  371. // if this is logged on the same line for example in a loop, set it to null to save space
  372. if (in_array($backtrace, $this->_backtraces)) {
  373. $backtrace = null;
  374. }
  375.  
  376. // for group, groupEnd, and groupCollapsed
  377. // take out the backtrace since it is not useful
  378. if ($type == self::GROUP || $type == self::GROUP_END || $type == self::GROUP_COLLAPSED) {
  379. $backtrace = null;
  380. }
  381.  
  382. if ($backtrace !== null) {
  383. $this->_backtraces[] = $backtrace;
  384. }
  385.  
  386. $row = array($logs, $backtrace, $type);
  387.  
  388. $this->_json['rows'][] = $row;
  389. $this->_writeHeader($this->_json);
  390. }
  391.  
  392. protected function _writeHeader($data)
  393. {
  394. header(self::HEADER_NAME . ': ' . $this->_encode($data));
  395. }
  396.  
  397. /**
  398.   * encodes the data to be sent along with the request
  399.   *
  400.   * @param array $data
  401.   * @return string
  402.   */
  403. protected function _encode($data)
  404. {
  405. return base64_encode(utf8_encode(json_encode($data)));
  406. }
  407.  
  408. /**
  409.   * adds a setting
  410.   *
  411.   * @param string key
  412.   * @param mixed value
  413.   * @return void
  414.   */
  415. public function addSetting($key, $value)
  416. {
  417. $this->_settings[$key] = $value;
  418. }
  419.  
  420. /**
  421.   * add ability to set multiple settings in one call
  422.   *
  423.   * @param array $settings
  424.   * @return void
  425.   */
  426. public function addSettings(array $settings)
  427. {
  428. foreach ($settings as $key => $value) {
  429. $this->addSetting($key, $value);
  430. }
  431. }
  432.  
  433. /**
  434.   * gets a setting
  435.   *
  436.   * @param string key
  437.   * @return mixed
  438.   */
  439. public function getSetting($key)
  440. {
  441. if (!isset($this->_settings[$key])) {
  442. return null;
  443. }
  444. return $this->_settings[$key];
  445. }
  446. }

Report this snippet  

You need to login to post a comment.