common.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605
  1. <?php
  2. // +--------------------------------------------------------------------------
  3. // | Senthot [ DEVELOPED BY ME ]
  4. // +--------------------------------------------------------------------------
  5. // | Copyright (c) 2005-2013 http://www.senthot.com All rights reserved.
  6. // | License ( http://www.apache.org/licenses/LICENSE-2.0 )
  7. // | Author: ms134n ( [email protected] )
  8. // +--------------------------------------------------------------------------
  9. /**
  10. * Sen Basic function library
  11. * @category Sen
  12. * @package Common
  13. * @author ms134n <[email protected]>
  14. */
  15. /**
  16. * Records and statistical time ( microseconds ) and memory usage
  17. * Use method:
  18. * <code>
  19. * G('begin'); // Records the start tag
  20. * // ... Interval running code
  21. * G('end'); // End of record tag
  22. * echo G('begin','end',6); // Running time interval statistics Accurate to six decimal
  23. * echo G('begin','end','m'); // Memory usage statistics interval
  24. * If the end tag bit is not defined, it will automatically mark the current position as
  25. * Which requires memory usage statistics MEMORY_LIMIT_ON Constant is true only valid
  26. * </code>
  27. * @param string $start Start tag
  28. * @param string $end End tag
  29. * @param integer|string $dec Decimal places or m
  30. * @return mixed
  31. */
  32. function G($start,$end='',$dec=4) {
  33. static $_info = array();
  34. static $_mem = array();
  35. if(is_float($end)) { // Record Time
  36. $_info[$start] = $end;
  37. }elseif(!empty($end)){ // Time and memory usage statistics
  38. if(!isset($_info[$end])) $_info[$end] = microtime(TRUE);
  39. if(MEMORY_LIMIT_ON && $dec=='m'){
  40. if(!isset($_mem[$end])) $_mem[$end] = memory_get_usage();
  41. return number_format(($_mem[$end]-$_mem[$start])/1024);
  42. }else{
  43. return number_format(($_info[$end]-$_info[$start]),$dec);
  44. }
  45. }else{ // Record Time and memory usage
  46. $_info[$start] = microtime(TRUE);
  47. if(MEMORY_LIMIT_ON) $_mem[$start] = memory_get_usage();
  48. }
  49. }
  50. /**
  51. * Set and get statistics
  52. * Use method:
  53. * <code>
  54. * N('db',1); // Record the number of database operations
  55. * N('read',1); // Record reads
  56. * echo N('db'); // Get the current page number of all database operations
  57. * echo N('read'); // Get the current page reads
  58. * </code>
  59. * @param string $key Identify the location
  60. * @param integer $step Step value
  61. * @return mixed
  62. */
  63. function N($key, $step=0,$save=false) {
  64. static $_num = array();
  65. if (!isset($_num[$key])) {
  66. $_num[$key] = (false !== $save)? S('N_'.$key) : 0;
  67. }
  68. if (empty($step))
  69. return $_num[$key];
  70. else
  71. $_num[$key] = $_num[$key] + (int) $step;
  72. if(false !== $save){ // Save Results
  73. S('N_'.$key,$_num[$key],$save);
  74. }
  75. }
  76. /**
  77. * Convert string naming style
  78. * type 0 The Java-style converted to C style 1 The C-style into Java style
  79. * @param string $name String
  80. * @param integer $type Conversion Type
  81. * @return string
  82. */
  83. function parse_name($name, $type=0) {
  84. if ($type) {
  85. return ucfirst(preg_replace("/_([a-zA-Z])/e", "strtoupper('\\1')", $name));
  86. } else {
  87. return strtolower(trim(preg_replace("/[A-Z]/", "_\\0", $name), "_"));
  88. }
  89. }
  90. /**
  91. * Optimized require_once
  92. * @param string $filename File address
  93. * @return boolean
  94. */
  95. function require_cache($filename) {
  96. static $_importFiles = array();
  97. if (!isset($_importFiles[$filename])) {
  98. if (file_exists_case($filename)) {
  99. require $filename;
  100. $_importFiles[$filename] = true;
  101. } else {
  102. $_importFiles[$filename] = false;
  103. }
  104. }
  105. return $_importFiles[$filename];
  106. }
  107. /**
  108. * Batch import file Success, returns
  109. * @param array $array Array of files
  110. * @param boolean $return Loaded successfully whether to return
  111. * @return boolean
  112. */
  113. function require_array($array,$return=false){
  114. foreach ($array as $file){
  115. if (require_cache($file) && $return) return true;
  116. }
  117. if($return) return false;
  118. }
  119. /**
  120. * Judged case-sensitive file exists
  121. * @param string $filename File address
  122. * @return boolean
  123. */
  124. function file_exists_case($filename) {
  125. if (is_file($filename)) {
  126. if (IS_WIN && C('APP_FILE_CASE')) {
  127. if (basename(realpath($filename)) != basename($filename))
  128. return false;
  129. }
  130. return true;
  131. }
  132. return false;
  133. }
  134. /**
  135. * Import the required class libraries With Java Import This function has the cache function
  136. * @param string $class Class Library namespace string
  137. * @param string $baseUrl Start Path
  138. * @param string $ext Importing the file extension
  139. * @return boolean
  140. */
  141. function import($class, $baseUrl = '', $ext='.class.php') {
  142. static $_file = array();
  143. $class = str_replace(array('.', '#'), array('/', '.'), $class);
  144. if ('' === $baseUrl && false === strpos($class, '/')) {
  145. // Check the alias import
  146. return alias_import($class);
  147. }
  148. if (isset($_file[$class . $baseUrl]))
  149. return true;
  150. else
  151. $_file[$class . $baseUrl] = true;
  152. $class_strut = explode('/', $class);
  153. if (empty($baseUrl)) {
  154. $libPath = defined('BASE_LIB_PATH')?BASE_LIB_PATH:LIB_PATH;
  155. if ('@' == $class_strut[0] || APP_NAME == $class_strut[0]) {
  156. //Load current project application library
  157. $baseUrl = dirname($libPath);
  158. $class = substr_replace($class, basename($libPath).'/', 0, strlen($class_strut[0]) + 1);
  159. }elseif ('sen' == strtolower($class_strut[0])){ // sen Official Base Class Library
  160. $baseUrl = CORE_PATH;
  161. $class = substr($class,6);
  162. }elseif (in_array(strtolower($class_strut[0]), array('org', 'com'))) {
  163. // org Third-party public libraries com Corporate public library
  164. $baseUrl = LIBRARY_PATH;
  165. }else { // Other items loaded application library
  166. $class = substr_replace($class, '', 0, strlen($class_strut[0]) + 1);
  167. $baseUrl = APP_PATH . '../' . $class_strut[0] . '/'.basename($libPath).'/';
  168. }
  169. }
  170. if (substr($baseUrl, -1) != '/')
  171. $baseUrl .= '/';
  172. $classfile = $baseUrl . $class . $ext;
  173. if (!class_exists(basename($class),false)) {
  174. // If the class does not exist The import library file
  175. return require_cache($classfile);
  176. }
  177. }
  178. /**
  179. * Way based on namespaces imported library
  180. * load('@.Util.Array')
  181. * @param string $name Library namespace string
  182. * @param string $baseUrl Start Path
  183. * @param string $ext Importing the file extension
  184. * @return void
  185. */
  186. function load($name, $baseUrl='', $ext='.php') {
  187. $name = str_replace(array('.', '#'), array('/', '.'), $name);
  188. if (empty($baseUrl)) {
  189. if (0 === strpos($name, '@/')) {
  190. //Load current project library
  191. $baseUrl = COMMON_PATH;
  192. $name = substr($name, 2);
  193. } else {
  194. //Load Senthot System Function Library
  195. $baseUrl = ADDONS_PATH . 'Function/';
  196. }
  197. }
  198. if (substr($baseUrl, -1) != '/')
  199. $baseUrl .= '/';
  200. require_cache($baseUrl . $name . $ext);
  201. }
  202. /**
  203. * Quickly import third-party frameworks library All third-party frameworks into a unified library files System, Vendor directory
  204. * @param string $class Library
  205. * @param string $baseUrl Base directory
  206. * @param string $ext Library suffix
  207. * @return boolean
  208. */
  209. function vendor($class, $baseUrl = '', $ext='.php') {
  210. if (empty($baseUrl))
  211. $baseUrl = VENDOR_PATH;
  212. return import($class, $baseUrl, $ext);
  213. }
  214. /**
  215. * Quickly define and import alias Support batch Definition
  216. * @param string|array $alias Alias library
  217. * @param string $classfile Corresponding library
  218. * @return boolean
  219. */
  220. function alias_import($alias, $classfile='') {
  221. static $_alias = array();
  222. if (is_string($alias)) {
  223. if(isset($_alias[$alias])) {
  224. return require_cache($_alias[$alias]);
  225. }elseif ('' !== $classfile) {
  226. // Defining aliases import
  227. $_alias[$alias] = $classfile;
  228. return;
  229. }
  230. }elseif (is_array($alias)) {
  231. $_alias = array_merge($_alias,$alias);
  232. return;
  233. }
  234. return false;
  235. }
  236. /**
  237. * D Functions Use for instantiating Model Format Project://Grouping/Module
  238. * @param string $name Model resource address
  239. * @param string $layer Business layer name
  240. * @return Model
  241. */
  242. function D($name='',$layer='') {
  243. if(empty($name)) return new Model;
  244. static $_model = array();
  245. $layer = $layer?$layer:C('DEFAULT_M_LAYER');
  246. if(strpos($name,'://')) {// Specify the project
  247. $name = str_replace('://','/'.$layer.'/',$name);
  248. }else{
  249. $name = C('DEFAULT_APP').'/'.$layer.'/'.$name;
  250. }
  251. if(isset($_model[$name])) return $_model[$name];
  252. import($name.$layer);
  253. $class = basename($name.$layer);
  254. if(class_exists($class)) {
  255. $model = new $class();
  256. }else {
  257. $model = new Model(basename($name));
  258. }
  259. $_model[$name] = $model;
  260. return $model;
  261. }
  262. /**
  263. * M function Use for instantiating a no model file Model
  264. * @param string $name Model Name Support base model designation For example, MongoModel:User
  265. * @param string $tablePrefix Table Prefix
  266. * @param mixed $connection Database connection information
  267. * @return Model
  268. */
  269. function M($name='', $tablePrefix='',$connection='') {
  270. static $_model = array();
  271. if(strpos($name,':')) {
  272. list($class,$name) = explode(':',$name);
  273. }else{
  274. $class = 'Model';
  275. }
  276. $guid = $tablePrefix . $name . '_' . $class;
  277. if (!isset($_model[$guid]))
  278. $_model[$guid] = new $class($name,$tablePrefix,$connection);
  279. return $_model[$guid];
  280. }
  281. /**
  282. * A function Use for instantiation Action Format:[Project://][Grouping/]Module
  283. * @param string $name Action Resources Address
  284. * @param string $layer Control layer name
  285. * @param boolean $common Whether public directory
  286. * @return Action|false
  287. */
  288. function A($name,$layer='',$common=false) {
  289. static $_action = array();
  290. $layer = $layer?$layer:C('DEFAULT_C_LAYER');
  291. if(strpos($name,'://')) {// Specify the project
  292. $name = str_replace('://','/'.$layer.'/',$name);
  293. }else{
  294. $name = '@/'.$layer.'/'.$name;
  295. }
  296. if(isset($_action[$name])) return $_action[$name];
  297. if($common){ // Independent groups case Loading public directories library
  298. import(str_replace('@/','',$name).$layer,LIB_PATH);
  299. }else{
  300. import($name.$layer);
  301. }
  302. $class = basename($name.$layer);
  303. if(class_exists($class,false)) {
  304. $action = new $class();
  305. $_action[$name] = $action;
  306. return $action;
  307. }else {
  308. return false;
  309. }
  310. }
  311. /**
  312. * Remote method invocation module operation URL Parameter format [Project://][Grouping/]Module/Operating
  313. * @param string $url Call address
  314. * @param string|array $vars Call parameters Support strings and arrays
  315. * @param string $layer To invoke the name of the control layer
  316. * @return mixed
  317. */
  318. function R($url,$vars=array(),$layer='') {
  319. $info = pathinfo($url);
  320. $action = $info['basename'];
  321. $module = $info['dirname'];
  322. $class = A($module,$layer);
  323. if($class){
  324. if(is_string($vars)) {
  325. parse_str($vars,$vars);
  326. }
  327. return call_user_func_array(array(&$class,$action.C('ACTION_SUFFIX')),$vars);
  328. }else{
  329. return false;
  330. }
  331. }
  332. /**
  333. * Get and Set language definition(Insensitive)
  334. * @param string|array $name Linguistic variables
  335. * @param string $value Language values
  336. * @return mixed
  337. */
  338. function L($name=null, $value=null) {
  339. static $_lang = array();
  340. // Empty parameter returns all definitions
  341. if (empty($name))
  342. return $_lang;
  343. // Determine the language for(Or set up)
  344. // If there, direct return all uppercase $name
  345. if (is_string($name)) {
  346. $name = strtoupper($name);
  347. if (is_null($value))
  348. return isset($_lang[$name]) ? $_lang[$name] : $name;
  349. $_lang[$name] = $value; // Language definition
  350. return;
  351. }
  352. // Batch Definition
  353. if (is_array($name))
  354. $_lang = array_merge($_lang, array_change_key_case($name, CASE_UPPER));
  355. return;
  356. }
  357. /**
  358. * Get and set configuration parameters Support batch Definition
  359. * @param string|array $name Configuration Variables
  360. * @param mixed $value Configuration values
  361. * @return mixed
  362. */
  363. function C($name=null, $value=null) {
  364. static $_config = array();
  365. // No parameters for all
  366. if (empty($name)) {
  367. if(!empty($value) && $array = S('c_'.$value)) {
  368. $_config = array_merge($_config, array_change_key_case($array));
  369. }
  370. return $_config;
  371. }
  372. // Get or set the precedence assignment
  373. if (is_string($name)) {
  374. if (!strpos($name, '.')) {
  375. $name = strtolower($name);
  376. if (is_null($value))
  377. return isset($_config[$name]) ? $_config[$name] : null;
  378. $_config[$name] = $value;
  379. return;
  380. }
  381. // Dimensional array set and get Support
  382. $name = explode('.', $name);
  383. $name[0] = strtolower($name[0]);
  384. if (is_null($value))
  385. return isset($_config[$name[0]][$name[1]]) ? $_config[$name[0]][$name[1]] : null;
  386. $_config[$name[0]][$name[1]] = $value;
  387. return;
  388. }
  389. // Batch settings
  390. if (is_array($name)){
  391. $_config = array_merge($_config, array_change_key_case($name));
  392. if(!empty($value)) {// Save the configuration values
  393. S('c_'.$value,$_config);
  394. }
  395. return;
  396. }
  397. return null; // Avoid illegal argument
  398. }
  399. /**
  400. * Tag extension treatment
  401. * @param string $tag Tag name
  402. * @param mixed $params Incoming parameters
  403. * @return mixed
  404. */
  405. function tag($tag, &$params=NULL) {
  406. // System tab expansion
  407. $extends = C('extends.' . $tag);
  408. // Apply Tag Expansion
  409. $tags = C('tags.' . $tag);
  410. if (!empty($tags)) {
  411. if(empty($tags['_overlay']) && !empty($extends)) { // Merge extended
  412. $tags = array_unique(array_merge($extends,$tags));
  413. }elseif(isset($tags['_overlay'])){ // By setting '_overlay'=>1 coverSystem tag
  414. unset($tags['_overlay']);
  415. }
  416. }elseif(!empty($extends)) {
  417. $tags = $extends;
  418. }
  419. if($tags) {
  420. if(APP_DEBUG) {
  421. G($tag.'Start');
  422. trace('[ '.$tag.' ] --START--','','INFO');
  423. }
  424. // Execute extended
  425. foreach ($tags as $key=>$name) {
  426. if(!is_int($key)) { // Specify the full path of the class acts Use forMode extended
  427. $name = $key;
  428. }
  429. B($name, $params);
  430. }
  431. if(APP_DEBUG) { // Record the behavior of execution log
  432. trace('[ '.$tag.' ] --END-- [ RunTime:'.G($tag.'Start',$tag.'End',6).'s ]','','INFO');
  433. }
  434. }else{ // Did not perform any act Return false
  435. return false;
  436. }
  437. }
  438. /**
  439. * Behavior extended to dynamically add a tag
  440. * @param string $tag Tag name
  441. * @param string $behavior Behavior name
  442. * @param string $path Behavior Path
  443. * @return void
  444. */
  445. function add_tag_behavior($tag,$behavior,$path='') {
  446. $array = C('tags.'.$tag);
  447. if(!$array) {
  448. $array = array();
  449. }
  450. if($path) {
  451. $array[$behavior] = $path;
  452. }else{
  453. $array[] = $behavior;
  454. }
  455. C('tags.'.$tag,$array);
  456. }
  457. /**
  458. * Perform an action
  459. * @param string $name Behavior name
  460. * @param Mixed $params Transmission parameters
  461. * @return void
  462. */
  463. function B($name, &$params=NULL) {
  464. $class = $name.'Behavior';
  465. if(APP_DEBUG) {
  466. G('behaviorStart');
  467. }
  468. $behavior = new $class();
  469. $behavior->run($params);
  470. if(APP_DEBUG) { // Record the behavior of execution log
  471. G('behaviorEnd');
  472. trace('Run '.$name.' Behavior [ RunTime:'.G('behaviorStart','behaviorEnd',6).'s ]','','INFO');
  473. }
  474. }
  475. /**
  476. * Removing whitespace and comments in the code
  477. * @param string $content Code Contents
  478. * @return string
  479. */
  480. function strip_whitespace($content) {
  481. $stripStr = '';
  482. //Php source code analysis
  483. $tokens = token_get_all($content);
  484. $last_space = false;
  485. for ($i = 0, $j = count($tokens); $i < $j; $i++) {
  486. if (is_string($tokens[$i])) {
  487. $last_space = false;
  488. $stripStr .= $tokens[$i];
  489. } else {
  490. switch ($tokens[$i][0]) {
  491. //Filter various PHP comments
  492. case T_COMMENT:
  493. case T_DOC_COMMENT:
  494. break;
  495. //Filter spaces
  496. case T_WHITESPACE:
  497. if (!$last_space) {
  498. $stripStr .= ' ';
  499. $last_space = true;
  500. }
  501. break;
  502. case T_START_HEREDOC:
  503. $stripStr .= "<<<SEN\n";
  504. break;
  505. case T_END_HEREDOC:
  506. $stripStr .= "SEN;\n";
  507. for($k = $i+1; $k < $j; $k++) {
  508. if(is_string($tokens[$k]) && $tokens[$k] == ';') {
  509. $i = $k;
  510. break;
  511. } else if($tokens[$k][0] == T_CLOSE_TAG) {
  512. break;
  513. }
  514. }
  515. break;
  516. default:
  517. $last_space = false;
  518. $stripStr .= $tokens[$i][1];
  519. }
  520. }
  521. }
  522. return $stripStr;
  523. }
  524. //[RUNTIME]
  525. // Compiled file
  526. function compile($filename) {
  527. $content = file_get_contents($filename);
  528. // Replace pre-compiler directives
  529. $content = preg_replace('/\/\/\[RUNTIME\](.*?)\/\/\[\/RUNTIME\]/s', '', $content);
  530. $content = substr(trim($content), 5);
  531. if ('?>' == substr($content, -2))
  532. $content = substr($content, 0, -2);
  533. return $content;
  534. }
  535. // According to the array generates constant definitions
  536. function array_define($array,$check=true) {
  537. $content = "\n";
  538. foreach ($array as $key => $val) {
  539. $key = strtoupper($key);
  540. if($check) $content .= 'defined(\'' . $key . '\') or ';
  541. if (is_int($val) || is_float($val)) {
  542. $content .= "define('" . $key . "'," . $val . ');';
  543. } elseif (is_bool($val)) {
  544. $val = ($val) ? 'true' : 'false';
  545. $content .= "define('" . $key . "'," . $val . ');';
  546. } elseif (is_string($val)) {
  547. $content .= "define('" . $key . "','" . addslashes($val) . "');";
  548. }
  549. $content .= "\n";
  550. }
  551. return $content;
  552. }
  553. //[/RUNTIME]
  554. /**
  555. * Trace records to add and get the page
  556. * @param string $value Variable
  557. * @param string $label Tag
  558. * @param string $level Log Level
  559. * @param boolean $record Whether logging
  560. * @return void
  561. */
  562. function trace($value='[sen]',$label='',$level='DEBUG',$record=false) {
  563. static $_trace = array();
  564. if('[sen]' === $value){ // Gets the trace information
  565. return $_trace;
  566. }else{
  567. $info = ($label?$label.':':'').print_r($value,true);
  568. if('ERR' == $level && C('TRACE_EXCEPTION')) {// throw an exception
  569. throw_exception($info);
  570. }
  571. $level = strtoupper($level);
  572. if(!isset($_trace[$level])) {
  573. $_trace[$level] = array();
  574. }
  575. $_trace[$level][] = $info;
  576. if((defined('IS_AJAX') && IS_AJAX) || !C('SHOW_PAGE_TRACE') || $record) {
  577. Log::record($info,$level,$record);
  578. }
  579. }
  580. }