Просмотр файла pear.php

Размер файла: 13.38Kb
  1. <?php
  2. define('PEAR_ERROR_RETURN', 1);
  3. define('PEAR_ERROR_PRINT', 2);
  4. define('PEAR_ERROR_TRIGGER', 4);
  5. define('PEAR_ERROR_DIE', 8);
  6. define('PEAR_ERROR_CALLBACK', 16);
  7. define('PEAR_ERROR_EXCEPTION', 32);
  8. define('PEAR_ZE2', (function_exists('version_compare') &&
  9. version_compare(zend_version(), "2-dev", "ge")));
  10. if (substr(PHP_OS, 0, 3) == 'WIN') {
  11. define('OS_WINDOWS', true);
  12. define('OS_UNIX', false);
  13. define('PEAR_OS', 'Windows');
  14. } else {
  15. define('OS_WINDOWS', false);
  16. define('OS_UNIX', true);
  17. define('PEAR_OS', 'Unix'); }
  18. if (!defined('PATH_SEPARATOR')) {
  19. if (OS_WINDOWS) {
  20. define('PATH_SEPARATOR', ';');
  21. } else {
  22. define('PATH_SEPARATOR', ':');
  23. }
  24. }
  25. $GLOBALS['_PEAR_default_error_mode'] = PEAR_ERROR_RETURN;
  26. $GLOBALS['_PEAR_default_error_options'] = E_USER_NOTICE;
  27. $GLOBALS['_PEAR_destructor_object_list'] = array();
  28. $GLOBALS['_PEAR_shutdown_funcs'] = array();
  29. $GLOBALS['_PEAR_error_handler_stack'] = array();
  30. @ini_set('track_errors', true);
  31. class PEAR
  32. {
  33. var $_debug = false;
  34. var $_default_error_mode = null;
  35. var $_default_error_options = null;
  36. var $_default_error_handler = '';
  37. var $_error_class = 'PEAR_Error';
  38. var $_expected_errors = array();
  39. function PEAR($error_class = null)
  40. {
  41. $classname = strtolower(get_class($this));
  42. if ($this->_debug) {
  43. print "PEAR constructor called, class=$classname\n";
  44. }
  45. if ($error_class !== null) {
  46. $this->_error_class = $error_class;
  47. }
  48. while ($classname && strcasecmp($classname, "pear")) {
  49. $destructor = "_$classname";
  50. if (method_exists($this, $destructor)) {
  51. global $_PEAR_destructor_object_list;
  52. $_PEAR_destructor_object_list[] = &$this;
  53. if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) {
  54. register_shutdown_function("_PEAR_call_destructors");
  55. $GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true;
  56. }
  57. break;
  58. } else {
  59. $classname = get_parent_class($classname);
  60. }
  61. }
  62. }
  63. function _PEAR() {
  64. if ($this->_debug) {
  65. printf("PEAR destructor called, class=%s\n", strtolower(get_class($this)));
  66. }
  67. }
  68. function &getStaticProperty($class, $var)
  69. {
  70. static $properties;
  71. if (!isset($properties[$class])) {
  72. $properties[$class] = array();
  73. }
  74. if (!array_key_exists($var, $properties[$class])) {
  75. $properties[$class][$var] = null;
  76. }
  77. return $properties[$class][$var];
  78. }
  79. function registerShutdownFunc($func, $args = array())
  80. {
  81. if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) {
  82. register_shutdown_function("_PEAR_call_destructors");
  83. $GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true;
  84. }
  85. $GLOBALS['_PEAR_shutdown_funcs'][] = array($func, $args);
  86. }
  87. function isError($data, $code = null)
  88. {
  89. if (is_a($data, 'PEAR_Error')) {
  90. if (is_null($code)) {
  91. return true;
  92. } elseif (is_string($code)) {
  93. return $data->getMessage() == $code;
  94. } else {
  95. return $data->getCode() == $code;
  96. }
  97. }
  98. return false;
  99. }
  100. function setErrorHandling($mode = null, $options = null)
  101. {
  102. if (isset($this) && is_a($this, 'PEAR')) {
  103. $setmode = &$this->_default_error_mode;
  104. $setoptions = &$this->_default_error_options;
  105. } else {
  106. $setmode = &$GLOBALS['_PEAR_default_error_mode'];
  107. $setoptions = &$GLOBALS['_PEAR_default_error_options'];
  108. }
  109. switch ($mode) {
  110. case PEAR_ERROR_EXCEPTION:
  111. case PEAR_ERROR_RETURN:
  112. case PEAR_ERROR_PRINT:
  113. case PEAR_ERROR_TRIGGER:
  114. case PEAR_ERROR_DIE:
  115. case null:
  116. $setmode = $mode;
  117. $setoptions = $options;
  118. break;
  119. case PEAR_ERROR_CALLBACK:
  120. $setmode = $mode;
  121. if (is_callable($options)) {
  122. $setoptions = $options;
  123. } else {
  124. trigger_error("invalid error callback", E_USER_WARNING);
  125. }
  126. break;
  127. default:
  128. trigger_error("invalid error mode", E_USER_WARNING);
  129. break;
  130. }
  131. }
  132. function expectError($code = '*')
  133. {
  134. if (is_array($code)) {
  135. array_push($this->_expected_errors, $code);
  136. } else {
  137. array_push($this->_expected_errors, array($code));
  138. }
  139. return sizeof($this->_expected_errors);
  140. }
  141. function popExpect()
  142. {
  143. return array_pop($this->_expected_errors);
  144. }
  145. function _checkDelExpect($error_code)
  146. {
  147. $deleted = false;
  148. foreach ($this->_expected_errors AS $key => $error_array) {
  149. if (in_array($error_code, $error_array)) {
  150. unset($this->_expected_errors[$key][array_search($error_code, $error_array)]);
  151. $deleted = true;
  152. }
  153. if (0 == count($this->_expected_errors[$key])) {
  154. unset($this->_expected_errors[$key]);
  155. }
  156. }
  157. return $deleted;
  158. }
  159. function delExpect($error_code)
  160. {
  161. $deleted = false;
  162. if ((is_array($error_code) && (0 != count($error_code)))) {
  163. foreach($error_code as $key => $error) {
  164. if ($this->_checkDelExpect($error)) {
  165. $deleted = true;
  166. } else {
  167. $deleted = false;
  168. }
  169. }
  170. return $deleted ? true : PEAR::raiseError("The expected error you submitted does not exist"); } elseif (!empty($error_code)) {
  171. if ($this->_checkDelExpect($error_code)) {
  172. return true;
  173. } else {
  174. return PEAR::raiseError("The expected error you submitted does not exist"); }
  175. } else {
  176. return PEAR::raiseError("The expected error you submitted is empty"); }
  177. }
  178. function &raiseError($message = null,
  179. $code = null,
  180. $mode = null,
  181. $options = null,
  182. $userinfo = null,
  183. $error_class = null,
  184. $skipmsg = false)
  185. {
  186. if (is_object($message)) {
  187. $code = $message->getCode();
  188. $userinfo = $message->getUserInfo();
  189. $error_class = $message->getType();
  190. $message->error_message_prefix = '';
  191. $message = $message->getMessage();
  192. }
  193. if (isset($this) && isset($this->_expected_errors) && sizeof($this->_expected_errors) > 0 && sizeof($exp = end($this->_expected_errors))) {
  194. if ($exp[0] == "*" ||
  195. (is_int(reset($exp)) && in_array($code, $exp)) ||
  196. (is_string(reset($exp)) && in_array($message, $exp))) {
  197. $mode = PEAR_ERROR_RETURN;
  198. }
  199. }
  200. if ($mode === null) {
  201. if (isset($this) && isset($this->_default_error_mode)) {
  202. $mode = $this->_default_error_mode;
  203. $options = $this->_default_error_options;
  204. } elseif (isset($GLOBALS['_PEAR_default_error_mode'])) {
  205. $mode = $GLOBALS['_PEAR_default_error_mode'];
  206. $options = $GLOBALS['_PEAR_default_error_options'];
  207. }
  208. }
  209. if ($error_class !== null) {
  210. $ec = $error_class;
  211. } elseif (isset($this) && isset($this->_error_class)) {
  212. $ec = $this->_error_class;
  213. } else {
  214. $ec = 'PEAR_Error';
  215. }
  216. if (intval(PHP_VERSION) < 5) {
  217. include 'PEAR/FixPHP5PEARWarnings.php';
  218. return $a;
  219. }
  220. if ($skipmsg) {
  221. $a = new $ec($code, $mode, $options, $userinfo);
  222. } else {
  223. $a = new $ec($message, $code, $mode, $options, $userinfo);
  224. }
  225. return $a;
  226. }
  227. function &throwError($message = null,
  228. $code = null,
  229. $userinfo = null)
  230. {
  231. if (isset($this) && is_a($this, 'PEAR')) {
  232. $a = &$this->raiseError($message, $code, null, null, $userinfo);
  233. return $a;
  234. } else {
  235. $a = &PEAR::raiseError($message, $code, null, null, $userinfo);
  236. return $a;
  237. }
  238. }
  239. function staticPushErrorHandling($mode, $options = null)
  240. {
  241. $stack = &$GLOBALS['_PEAR_error_handler_stack'];
  242. $def_mode = &$GLOBALS['_PEAR_default_error_mode'];
  243. $def_options = &$GLOBALS['_PEAR_default_error_options'];
  244. $stack[] = array($def_mode, $def_options);
  245. switch ($mode) {
  246. case PEAR_ERROR_EXCEPTION:
  247. case PEAR_ERROR_RETURN:
  248. case PEAR_ERROR_PRINT:
  249. case PEAR_ERROR_TRIGGER:
  250. case PEAR_ERROR_DIE:
  251. case null:
  252. $def_mode = $mode;
  253. $def_options = $options;
  254. break;
  255. case PEAR_ERROR_CALLBACK:
  256. $def_mode = $mode;
  257. if (is_callable($options)) {
  258. $def_options = $options;
  259. } else {
  260. trigger_error("invalid error callback", E_USER_WARNING);
  261. }
  262. break;
  263. default:
  264. trigger_error("invalid error mode", E_USER_WARNING);
  265. break;
  266. }
  267. $stack[] = array($mode, $options);
  268. return true;
  269. }
  270. function staticPopErrorHandling()
  271. {
  272. $stack = &$GLOBALS['_PEAR_error_handler_stack'];
  273. $setmode = &$GLOBALS['_PEAR_default_error_mode'];
  274. $setoptions = &$GLOBALS['_PEAR_default_error_options'];
  275. array_pop($stack);
  276. list($mode, $options) = $stack[sizeof($stack) - 1];
  277. array_pop($stack);
  278. switch ($mode) {
  279. case PEAR_ERROR_EXCEPTION:
  280. case PEAR_ERROR_RETURN:
  281. case PEAR_ERROR_PRINT:
  282. case PEAR_ERROR_TRIGGER:
  283. case PEAR_ERROR_DIE:
  284. case null:
  285. $setmode = $mode;
  286. $setoptions = $options;
  287. break;
  288. case PEAR_ERROR_CALLBACK:
  289. $setmode = $mode;
  290. if (is_callable($options)) {
  291. $setoptions = $options;
  292. } else {
  293. trigger_error("invalid error callback", E_USER_WARNING);
  294. }
  295. break;
  296. default:
  297. trigger_error("invalid error mode", E_USER_WARNING);
  298. break;
  299. }
  300. return true;
  301. }
  302. function pushErrorHandling($mode, $options = null)
  303. {
  304. $stack = &$GLOBALS['_PEAR_error_handler_stack'];
  305. if (isset($this) && is_a($this, 'PEAR')) {
  306. $def_mode = &$this->_default_error_mode;
  307. $def_options = &$this->_default_error_options;
  308. } else {
  309. $def_mode = &$GLOBALS['_PEAR_default_error_mode'];
  310. $def_options = &$GLOBALS['_PEAR_default_error_options'];
  311. }
  312. $stack[] = array($def_mode, $def_options);
  313. if (isset($this) && is_a($this, 'PEAR')) {
  314. $this->setErrorHandling($mode, $options);
  315. } else {
  316. PEAR::setErrorHandling($mode, $options);
  317. }
  318. $stack[] = array($mode, $options);
  319. return true;
  320. }
  321. function popErrorHandling()
  322. {
  323. $stack = &$GLOBALS['_PEAR_error_handler_stack'];
  324. array_pop($stack);
  325. list($mode, $options) = $stack[sizeof($stack) - 1];
  326. array_pop($stack);
  327. if (isset($this) && is_a($this, 'PEAR')) {
  328. $this->setErrorHandling($mode, $options);
  329. } else {
  330. PEAR::setErrorHandling($mode, $options);
  331. }
  332. return true;
  333. }
  334. function loadExtension($ext)
  335. {
  336. if (!extension_loaded($ext)) {
  337. if ((ini_get('enable_dl') != 1) || (ini_get('safe_mode') == 1)) {
  338. return false;
  339. }
  340. if (OS_WINDOWS) {
  341. $suffix = '.dll';
  342. } elseif (PHP_OS == 'HP-UX') {
  343. $suffix = '.sl';
  344. } elseif (PHP_OS == 'AIX') {
  345. $suffix = '.a';
  346. } elseif (PHP_OS == 'OSX') {
  347. $suffix = '.bundle';
  348. } else {
  349. $suffix = '.so';
  350. }
  351. return @dl('php_'.$ext.$suffix) || @dl($ext.$suffix);
  352. }
  353. return true;
  354. }
  355. }
  356. function _PEAR_call_destructors()
  357. {
  358. global $_PEAR_destructor_object_list;
  359. if (is_array($_PEAR_destructor_object_list) &&
  360. sizeof($_PEAR_destructor_object_list))
  361. {
  362. reset($_PEAR_destructor_object_list);
  363. if (PEAR::getStaticProperty('PEAR', 'destructlifo')) {
  364. $_PEAR_destructor_object_list = array_reverse($_PEAR_destructor_object_list);
  365. }
  366. while (list($k, $objref) = each($_PEAR_destructor_object_list)) {
  367. $classname = get_class($objref);
  368. while ($classname) {
  369. $destructor = "_$classname";
  370. if (method_exists($objref, $destructor)) {
  371. $objref->$destructor();
  372. break;
  373. } else {
  374. $classname = get_parent_class($classname);
  375. }
  376. }
  377. }
  378. $_PEAR_destructor_object_list = array();
  379. }
  380. if (is_array($GLOBALS['_PEAR_shutdown_funcs']) AND !empty($GLOBALS['_PEAR_shutdown_funcs'])) {
  381. foreach ($GLOBALS['_PEAR_shutdown_funcs'] as $value) {
  382. call_user_func_array($value[0], $value[1]);
  383. }
  384. }
  385. }
  386. class PEAR_Error
  387. {
  388. var $error_message_prefix = '';
  389. var $mode = PEAR_ERROR_RETURN;
  390. var $level = E_USER_NOTICE;
  391. var $code = -1;
  392. var $message = '';
  393. var $userinfo = '';
  394. var $backtrace = null;
  395. function PEAR_Error($message = 'unknown error', $code = null,
  396. $mode = null, $options = null, $userinfo = null)
  397. {
  398. if ($mode === null) {
  399. $mode = PEAR_ERROR_RETURN;
  400. }
  401. $this->message = $message;
  402. $this->code = $code;
  403. $this->mode = $mode;
  404. $this->userinfo = $userinfo;
  405. if (!PEAR::getStaticProperty('PEAR_Error', 'skiptrace')) {
  406. $this->backtrace = debug_backtrace();
  407. if (isset($this->backtrace[0]) && isset($this->backtrace[0]['object'])) {
  408. unset($this->backtrace[0]['object']);
  409. }
  410. }
  411. if ($mode & PEAR_ERROR_CALLBACK) {
  412. $this->level = E_USER_NOTICE;
  413. $this->callback = $options;
  414. } else {
  415. if ($options === null) {
  416. $options = E_USER_NOTICE;
  417. }
  418. $this->level = $options;
  419. $this->callback = null;
  420. }
  421. if ($this->mode & PEAR_ERROR_PRINT) {
  422. if (is_null($options) || is_int($options)) {
  423. $format = "%s";
  424. } else {
  425. $format = $options;
  426. }
  427. printf($format, $this->getMessage());
  428. }
  429. if ($this->mode & PEAR_ERROR_TRIGGER) {
  430. trigger_error($this->getMessage(), $this->level);
  431. }
  432. if ($this->mode & PEAR_ERROR_DIE) {
  433. $msg = $this->getMessage();
  434. if (is_null($options) || is_int($options)) {
  435. $format = "%s";
  436. if (substr($msg, -1) != "\n") {
  437. $msg .= "\n";
  438. }
  439. } else {
  440. $format = $options;
  441. }
  442. die(sprintf($format, $msg));
  443. }
  444. if ($this->mode & PEAR_ERROR_CALLBACK) {
  445. if (is_callable($this->callback)) {
  446. call_user_func($this->callback, $this);
  447. }
  448. }
  449. if ($this->mode & PEAR_ERROR_EXCEPTION) {
  450. trigger_error("PEAR_ERROR_EXCEPTION is obsolete, use class PEAR_Exception for exceptions", E_USER_WARNING);
  451. eval('$e = new Exception($this->message, $this->code);throw($e);');
  452. }
  453. }
  454. function getMode() {
  455. return $this->mode;
  456. }
  457. function getCallback() {
  458. return $this->callback;
  459. }
  460. function getMessage()
  461. {
  462. return ($this->error_message_prefix . $this->message);
  463. }
  464. function getCode()
  465. {
  466. return $this->code;
  467. }
  468. function getType()
  469. {
  470. return get_class($this);
  471. }
  472. function getUserInfo()
  473. {
  474. return $this->userinfo;
  475. }
  476. function getDebugInfo()
  477. {
  478. return $this->getUserInfo();
  479. }
  480. function getBacktrace($frame = null)
  481. {
  482. if (defined('PEAR_IGNORE_BACKTRACE')) {
  483. return null;
  484. }
  485. if ($frame === null) {
  486. return $this->backtrace;
  487. }
  488. return $this->backtrace[$frame];
  489. }
  490. function addUserInfo($info)
  491. {
  492. if (empty($this->userinfo)) {
  493. $this->userinfo = $info;
  494. } else {
  495. $this->userinfo .= " ** $info";
  496. }
  497. }
  498. function __toString()
  499. {
  500. return $this->getMessage();
  501. }
  502. function toString() {
  503. $modes = array();
  504. $levels = array(E_USER_NOTICE => 'notice',
  505. E_USER_WARNING => 'warning',
  506. E_USER_ERROR => 'error');
  507. if ($this->mode & PEAR_ERROR_CALLBACK) {
  508. if (is_array($this->callback)) {
  509. $callback = (is_object($this->callback[0]) ?
  510. strtolower(get_class($this->callback[0])) :
  511. $this->callback[0]) . '::' .
  512. $this->callback[1];
  513. } else {
  514. $callback = $this->callback;
  515. }
  516. return sprintf('[%s: message="%s" code=%d mode=callback '.
  517. 'callback=%s prefix="%s" info="%s"]',
  518. strtolower(get_class($this)), $this->message, $this->code,
  519. $callback, $this->error_message_prefix,
  520. $this->userinfo);
  521. }
  522. if ($this->mode & PEAR_ERROR_PRINT) {
  523. $modes[] = 'print';
  524. }
  525. if ($this->mode & PEAR_ERROR_TRIGGER) {
  526. $modes[] = 'trigger';
  527. }
  528. if ($this->mode & PEAR_ERROR_DIE) {
  529. $modes[] = 'die';
  530. }
  531. if ($this->mode & PEAR_ERROR_RETURN) {
  532. $modes[] = 'return';
  533. }
  534. return sprintf('[%s: message="%s" code=%d mode=%s level=%s '.
  535. 'prefix="%s" info="%s"]',
  536. strtolower(get_class($this)), $this->message, $this->code,
  537. implode("|", $modes), $levels[$this->level],
  538. $this->error_message_prefix,
  539. $this->userinfo);
  540. }
  541. }
  542. ?>