PageRenderTime 58ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/classes/core/System.class.php

https://bitbucket.org/stk2k/charcoalphp2.1
PHP | 802 lines | 599 code | 72 blank | 131 comment | 69 complexity | 6c1d0f6603615fbd8e341c28bcfb1dfc MD5 | raw file
  1. <?php
  2. /**
  3. * ?????????????
  4. *
  5. * PHP version 5
  6. *
  7. * @package core
  8. * @author CharcoalPHP Development Team
  9. * @copyright 2008 - 2012 CharcoalPHP Development Team
  10. */
  11. class Charcoal_System
  12. {
  13. const TOSTRING_MAX_LENGTH = 9999;
  14. const DUMP_MAX_LENGTH = 4096;
  15. /*
  16. * Convert PHP error number to string
  17. */
  18. public static function phpErrorString( $errno )
  19. {
  20. $errors = array(
  21. E_ERROR => "E_ERROR",
  22. E_WARNING => "E_WARNING",
  23. E_PARSE => "E_PARSE",
  24. E_NOTICE => "E_NOTICE",
  25. E_CORE_ERROR => "E_CORE_ERROR",
  26. E_CORE_WARNING => "E_CORE_WARNING",
  27. E_COMPILE_ERROR => "E_COMPILE_ERROR",
  28. E_COMPILE_WARNING => "E_COMPILE_WARNING",
  29. E_USER_ERROR => "E_USER_ERROR",
  30. E_USER_NOTICE => "E_USER_NOTICE",
  31. E_STRICT => "E_STRICT",
  32. E_RECOVERABLE_ERROR => "E_RECOVERABLE_ERROR",
  33. E_DEPRECATED => "E_DEPRECATED",
  34. E_USER_DEPRECATED => "E_USER_DEPRECATED",
  35. );
  36. return isset($errors[$errno]) ? $errors[$errno] : '';
  37. }
  38. /*
  39. * ???????????????????
  40. */
  41. public static function appendArray( $a, $b )
  42. {
  43. if ( $a === NULL ){
  44. $a = array();
  45. }
  46. array_splice($a,count($a),0,$b);
  47. return $a;
  48. }
  49. /*
  50. * ????????
  51. */
  52. public static function swap( $a, $b )
  53. {
  54. $tmp = $a;
  55. $a = $b;
  56. $b = $tmp;
  57. return array( $a, $b );
  58. }
  59. /*
  60. * ??????????????
  61. */
  62. public static function formatByteSize( $size, $precision = 1, array $symbols = NULL )
  63. {
  64. if ( $symbols === NULL ){
  65. $symbols = array('B', 'Kb', 'Mb', 'Gb', 'Tb', 'Pb');
  66. }
  67. $i=0;
  68. while (($size/1024)>1) {
  69. $size=$size/1024;
  70. $i++;
  71. }
  72. return (round($size,$precision)." ".$symbols[$i]);
  73. }
  74. /**
  75. * ????????
  76. *
  77. */
  78. public static function hash( $algorithm = 'sha1' )
  79. {
  80. switch( $algorithm )
  81. {
  82. case 'sha1':
  83. return sha1(uniqid(rand(),1));
  84. case 'md5':
  85. return md5(uniqid(rand(),1));
  86. }
  87. return NULL;
  88. }
  89. /**
  90. * HTML???????????
  91. *
  92. */
  93. public static function escape( $value )
  94. {
  95. if ( is_string($value) ){
  96. $res = htmlspecialchars($value, ENT_QUOTES, mb_internal_encoding());
  97. //log_debug( "debug", "escape:" . print_r($res,true) );
  98. return $res;
  99. }
  100. else if ( is_array($value) ){
  101. return array_map('Charcoal_System::escape', $value);
  102. }
  103. else if ( is_object($value) ){
  104. $object = $value;
  105. $vars = get_object_vars($object);
  106. foreach( $vars as $key => $value ){
  107. $object->$key = self::escape( $value );
  108. }
  109. return $object;
  110. }
  111. return $value;
  112. }
  113. /**
  114. * ???????????HTML???
  115. *
  116. */
  117. public static function decode( $value )
  118. {
  119. if ( is_string($value) ){
  120. //log_debug( "debug", "decode before:" . print_r($value,true) );
  121. $res = htmlspecialchars_decode($value, ENT_QUOTES);
  122. //log_debug( "debug", "decode after:" . print_r($res,true) );
  123. return $res;
  124. }
  125. else if ( is_array($value) ){
  126. return array_map('Charcoal_System::decode', $value);
  127. }
  128. else if ( is_object($value) ){
  129. $object = $value;
  130. $vars = get_object_vars($object);
  131. foreach( $vars as $key => $value ){
  132. $object->$key = self::decode( $value );
  133. }
  134. return $object;
  135. }
  136. return $value;
  137. }
  138. /**
  139. * ??????????????????
  140. *
  141. */
  142. public static function stripTags( $value, $allowable_tags = NULL )
  143. {
  144. if ( is_string($value) ){
  145. $res = strip_tags($value, $allowable_tags);
  146. //log_debug( "debug", "stripTags:" . print_r($res,true) );
  147. return $res;
  148. }
  149. else if ( is_array($value) ){
  150. $array = $value;
  151. foreach( $array as $key => $value ){
  152. $array[$key] = self::stripTags( $value, $allowable_tags );
  153. }
  154. return $array;
  155. }
  156. else if ( is_object($value) ){
  157. $object = $value;
  158. $vars = get_object_vars($object);
  159. foreach( $vars as $key => $value ){
  160. $object->$key = self::stripTags( $value );
  161. }
  162. return $object;
  163. }
  164. return $value;
  165. }
  166. /**
  167. * ????????????????????????
  168. *
  169. */
  170. public static function stripSlashes( $value )
  171. {
  172. if ( is_string($value) ){
  173. return stripslashes($value);
  174. }
  175. else if ( is_array($value) ){
  176. return array_map('Charcoal_System::stripSlashes', $value);
  177. }
  178. else if ( is_object($value) ){
  179. $object = $value;
  180. $vars = get_object_vars($object);
  181. foreach( $vars as $key => $value ){
  182. $object->$key = self::stripSlashes( $value );
  183. }
  184. return $object;
  185. }
  186. return $value;
  187. }
  188. /**
  189. * ?????????????
  190. *
  191. */
  192. public static function escapeString( $string_data, $options = NULL )
  193. {
  194. if ( !$options ){
  195. $options = array(
  196. 'quote_style' => 'ENT_QUOTES',
  197. );
  198. }
  199. $quote_style = ENT_NOQUOTES;
  200. if ( isset($options['quote_style']) && $options['quote_style'] == 'ENT_QUOTES' ){
  201. $quote_style = ENT_QUOTES;
  202. }
  203. $str = htmlspecialchars( $string_data, $quote_style );
  204. return $str;
  205. }
  206. /**
  207. * ??????
  208. *
  209. */
  210. public static function arrayMerge( $array1, $array2 )
  211. {
  212. if ( $array1 === NULL ){
  213. $array1 = array();
  214. }
  215. if ( $array2 === NULL ){
  216. $array2 = array();
  217. }
  218. return array_merge( $array1, $array2 );
  219. }
  220. /**
  221. * ???????????
  222. *
  223. */
  224. public static function makeRandomString( $length, $char_set = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_' )
  225. {
  226. $ret = '';
  227. $char_set_cnt = strlen($char_set);
  228. mt_srand();
  229. for($i = 0; $i < $length; $i++){
  230. $idx = mt_rand(0, $char_set_cnt - 1);
  231. $ret .= $char_set[ $idx ];
  232. }
  233. return $ret;
  234. }
  235. /**
  236. * ??????
  237. *
  238. * @return list($file,$line) ????????????
  239. */
  240. public static function caller( $back = 0 )
  241. {
  242. $bt = debug_backtrace();
  243. $trace = $bt[1 + $back];
  244. $file = isset($trace['file']) ? $trace['file'] : "";
  245. $line = isset($trace['line']) ? $trace['line'] : "";
  246. $object = isset($trace['object']) ? $trace['object'] : "";
  247. $clazz = isset($trace['class']) ? $trace['class'] : "";
  248. return array( $file, $line, $object, $clazz );
  249. }
  250. /**
  251. * ??????????
  252. *
  253. */
  254. public static function filterCallStack( $call_stack = NULL, $fields = "file,line,function,class,args" )
  255. {
  256. $fields = array_flip(explode(",",$fields));
  257. $bt = $call_stack ? $call_stack : debug_backtrace();
  258. $new_bt = array();
  259. foreach( $bt as $row ){
  260. $new_row = array();
  261. if ( isset($fields['file']) ) $new_row['file'] = isset($row['file']) ? $row['file'] : NULL;
  262. if ( isset($fields['line']) ) $new_row['line'] = isset($row['line']) ? $row['line'] : NULL;
  263. if ( isset($fields['function']) ) $new_row['function'] = isset($row['function']) ? $row['function'] : NULL;
  264. if ( isset($fields['class']) ) $new_row['class'] = isset($row['class']) ? $row['class'] : NULL;
  265. if ( isset($fields['object']) ) $new_row['object'] = isset($row['object']) ? $row['object'] : NULL;
  266. if ( isset($fields['type']) ) $new_row['type'] = isset($row['type']) ? $row['type'] : NULL;
  267. if ( isset($fields['args']) ) $new_row['args'] = isset($row['args']) ? $row['args'] : NULL;
  268. $new_bt[] = $new_row;
  269. }
  270. return $new_bt;
  271. }
  272. /**
  273. * ??????????
  274. *
  275. */
  276. public static function printCallStack()
  277. {
  278. $bt = debug_backtrace();
  279. self::dump( $bt );
  280. }
  281. /*
  282. * ???????
  283. */
  284. public static function now(){
  285. list($msec,$sec) = explode(' ',microtime());
  286. return ( (float)$msec + (float)$sec );
  287. }
  288. /**
  289. * ??????????
  290. */
  291. public static function makeTime( $year, $month, $day, $hour = 0, $minute = 0, $second = 0 )
  292. {
  293. return mktime( $hour, $minute, $second, $month, $day, $year );
  294. }
  295. /**
  296. * ???????
  297. */
  298. public static function dateAdd( $year, $month, $day, $add )
  299. {
  300. $new_date = strtotime( "$year/$month/$day + $add days");
  301. return array( date('Y',$new_date), date('n',$new_date), date('j',$new_date) );
  302. }
  303. /**
  304. * ????????
  305. */
  306. public static function dateSub( $year, $month, $day, $sub )
  307. {
  308. $new_date = strtotime( "$year/$month/$day - $sub days");
  309. return array( date('Y',$new_date), date('n',$new_date), date('j',$new_date) );
  310. }
  311. /**
  312. * ????????????????
  313. */
  314. public static function dateDiff( $date1, $date2 = NULL ){
  315. if ( $date2 == NULL ){
  316. // ?????
  317. $date2 = date("Y/m/d");
  318. }
  319. $result = strtotime($date2) - strtotime($date1);
  320. $result = intval( $result / (24 * 60 * 60));
  321. return $result;
  322. }
  323. /**
  324. * ????????
  325. */
  326. public static function compareDate( $date1, $date2 = NULL )
  327. {
  328. if ( $date2 == NULL ){
  329. // ?????
  330. $date2 = date("Y/m/d");
  331. }
  332. $result = strtotime($date1) - strtotime($date2);
  333. return $result;
  334. }
  335. /**
  336. * ????????
  337. */
  338. public static function compareDateYMD( $year1, $month1, $day1, $year2, $month2, $day2 )
  339. {
  340. $result = strtotime("$year1/$month1/$day1") - strtotime("$year2/$month2/$day2");
  341. return $result;
  342. }
  343. /**
  344. * toString?????
  345. *
  346. */
  347. public static function toString( $value, $with_type = FALSE, $max_size = self::TOSTRING_MAX_LENGTH, $tostring_methods = '__toString,toString' )
  348. {
  349. $ret = '';
  350. if ( $value === NULL ){
  351. $ret = 'NULL';
  352. }
  353. else{
  354. $type = gettype($value);
  355. switch( $type ){
  356. case 'string':
  357. case 'integer':
  358. case 'double':
  359. case 'boolean':
  360. case 'NULL':
  361. case 'unknown type':
  362. $ret = strval($value);
  363. if ( $with_type ){
  364. $ret .= '(' . $type . ')';
  365. }
  366. break;
  367. case 'array':
  368. $ret = implode(',',$value);
  369. if ( $with_type ){
  370. $ret .= '(' . $type . ')';
  371. }
  372. break;
  373. case 'object':
  374. {
  375. $methods = explode( ',', $tostring_methods );
  376. foreach( $methods as $method ){
  377. if ( method_exists($value, $method) ){
  378. $ret = $value->{$method}();
  379. break;
  380. }
  381. }
  382. if ( $with_type ){
  383. $ret .= '(' . get_class($value) . ')';
  384. }
  385. }
  386. break;
  387. }
  388. }
  389. if ( $max_size > 0 ){
  390. return strlen($ret) > $max_size ? substr($ret,0,$max_size) . '...' : $ret;
  391. }
  392. else{
  393. return $ret;
  394. }
  395. }
  396. /**
  397. * ?????????
  398. *
  399. */
  400. public static function arrayToString( $ary )
  401. {
  402. return self::implodeArray( ',', $ary );
  403. }
  404. /**
  405. * implode??????5.1.6?????__toString???????????
  406. *
  407. */
  408. public static function implodeArray( $glue, $pieces, $with_type = FALSE, $max_size = self::TOSTRING_MAX_LENGTH, $tostring_methods = '__toString,toString' )
  409. {
  410. $ret = '';
  411. if ( $pieces && is_array($pieces) )
  412. {
  413. foreach( $pieces as $key => $p ){
  414. if ( strlen($ret) > 0 ){
  415. $ret .= $glue;
  416. }
  417. $value = self::toString($p, $with_type, $max_size, $tostring_methods);
  418. $ret .= $value;
  419. }
  420. }
  421. return $ret;
  422. }
  423. /**
  424. * implode??????5.1.6?????__toString???????????
  425. *
  426. */
  427. public static function implodeAssoc( $glue, $pieces, $with_type = FALSE, $max_size = self::TOSTRING_MAX_LENGTH, $tostring_methods = '__toString,toString' )
  428. {
  429. $ret = '';
  430. foreach( $pieces as $key => $value ){
  431. if ( strlen($ret) > 0 ){
  432. $ret .= $glue;
  433. }
  434. $ret .= self::toString($key, $with_type, $max_size, $tostring_methods) . '=' . self::toString($value, $with_type, $max_size, $tostring_methods);
  435. }
  436. return $ret;
  437. }
  438. /**
  439. * ????????
  440. *
  441. */
  442. public static function dump( $var, $back = 0, $options = NULL, $return = FALSE, $max_depth = 6 )
  443. {
  444. list( $file, $line ) = self::caller( $back );
  445. if ( !$options ){
  446. $options = array();
  447. }
  448. $default_options = array(
  449. 'title' => 'system tree dump',
  450. 'font_size' => 11,
  451. 'max_string_length' => self::DUMP_MAX_LENGTH,
  452. 'type' => 'textarea',
  453. );
  454. $options = array_merge( $default_options, $options );
  455. $title = $options['title'];
  456. $font_size = $options['font_size'];
  457. $max_string_length = $options['max_string_length'];
  458. $type = $options['type'];
  459. $lines = array();
  460. self::_dump( '-', $var, 0, $max_string_length, $lines, $max_depth );
  461. switch( CHARCOAL_RUNMODE )
  462. {
  463. case "shell":
  464. $output = "$title @$file($line)" . PHP_EOL;
  465. $output .= implode(PHP_EOL,$lines) . PHP_EOL;
  466. break;
  467. case "http":
  468. switch( $type ){
  469. case 'textarea':
  470. $output = "<h3 style=\"font-size:12px; margin: 2px\"> $title @$file($line)</h3>";
  471. $output .= "<textarea rows=14 style=\"width:100%; font-size:{$font_size}px; margin: 2px\">" . implode(PHP_EOL,$lines) . "</textarea>";
  472. break;
  473. case 'div':
  474. $output = "<div style=\"font-size:12px; margin: 2px\"> $title:" . implode('',$lines) . " @$file($line)</div>";
  475. break;
  476. }
  477. }
  478. if ( $return ){
  479. return $output;
  480. }
  481. else{
  482. echo $output;
  483. }
  484. }
  485. private static function _dump( $key, $value, $depth, $max_string_length, &$lines, $max_depth )
  486. {
  487. if ( $depth > $max_depth ){
  488. $lines[] = str_repeat( '.', $depth * 4 ) . "......(max depth over:$max_depth)";
  489. return;
  490. }
  491. $type = gettype($value);
  492. switch( $type ){
  493. case 'string':
  494. case 'integer':
  495. case 'double':
  496. case 'boolean':
  497. case 'NULL':
  498. case 'unknown type':
  499. {
  500. $str = strval($value);
  501. if ( strlen($str) > $max_string_length ){
  502. $str = substr( $str, 0, $max_string_length ) . '...(total:' . strlen($str) . 'bytes)';
  503. }
  504. $str = htmlspecialchars( $str, ENT_QUOTES );
  505. $lines[] = str_repeat( '.', $depth * 4 ) . "[$key:$type]$str";
  506. }
  507. break;
  508. case 'array':
  509. {
  510. $lines[] = str_repeat( '.', $depth * 4 ) . "[$key:array(" . count($value) . ')]';
  511. foreach( $value as $_key => $_value ){
  512. self::_dump( $_key, $_value, $depth + 2, $max_string_length, $lines, $max_depth );
  513. }
  514. }
  515. break;
  516. case 'object':
  517. {
  518. $clazz = get_class( $value );
  519. $id = function_exists('spl_object_hash') ? spl_object_hash($value) : 'unknown';
  520. $lines[] = str_repeat( '.', $depth * 4 ) . "[$key:object($clazz)@$id]";
  521. foreach( ((array)$value) as $_key => $_value ){
  522. self::_dump( $_key, $_value, $depth + 2, $max_string_length, $lines, $max_depth );
  523. }
  524. }
  525. break;
  526. }
  527. }
  528. /**
  529. * ????????????
  530. *
  531. */
  532. public static function tree_dump( $var, $back = 1, $options = NULL, $return = FALSE, $max_depth = 6 )
  533. {
  534. list( $file, $line ) = self::caller( $back );
  535. if ( !$options ){
  536. $options = array();
  537. }
  538. $default_options = array(
  539. 'title' => 'system tree dump',
  540. 'font_size' => 11,
  541. 'max_string_length' => self::DUMP_MAX_LENGTH,
  542. 'type' => 'textarea',
  543. );
  544. $options = array_merge( $default_options, $options );
  545. $title = $options['title'];
  546. $font_size = $options['font_size'];
  547. $max_string_length = $options['max_string_length'];
  548. $type = $options['type'];
  549. $lines = array();
  550. self::_tree_dump( '-', $var, 0, $max_string_length, $lines, $max_depth );
  551. switch( CHARCOAL_RUNMODE )
  552. {
  553. case "shell":
  554. $output = "$title @$file($line)" . PHP_EOL;
  555. $output .= implode(PHP_EOL,$lines) . PHP_EOL;
  556. break;
  557. case "http":
  558. switch( $type ){
  559. case 'textarea':
  560. $output = "<h3 style=\"font-size:12px; margin: 2px\"> $title @$file($line)</h3>";
  561. $output .= "<textarea rows=14 style=\"width:100%; font-size:{$font_size}px; margin: 2px\">" . implode(PHP_EOL,$lines) . "</textarea>";
  562. break;
  563. case 'div':
  564. $output = "<div style=\"font-size:12px; margin: 2px\"> $title:" . implode('',$lines) . " @$file($line)</div>";
  565. break;
  566. }
  567. }
  568. if ( $return ){
  569. return $output;
  570. }
  571. else{
  572. echo $output;
  573. }
  574. }
  575. private static function _tree_dump( $key, $value, $depth, $max_string_length, &$lines, $max_depth )
  576. {
  577. if ( $depth > $max_depth ){
  578. return;
  579. }
  580. $type = gettype($value);
  581. switch( $type ){
  582. case 'string':
  583. case 'integer':
  584. case 'double':
  585. case 'boolean':
  586. case 'NULL':
  587. case 'unknown type':
  588. {
  589. $lines[] = str_repeat( '-', $depth * 4 ) . "[$key:$type]$value";
  590. }
  591. break;
  592. case 'array':
  593. {
  594. $lines[] = str_repeat( '-', $depth * 4 ) . "[$key:array(" . count($value) . ')]';
  595. foreach( $value as $key => $value ){
  596. $type = gettype($value);
  597. if ( $type == 'array' || $type == 'object' ){
  598. self::_tree_dump( $key, $value, $depth + 1, $max_string_length, $lines, $max_depth );
  599. }
  600. }
  601. }
  602. break;
  603. case 'object':
  604. {
  605. $clazz = get_class( $value );
  606. $id = function_exists('spl_object_hash') ? spl_object_hash($value) : 'unknown';
  607. $lines[] = str_repeat( '-', $depth * 4 ) . "[$key:object($clazz)@$id]";
  608. foreach( ((array)$value) as $key => $value ){
  609. $type = gettype($value);
  610. if ( $type == 'array' || $type == 'object' ){
  611. self::_tree_dump( $key, $value, $depth + 1, $max_string_length, $lines, $max_depth );
  612. }
  613. }
  614. }
  615. break;
  616. }
  617. }
  618. /**
  619. * ??????????????
  620. */
  621. public static function detectEncoding( $str, $detect_order = "EUC-JP, SJIS, JIS, UTF-8" )
  622. {
  623. return mb_detect_encoding( $str, $detect_order, TRUE );
  624. }
  625. /**
  626. * ???????
  627. */
  628. public static function convertEncoding( $str, $to_encoding = NULL, $from_encoding = NULL )
  629. {
  630. if ( is_string($str) && $to_encoding ){
  631. // ???????
  632. return mb_convert_encoding($str,$to_encoding, $from_encoding);
  633. }
  634. // ???????
  635. return $str;
  636. }
  637. /**
  638. * ?????????
  639. */
  640. public static function convertEncodingRecursive( $var, $to_encoding = NULL, $from_encoding = NULL )
  641. {
  642. $type = gettype($var);
  643. switch( $type ){
  644. case 'string':
  645. {
  646. return mb_convert_encoding($var,$to_encoding, $from_encoding);
  647. }
  648. break;
  649. case 'integer':
  650. case 'double':
  651. case 'boolean':
  652. case 'NULL':
  653. case 'unknown type':
  654. break;
  655. case 'array':
  656. {
  657. $newArray = array();
  658. foreach( $var as $key => $value ){
  659. $value = self::convertEncodingRecursive( $value, $to_encoding, $from_encoding );
  660. $newArray[ $key ] = $value;
  661. }
  662. return $newArray;
  663. }
  664. break;
  665. case 'object':
  666. {
  667. $newObject = clone $var;
  668. if ( $var instanceof Charcoal_Iterator ){
  669. foreach( $var as $key => $value ){
  670. $value = self::convertEncodingRecursive( $value, $to_encoding, $from_encoding );
  671. $newObject->$key = $value;
  672. }
  673. return $newObject;
  674. }
  675. else{
  676. $obj_vars = get_object_vars( $var );
  677. foreach( $obj_vars as $key => $value ){
  678. $value = self::convertEncodingRecursive( $value, $to_encoding, $from_encoding );
  679. $newObject->$key = $value;
  680. }
  681. return $newObject;
  682. }
  683. }
  684. break;
  685. }
  686. return $var;
  687. }
  688. /**
  689. * ??????
  690. */
  691. public static function convertArrayRecursive( $var )
  692. {
  693. $type = gettype($var);
  694. switch( $type ){
  695. case 'string':
  696. case 'integer':
  697. case 'double':
  698. case 'boolean':
  699. case 'NULL':
  700. case 'unknown type':
  701. {
  702. return $var;
  703. }
  704. break;
  705. case 'array':
  706. {
  707. $newArray = array();
  708. foreach( $var as $key => $value ){
  709. $value = self::convertArrayRecursive( $value );
  710. $newArray[ $key ] = $value;
  711. }
  712. return $newArray;
  713. }
  714. break;
  715. case 'object':
  716. {
  717. $newArray = array();
  718. $obj_vars = get_object_vars( $var );
  719. foreach( $obj_vars as $key => $value ){
  720. $value = self::convertArrayRecursive( $value );
  721. $newArray[$key] = $value;
  722. }
  723. return $newArray;
  724. }
  725. break;
  726. }
  727. return $var;
  728. }
  729. }
  730. return __FILE__;