PageRenderTime 47ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/jsLinb4.0/phpLinb/linb.php

http://linb.googlecode.com/
PHP | 482 lines | 280 code | 37 blank | 165 comment | 40 complexity | a238a3bd2181e99f3818bffe79b48e3b MD5 | raw file
  1. <?php
  2. if(function_exists('date_default_timezone_set')){
  3. date_default_timezone_set('UTC');
  4. }
  5. /*
  6. * phpLinb 1.2
  7. * Copyright(c) 2008 Yingbo Li(linb.net, linb.net[at]gmail.com).
  8. * GPL3 (http://www.opensource.org/licenses/gpl-3.0.html) licenses.
  9. */
  10. /**
  11. * __autoload class
  12. * @author rambolee <linb.net@gmail.com>
  13. **/
  14. function __autoload($class){
  15. try{
  16. $path = LINB::$DIR_LINB.LINB::$DIR_CLASS.str_replace('_', DIRECTORY_SEPARATOR, str_replace('.', DIRECTORY_SEPARATOR, $class)).'.php';
  17. if(!file_exists($path)){
  18. $path = LINB::$DIR_APP.LINB::$DIR_CLASS.str_replace('_', DIRECTORY_SEPARATOR, str_replace('.', DIRECTORY_SEPARATOR, $class)).'.php';
  19. }
  20. if(file_exists($path)){
  21. include_once($path);
  22. } else {
  23. return eval("
  24. class $class{
  25. function __construct(\$a=0, \$b=0, \$c=0, \$d=0, \$e=0, \$f=0, \$g=0, \$h=0, \$i=0){
  26. throw new LINB_E('Class $class could not be found.');
  27. }
  28. }
  29. ");
  30. }
  31. }catch (LINB_E $e){
  32. throw new LINB_E($e->getMessage(), $e->getCode());
  33. }
  34. }
  35. /**
  36. * Exception class for LINB
  37. * @author rambolee <linb.net@gmail.com>
  38. **/
  39. class LINB_E extends Exception
  40. {
  41. /**
  42. * constructor
  43. *
  44. * @param string $message
  45. * @param int $code
  46. *
  47. * @return LINB_E
  48. */
  49. function __construct ($message = '', $code = 0, $file = '', $line = -1) {
  50. parent::__construct($message, $code);
  51. }
  52. function _handle_exception(Exception $e) {
  53. LINB::echoException('001', $e);
  54. }
  55. function _handle_error($errno, $errstr, $errfile, $errline) {
  56. LINB::echoException('001', $errstr, $errfile, $errline);
  57. }
  58. };
  59. $err = new LINB_E();
  60. set_error_handler (array ($err, '_handle_error'));
  61. set_exception_handler(array($err, "_handle_exception"));
  62. unset($err);
  63. /**
  64. * LINB base class
  65. *
  66. * @author rambolee <linb.net@gmail.com>
  67. **/
  68. class LINB
  69. {
  70. /**
  71. * logic unit abstrct class name
  72. */
  73. const UNIT = "Unit";
  74. /**
  75. * request data symbol: callback
  76. */
  77. const SYM_CALLBACK = "callback";
  78. /**
  79. * request data symbol: hash
  80. */
  81. const SYM_HASH = "hash";
  82. /**
  83. * request data symbol: data
  84. * for exception in __autoload
  85. */
  86. const SYM_DATA = "data";
  87. /**
  88. * request data symbol: error
  89. */
  90. const SYM_ERR = "error";
  91. /**
  92. * request data symbol: error
  93. */
  94. const SYM_ID = "id";
  95. const SYM_MESSAGE = "message";
  96. /**
  97. * request data sub symbol: key
  98. *
  99. */
  100. const SYM_KEY = "key";
  101. /**
  102. * request data sub symbol: parameter
  103. *
  104. */
  105. const SYM_PARA = "para";
  106. const MAX_LEN = 800;
  107. /**
  108. * Request data backup
  109. *
  110. */
  111. public static $data;
  112. /**
  113. * for switch debug
  114. *
  115. */
  116. public static $debug;
  117. /**
  118. * The path of LINB.PHP
  119. */
  120. public static $DIR_LINB;
  121. /**
  122. * path for main app
  123. */
  124. public static $DIR_APP;
  125. /**
  126. * The root path of class files
  127. */
  128. public static $DIR_CLASS;
  129. /**
  130. * JSON object
  131. */
  132. public static $json;
  133. /**
  134. * object hash table for straight call
  135. */
  136. private static $H = array();
  137. /**
  138. * type strict
  139. *
  140. * @param string $type
  141. * @param mix $v
  142. * @param mix $default
  143. * @return mix
  144. */
  145. public static function toStrict($type, $v, $default){
  146. $map = array(
  147. 'string' => array('is_string',''),
  148. 'integer' => array('is_integer',0),
  149. 'double' => array('is_float',0.0),
  150. 'boolean' => array('is_bool',false),
  151. 'array' => array('is_array',array()),
  152. 'object' => array('is_object', new stdClass())
  153. );
  154. if(!in_array($type, array_keys($map))){
  155. throw new LINB_E('$type is not a valid type.');
  156. }
  157. $r=$map[$type][1];
  158. if(isset($v) || $map[$type][0]($v)){
  159. $r=$v;
  160. }else{
  161. if(isset($default) || $map[$type][0]($default)){
  162. $r = $default;
  163. }
  164. }
  165. return $r;
  166. }
  167. public static function toType($v, $type){
  168. switch ($type){
  169. case 'string' :
  170. return (string)$v;
  171. case 'integer' :
  172. return (integer)$v;
  173. case 'double' :
  174. return (double)$v;
  175. case 'boolean' :
  176. return (boolean)$v;
  177. case 'array' :
  178. return (array)$v;
  179. case 'object' :
  180. return (object)$v;
  181. default:
  182. throw new LINB_E('No such type: $type!');
  183. }
  184. }
  185. /**
  186. * check arguemnts
  187. *
  188. * @param arary $h
  189. * @param array $a
  190. * array(
  191. * 'string' => array(
  192. * 'id' => NULL,
  193. * 'action' => ''
  194. * )
  195. * )
  196. */
  197. public static function checkArgs(&$h, $a){
  198. if(is_object($h)){
  199. $o = (array)$h;
  200. }else{
  201. $o = & $h;
  202. }
  203. foreach ($a as $k=>$v){
  204. foreach ($v as $k2=>$v2){
  205. if(is_null($v2)){
  206. if(isset($o[$k2])){
  207. if(gettype($o[$k2]) != $k)
  208. $o[$k2] = self::toType($o[$k2], $k);
  209. }else
  210. throw new LINB_E($k2." must be specified!");
  211. }else{
  212. $o[$k2] = self::toStrict($k, isset($o[$k2])?$o[$k2]:NULL, $v2 );
  213. }
  214. }
  215. }
  216. if(is_object($h)){
  217. foreach ($o as $k=>$v){
  218. $h->$k = $v;
  219. }
  220. }
  221. }
  222. /**
  223. * Parse a template to string
  224. *
  225. * @param string $template
  226. * tag: {tag}
  227. * or
  228. * tag pairs: {tag} string... {/tag}
  229. * @param array $data
  230. * array(
  231. * 'a' => 'a',
  232. * array(
  233. * array('i'=>'i','j1'=>'j1'),
  234. * array('i'=>'i','j2'=>'j2'),
  235. * array('i'=>'i','j3'=>'j3')
  236. * )
  237. * )
  238. * @return string
  239. */
  240. public static function parseTemplate($template, $data, $tag_l = '{', $tag_r = '}'){
  241. $str = $template;
  242. if(is_object($data))
  243. $data=(array)$data;
  244. foreach ($data as $key => $val){
  245. if ( ! is_array($val)){
  246. $str = str_replace($tag_l.$key.$tag_r, $val, $str);
  247. }else{
  248. if (preg_match("|".$tag_l.$key.$tag_r."(.+)".$tag_l.'/'.$key.$tag_r."|s", $template, $match)) {
  249. $str2 = '';
  250. foreach ($val as $item){
  251. $str2 .= LINB::parseTemplate($match['1'], $item);
  252. }
  253. $str = str_replace($match['0'], $str2, $str);
  254. }
  255. }
  256. }
  257. return $str;
  258. }
  259. /**
  260. * Staight call
  261. *
  262. * @param string $key
  263. * @return object
  264. */
  265. public static function SC($key, $new=false){
  266. if ($new || !isset(self::$H[$key])) {
  267. try{
  268. if ($new)
  269. return new $key();
  270. else
  271. self::$H[$key] = new $key();
  272. }catch(LINB_E $e){
  273. throw $e;
  274. }
  275. }
  276. return self::$H[$key];
  277. }
  278. /**
  279. * stimulate
  280. *
  281. * @param object $hash
  282. * @return object
  283. */
  284. public static function stimulate(&$hash){
  285. $key = self::SYM_KEY;
  286. $para = self::SYM_PARA;
  287. if(!is_object($hash)){ throw new LINB_E('Input data format error!');}
  288. if(!isset($hash->$key)){ throw new LINB_E('Input data must include key!');}
  289. $key = $hash->$key;
  290. $o = self::SC($key);
  291. if(is_subclass_of($o,self::UNIT)){
  292. return $o->stimulate($hash->$para);
  293. }else{ throw new LINB_E('$key is not a substantial class of Unit!'); }
  294. }
  295. /**
  296. * handle http post or get request
  297. * html get/post : key=xxx&para={...}
  298. * cgi get/pos :{key:xxx,para:{...}}
  299. * there must be a 'key' included.
  300. *
  301. */
  302. public static function handler(){
  303. try{
  304. $httpdata=new stdClass;
  305. $data = self::SYM_DATA;
  306. $para = self::SYM_PARA;
  307. //"post" request
  308. //post a=b$c=d
  309. if(count($_POST)>0){
  310. foreach ($_POST as $k=>$v)
  311. $httpdata->$k = get_magic_quotes_gpc()?stripslashes($v):$v;
  312. //post {a:'b',c:'d'}
  313. //or xmlhttp post
  314. }else{
  315. //get string post next
  316. $request = file_get_contents('php://input');
  317. if($request){
  318. $request = LINB::$json->decode($request);
  319. foreach ($request as $k=>$v)
  320. $httpdata->$k = is_string($v)?get_magic_quotes_gpc()?stripslashes($v):$v:$v;
  321. }
  322. }
  323. //"get" request
  324. $request = $_SERVER['QUERY_STRING'];
  325. //get ?a=b$c=d
  326. if($request){
  327. if(strstr($request,'=')!==false){
  328. foreach ($_GET as $k=>$v)
  329. $httpdata->$k = get_magic_quotes_gpc()?stripslashes($v):$v;
  330. //get ?{a:'b',c:'d'}
  331. }else{
  332. $request = LINB::$json->decode(rawurldecode($request));
  333. foreach ($request as $k=>$v)
  334. $httpdata->$k = is_string($v)?get_magic_quotes_gpc()?stripslashes($v):$v:$v;
  335. }
  336. }
  337. if($_SERVER['QUERY_STRING']){
  338. header ("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
  339. header ("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
  340. header ("Cache-Control: no-cache, must-revalidate");
  341. header ("Pragma: no-cache");
  342. }
  343. if(isset($httpdata->$para)){
  344. if(is_string($httpdata->$para))
  345. $httpdata->$para = LINB::$json->decode($httpdata->$para);
  346. // for __autoload
  347. LINB::$data = &$httpdata;
  348. $d = self::stimulate($httpdata);
  349. if(isset($d))
  350. echo LINB::formatResponse($d);
  351. }
  352. }catch(LINB_E $e){
  353. throw new LINB_E($e->getMessage(), $e->getCode());
  354. }
  355. }
  356. public static function formatResponse($d, $ok=true){
  357. $data = self::SYM_DATA;
  358. $hash = self::SYM_HASH ;
  359. $callback = self::SYM_CALLBACK;
  360. $err = self::SYM_ERR;
  361. $key = self::SYM_KEY;
  362. $para = self::SYM_PARA;
  363. $httpdata = &LINB::$data;
  364. if(isset($httpdata->$callback))
  365. $cb=$httpdata->$callback;
  366. unset($httpdata->$key);
  367. unset($httpdata->$para);
  368. unset($httpdata->$callback);
  369. if($ok)
  370. $httpdata->$data = $d;
  371. else
  372. $httpdata->$err = $d;
  373. $output=LINB::$json->encode($httpdata);
  374. //use script tag
  375. if(isset($cb)){
  376. if($cb=="window.name"){
  377. $output="<script type='text' id='json'>".$output."</script><script type='text/javascript'>window.name=document.getElementById('json').innerHTML;</script>";
  378. }else{
  379. $output = $cb.'('.$output.')';
  380. }
  381. }
  382. return $output;
  383. }
  384. public static function echoException($eid, $e, $file='', $line=-1){
  385. $id = LINB::SYM_ID;
  386. $msg = LINB::SYM_MESSAGE;
  387. if($e instanceof Exception){
  388. $file = $e->getFile();
  389. $line = $e->getLine();
  390. $e = $e->getMessage();
  391. }
  392. if(LINB::$debug)
  393. $e = $e." at ".$file."(".$line.")";
  394. $d = array( $id => $eid, $msg => $e);
  395. echo LINB::formatResponse($d,false );
  396. //only the first error will return to browser
  397. exit();
  398. }
  399. }
  400. /**
  401. * logic unit abstrct class
  402. *
  403. */
  404. abstract class Unit
  405. {
  406. /**
  407. * for logic unit interface
  408. *
  409. * @param class $hash
  410. */
  411. abstract public function stimulate(&$hash);
  412. }
  413. /**
  414. * shortcut for LINB::SC
  415. *
  416. * @param string $key
  417. * @return object
  418. */
  419. function SC($key, $new=false){
  420. return LINB::SC($key, $new);
  421. }
  422. ///////////////
  423. /////running functions
  424. ///////////////
  425. // ini the object of LINB
  426. LINB::$debug = true;
  427. LINB::$DIR_LINB = dirname(__FILE__).DIRECTORY_SEPARATOR;
  428. LINB::$DIR_APP = realpath('.').DIRECTORY_SEPARATOR;
  429. LINB::$DIR_CLASS = 'phpClass'.DIRECTORY_SEPARATOR;
  430. //for php 5.22 json enabled
  431. if(function_exists("json_encode")){
  432. class PHPJSON{
  433. function encode($var){
  434. return json_encode($var);
  435. }
  436. function decode($var){
  437. return json_decode($var);
  438. }
  439. }
  440. LINB::$json = new PHPJSON;
  441. }else
  442. LINB::$json = new JSON;
  443. // handle http request
  444. LINB::handler();
  445. ?>