PEAR.php 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970
  1. <?php
  2. //
  3. // +----------------------------------------------------------------------+
  4. // | PEAR, the PHP Extension and Application Repository |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 1997-2004 The PHP Group |
  7. // +----------------------------------------------------------------------+
  8. // | This source file is subject to version 2.0 of the PHP license, |
  9. // | that is bundled with this package in the file LICENSE, and is |
  10. // | available through the world-wide-web at the following url: |
  11. // | http://www.php.net/license/3_0.txt. |
  12. // | If you did not receive a copy of the PHP license and are unable to |
  13. // | obtain it through the world-wide-web, please send a note to |
  14. // | license@php.net so we can mail you a copy immediately. |
  15. // +----------------------------------------------------------------------+
  16. // | Authors: Sterling Hughes <sterling@php.net> |
  17. // | Stig Bakken <ssb@php.net> |
  18. // | Tomas V.V.Cox <cox@idecnet.com> |
  19. // +----------------------------------------------------------------------+
  20. //
  21. // $Id: PEAR.php,v 1.77 2004/02/07 04:42:07 cellog Exp $
  22. //
  23. define('PEAR_ERROR_RETURN', 1);
  24. define('PEAR_ERROR_PRINT', 2);
  25. define('PEAR_ERROR_TRIGGER', 4);
  26. define('PEAR_ERROR_DIE', 8);
  27. define('PEAR_ERROR_CALLBACK', 16);
  28. define('PEAR_ERROR_EXCEPTION', 32);
  29. define('PEAR_ZE2', (function_exists('version_compare') &&
  30. version_compare(zend_version(), "2-dev", "ge")));
  31. if (substr(PHP_OS, 0, 3) == 'WIN') {
  32. define('OS_WINDOWS', true);
  33. define('OS_UNIX', false);
  34. define('PEAR_OS', 'Windows');
  35. } else {
  36. define('OS_WINDOWS', false);
  37. define('OS_UNIX', true);
  38. define('PEAR_OS', 'Unix'); // blatant assumption
  39. }
  40. // instant backwards compatibility
  41. if (!defined('PATH_SEPARATOR')) {
  42. if (OS_WINDOWS) {
  43. define('PATH_SEPARATOR', ';');
  44. } else {
  45. define('PATH_SEPARATOR', ':');
  46. }
  47. }
  48. $GLOBALS['_PEAR_default_error_mode'] = PEAR_ERROR_RETURN;
  49. $GLOBALS['_PEAR_default_error_options'] = E_USER_NOTICE;
  50. $GLOBALS['_PEAR_destructor_object_list'] = array();
  51. $GLOBALS['_PEAR_shutdown_funcs'] = array();
  52. $GLOBALS['_PEAR_error_handler_stack'] = array();
  53. ini_set('track_errors', true);
  54. /**
  55. * Base class for other PEAR classes. Provides rudimentary
  56. * emulation of destructors.
  57. *
  58. * If you want a destructor in your class, inherit PEAR and make a
  59. * destructor method called _yourclassname (same name as the
  60. * constructor, but with a "_" prefix). Also, in your constructor you
  61. * have to call the PEAR constructor: $this->PEAR();.
  62. * The destructor method will be called without parameters. Note that
  63. * at in some SAPI implementations (such as Apache), any output during
  64. * the request shutdown (in which destructors are called) seems to be
  65. * discarded. If you need to get any debug information from your
  66. * destructor, use error_log(), syslog() or something similar.
  67. *
  68. * IMPORTANT! To use the emulated destructors you need to create the
  69. * objects by reference: $obj =& new PEAR_child;
  70. *
  71. * @since PHP 4.0.2
  72. * @author Stig Bakken <ssb@php.net>
  73. * @see http://pear.php.net/manual/
  74. */
  75. class PEAR
  76. {
  77. // {{{ properties
  78. /**
  79. * Whether to enable internal debug messages.
  80. *
  81. * @var bool
  82. * @access private
  83. */
  84. var $_debug = false;
  85. /**
  86. * Default error mode for this object.
  87. *
  88. * @var int
  89. * @access private
  90. */
  91. var $_default_error_mode = null;
  92. /**
  93. * Default error options used for this object when error mode
  94. * is PEAR_ERROR_TRIGGER.
  95. *
  96. * @var int
  97. * @access private
  98. */
  99. var $_default_error_options = null;
  100. /**
  101. * Default error handler (callback) for this object, if error mode is
  102. * PEAR_ERROR_CALLBACK.
  103. *
  104. * @var string
  105. * @access private
  106. */
  107. var $_default_error_handler = '';
  108. /**
  109. * Which class to use for error objects.
  110. *
  111. * @var string
  112. * @access private
  113. */
  114. var $_error_class = 'PEAR_Error';
  115. /**
  116. * An array of expected errors.
  117. *
  118. * @var array
  119. * @access private
  120. */
  121. var $_expected_errors = array();
  122. // }}}
  123. // {{{ constructor
  124. /**
  125. * Constructor. Registers this object in
  126. * $_PEAR_destructor_object_list for destructor emulation if a
  127. * destructor object exists.
  128. *
  129. * @param string $error_class (optional) which class to use for
  130. * error objects, defaults to PEAR_Error.
  131. * @access public
  132. * @return void
  133. */
  134. function PEAR($error_class = null)
  135. {
  136. $classname = get_class($this);
  137. if ($this->_debug) {
  138. print "PEAR constructor called, class=$classname\n";
  139. }
  140. if ($error_class !== null) {
  141. $this->_error_class = $error_class;
  142. }
  143. while ($classname) {
  144. $destructor = "_$classname";
  145. if (method_exists($this, $destructor)) {
  146. global $_PEAR_destructor_object_list;
  147. $_PEAR_destructor_object_list[] = &$this;
  148. break;
  149. } else {
  150. $classname = get_parent_class($classname);
  151. }
  152. }
  153. }
  154. // }}}
  155. // {{{ destructor
  156. /**
  157. * Destructor (the emulated type of...). Does nothing right now,
  158. * but is included for forward compatibility, so subclass
  159. * destructors should always call it.
  160. *
  161. * See the note in the class desciption about output from
  162. * destructors.
  163. *
  164. * @access public
  165. * @return void
  166. */
  167. function _PEAR() {
  168. if ($this->_debug) {
  169. printf("PEAR destructor called, class=%s\n", get_class($this));
  170. }
  171. }
  172. // }}}
  173. // {{{ getStaticProperty()
  174. /**
  175. * If you have a class that's mostly/entirely static, and you need static
  176. * properties, you can use this method to simulate them. Eg. in your method(s)
  177. * do this: $myVar = &PEAR::getStaticProperty('myVar');
  178. * You MUST use a reference, or they will not persist!
  179. *
  180. * @access public
  181. * @param string $class The calling classname, to prevent clashes
  182. * @param string $var The variable to retrieve.
  183. * @return mixed A reference to the variable. If not set it will be
  184. * auto initialised to NULL.
  185. */
  186. function &getStaticProperty($class, $var)
  187. {
  188. static $properties;
  189. return $properties[$class][$var];
  190. }
  191. // }}}
  192. // {{{ registerShutdownFunc()
  193. /**
  194. * Use this function to register a shutdown method for static
  195. * classes.
  196. *
  197. * @access public
  198. * @param mixed $func The function name (or array of class/method) to call
  199. * @param mixed $args The arguments to pass to the function
  200. * @return void
  201. */
  202. function registerShutdownFunc($func, $args = array())
  203. {
  204. $GLOBALS['_PEAR_shutdown_funcs'][] = array($func, $args);
  205. }
  206. // }}}
  207. // {{{ isError()
  208. /**
  209. * Tell whether a value is a PEAR error.
  210. *
  211. * @param mixed $data the value to test
  212. * @param int $code if $data is an error object, return true
  213. * only if $code is a string and
  214. * $obj->getMessage() == $code or
  215. * $code is an integer and $obj->getCode() == $code
  216. * @access public
  217. * @return bool true if parameter is an error
  218. */
  219. function isError($data, $code = null)
  220. {
  221. if (is_a($data, 'PEAR_Error')) {
  222. if (is_null($code)) {
  223. return true;
  224. } elseif (is_string($code)) {
  225. return $data->getMessage() == $code;
  226. } else {
  227. return $data->getCode() == $code;
  228. }
  229. }
  230. return false;
  231. }
  232. // }}}
  233. // {{{ setErrorHandling()
  234. /**
  235. * Sets how errors generated by this object should be handled.
  236. * Can be invoked both in objects and statically. If called
  237. * statically, setErrorHandling sets the default behaviour for all
  238. * PEAR objects. If called in an object, setErrorHandling sets
  239. * the default behaviour for that object.
  240. *
  241. * @param int $mode
  242. * One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT,
  243. * PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE,
  244. * PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION.
  245. *
  246. * @param mixed $options
  247. * When $mode is PEAR_ERROR_TRIGGER, this is the error level (one
  248. * of E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR).
  249. *
  250. * When $mode is PEAR_ERROR_CALLBACK, this parameter is expected
  251. * to be the callback function or method. A callback
  252. * function is a string with the name of the function, a
  253. * callback method is an array of two elements: the element
  254. * at index 0 is the object, and the element at index 1 is
  255. * the name of the method to call in the object.
  256. *
  257. * When $mode is PEAR_ERROR_PRINT or PEAR_ERROR_DIE, this is
  258. * a printf format string used when printing the error
  259. * message.
  260. *
  261. * @access public
  262. * @return void
  263. * @see PEAR_ERROR_RETURN
  264. * @see PEAR_ERROR_PRINT
  265. * @see PEAR_ERROR_TRIGGER
  266. * @see PEAR_ERROR_DIE
  267. * @see PEAR_ERROR_CALLBACK
  268. * @see PEAR_ERROR_EXCEPTION
  269. *
  270. * @since PHP 4.0.5
  271. */
  272. function setErrorHandling($mode = null, $options = null)
  273. {
  274. if (isset($this) && is_a($this, 'PEAR')) {
  275. $setmode = &$this->_default_error_mode;
  276. $setoptions = &$this->_default_error_options;
  277. } else {
  278. $setmode = &$GLOBALS['_PEAR_default_error_mode'];
  279. $setoptions = &$GLOBALS['_PEAR_default_error_options'];
  280. }
  281. switch ($mode) {
  282. case PEAR_ERROR_RETURN:
  283. case PEAR_ERROR_PRINT:
  284. case PEAR_ERROR_TRIGGER:
  285. case PEAR_ERROR_DIE:
  286. case PEAR_ERROR_EXCEPTION:
  287. case null:
  288. $setmode = $mode;
  289. $setoptions = $options;
  290. break;
  291. case PEAR_ERROR_CALLBACK:
  292. $setmode = $mode;
  293. // class/object method callback
  294. if (is_callable($options)) {
  295. $setoptions = $options;
  296. } else {
  297. trigger_error("invalid error callback", E_USER_WARNING);
  298. }
  299. break;
  300. default:
  301. trigger_error("invalid error mode", E_USER_WARNING);
  302. break;
  303. }
  304. }
  305. // }}}
  306. // {{{ expectError()
  307. /**
  308. * This method is used to tell which errors you expect to get.
  309. * Expected errors are always returned with error mode
  310. * PEAR_ERROR_RETURN. Expected error codes are stored in a stack,
  311. * and this method pushes a new element onto it. The list of
  312. * expected errors are in effect until they are popped off the
  313. * stack with the popExpect() method.
  314. *
  315. * Note that this method can not be called statically
  316. *
  317. * @param mixed $code a single error code or an array of error codes to expect
  318. *
  319. * @return int the new depth of the "expected errors" stack
  320. * @access public
  321. */
  322. function expectError($code = '*')
  323. {
  324. if (is_array($code)) {
  325. array_push($this->_expected_errors, $code);
  326. } else {
  327. array_push($this->_expected_errors, array($code));
  328. }
  329. return sizeof($this->_expected_errors);
  330. }
  331. // }}}
  332. // {{{ popExpect()
  333. /**
  334. * This method pops one element off the expected error codes
  335. * stack.
  336. *
  337. * @return array the list of error codes that were popped
  338. */
  339. function popExpect()
  340. {
  341. return array_pop($this->_expected_errors);
  342. }
  343. // }}}
  344. // {{{ _checkDelExpect()
  345. /**
  346. * This method checks unsets an error code if available
  347. *
  348. * @param mixed error code
  349. * @return bool true if the error code was unset, false otherwise
  350. * @access private
  351. * @since PHP 4.3.0
  352. */
  353. function _checkDelExpect($error_code)
  354. {
  355. $deleted = false;
  356. foreach ($this->_expected_errors AS $key => $error_array) {
  357. if (in_array($error_code, $error_array)) {
  358. unset($this->_expected_errors[$key][array_search($error_code, $error_array)]);
  359. $deleted = true;
  360. }
  361. // clean up empty arrays
  362. if (0 == count($this->_expected_errors[$key])) {
  363. unset($this->_expected_errors[$key]);
  364. }
  365. }
  366. return $deleted;
  367. }
  368. // }}}
  369. // {{{ delExpect()
  370. /**
  371. * This method deletes all occurences of the specified element from
  372. * the expected error codes stack.
  373. *
  374. * @param mixed $error_code error code that should be deleted
  375. * @return mixed list of error codes that were deleted or error
  376. * @access public
  377. * @since PHP 4.3.0
  378. */
  379. function delExpect($error_code)
  380. {
  381. $deleted = false;
  382. if ((is_array($error_code) && (0 != count($error_code)))) {
  383. // $error_code is a non-empty array here;
  384. // we walk through it trying to unset all
  385. // values
  386. foreach($error_code as $key => $error) {
  387. if ($this->_checkDelExpect($error)) {
  388. $deleted = true;
  389. } else {
  390. $deleted = false;
  391. }
  392. }
  393. return $deleted ? true : PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME
  394. } elseif (!empty($error_code)) {
  395. // $error_code comes alone, trying to unset it
  396. if ($this->_checkDelExpect($error_code)) {
  397. return true;
  398. } else {
  399. return PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME
  400. }
  401. } else {
  402. // $error_code is empty
  403. return PEAR::raiseError("The expected error you submitted is empty"); // IMPROVE ME
  404. }
  405. }
  406. // }}}
  407. // {{{ raiseError()
  408. /**
  409. * This method is a wrapper that returns an instance of the
  410. * configured error class with this object's default error
  411. * handling applied. If the $mode and $options parameters are not
  412. * specified, the object's defaults are used.
  413. *
  414. * @param mixed $message a text error message or a PEAR error object
  415. *
  416. * @param int $code a numeric error code (it is up to your class
  417. * to define these if you want to use codes)
  418. *
  419. * @param int $mode One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT,
  420. * PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE,
  421. * PEAR_ERROR_CALLBACK, PEAR_ERROR_EXCEPTION.
  422. *
  423. * @param mixed $options If $mode is PEAR_ERROR_TRIGGER, this parameter
  424. * specifies the PHP-internal error level (one of
  425. * E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR).
  426. * If $mode is PEAR_ERROR_CALLBACK, this
  427. * parameter specifies the callback function or
  428. * method. In other error modes this parameter
  429. * is ignored.
  430. *
  431. * @param string $userinfo If you need to pass along for example debug
  432. * information, this parameter is meant for that.
  433. *
  434. * @param string $error_class The returned error object will be
  435. * instantiated from this class, if specified.
  436. *
  437. * @param bool $skipmsg If true, raiseError will only pass error codes,
  438. * the error message parameter will be dropped.
  439. *
  440. * @access public
  441. * @return object a PEAR error object
  442. * @see PEAR::setErrorHandling
  443. * @since PHP 4.0.5
  444. */
  445. function raiseError($message = null,
  446. $code = null,
  447. $mode = null,
  448. $options = null,
  449. $userinfo = null,
  450. $error_class = null,
  451. $skipmsg = false)
  452. {
  453. // The error is yet a PEAR error object
  454. if (is_object($message)) {
  455. $code = $message->getCode();
  456. $userinfo = $message->getUserInfo();
  457. $error_class = $message->getType();
  458. $message->error_message_prefix = '';
  459. $message = $message->getMessage();
  460. }
  461. if (isset($this) && isset($this->_expected_errors) && sizeof($this->_expected_errors) > 0 && sizeof($exp = end($this->_expected_errors))) {
  462. if ($exp[0] == "*" ||
  463. (is_int(reset($exp)) && in_array($code, $exp)) ||
  464. (is_string(reset($exp)) && in_array($message, $exp))) {
  465. $mode = PEAR_ERROR_RETURN;
  466. }
  467. }
  468. // No mode given, try global ones
  469. if ($mode === null) {
  470. // Class error handler
  471. if (isset($this) && isset($this->_default_error_mode)) {
  472. $mode = $this->_default_error_mode;
  473. $options = $this->_default_error_options;
  474. // Global error handler
  475. } elseif (isset($GLOBALS['_PEAR_default_error_mode'])) {
  476. $mode = $GLOBALS['_PEAR_default_error_mode'];
  477. $options = $GLOBALS['_PEAR_default_error_options'];
  478. }
  479. }
  480. if ($error_class !== null) {
  481. $ec = $error_class;
  482. } elseif (isset($this) && isset($this->_error_class)) {
  483. $ec = $this->_error_class;
  484. } else {
  485. $ec = 'PEAR_Error';
  486. }
  487. if ($skipmsg) {
  488. return new $ec($code, $mode, $options, $userinfo);
  489. } else {
  490. return new $ec($message, $code, $mode, $options, $userinfo);
  491. }
  492. }
  493. // }}}
  494. // {{{ throwError()
  495. /**
  496. * Simpler form of raiseError with fewer options. In most cases
  497. * message, code and userinfo are enough.
  498. *
  499. * @param string $message
  500. *
  501. */
  502. function throwError($message = null,
  503. $code = null,
  504. $userinfo = null)
  505. {
  506. if (isset($this) && is_subclass_of($this, 'PEAR_Error')) {
  507. return $this->raiseError($message, $code, null, null, $userinfo);
  508. } else {
  509. return PEAR::raiseError($message, $code, null, null, $userinfo);
  510. }
  511. }
  512. // }}}
  513. // {{{ pushErrorHandling()
  514. /**
  515. * Push a new error handler on top of the error handler options stack. With this
  516. * you can easily override the actual error handler for some code and restore
  517. * it later with popErrorHandling.
  518. *
  519. * @param mixed $mode (same as setErrorHandling)
  520. * @param mixed $options (same as setErrorHandling)
  521. *
  522. * @return bool Always true
  523. *
  524. * @see PEAR::setErrorHandling
  525. */
  526. function pushErrorHandling($mode, $options = null)
  527. {
  528. $stack = &$GLOBALS['_PEAR_error_handler_stack'];
  529. if (isset($this) && is_a($this, 'PEAR')) {
  530. $def_mode = &$this->_default_error_mode;
  531. $def_options = &$this->_default_error_options;
  532. } else {
  533. $def_mode = &$GLOBALS['_PEAR_default_error_mode'];
  534. $def_options = &$GLOBALS['_PEAR_default_error_options'];
  535. }
  536. $stack[] = array($def_mode, $def_options);
  537. if (isset($this) && is_a($this, 'PEAR')) {
  538. $this->setErrorHandling($mode, $options);
  539. } else {
  540. PEAR::setErrorHandling($mode, $options);
  541. }
  542. $stack[] = array($mode, $options);
  543. return true;
  544. }
  545. // }}}
  546. // {{{ popErrorHandling()
  547. /**
  548. * Pop the last error handler used
  549. *
  550. * @return bool Always true
  551. *
  552. * @see PEAR::pushErrorHandling
  553. */
  554. function popErrorHandling()
  555. {
  556. $stack = &$GLOBALS['_PEAR_error_handler_stack'];
  557. array_pop($stack);
  558. list($mode, $options) = $stack[sizeof($stack) - 1];
  559. array_pop($stack);
  560. if (isset($this) && is_a($this, 'PEAR')) {
  561. $this->setErrorHandling($mode, $options);
  562. } else {
  563. PEAR::setErrorHandling($mode, $options);
  564. }
  565. return true;
  566. }
  567. // }}}
  568. // {{{ loadExtension()
  569. /**
  570. * OS independant PHP extension load. Remember to take care
  571. * on the correct extension name for case sensitive OSes.
  572. *
  573. * @param string $ext The extension name
  574. * @return bool Success or not on the dl() call
  575. */
  576. function loadExtension($ext)
  577. {
  578. if (!extension_loaded($ext)) {
  579. // if either returns true dl() will produce a FATAL error, stop that
  580. if ((ini_get('enable_dl') != 1) || (ini_get('safe_mode') == 1)) {
  581. return false;
  582. }
  583. if (OS_WINDOWS) {
  584. $suffix = '.dll';
  585. } elseif (PHP_OS == 'HP-UX') {
  586. $suffix = '.sl';
  587. } elseif (PHP_OS == 'AIX') {
  588. $suffix = '.a';
  589. } elseif (PHP_OS == 'OSX') {
  590. $suffix = '.bundle';
  591. } else {
  592. $suffix = '.so';
  593. }
  594. return @dl('php_'.$ext.$suffix) || @dl($ext.$suffix);
  595. }
  596. return true;
  597. }
  598. // }}}
  599. }
  600. // {{{ _PEAR_call_destructors()
  601. function _PEAR_call_destructors()
  602. {
  603. global $_PEAR_destructor_object_list;
  604. if (is_array($_PEAR_destructor_object_list) &&
  605. sizeof($_PEAR_destructor_object_list))
  606. {
  607. reset($_PEAR_destructor_object_list);
  608. while (list($k, $objref) = each($_PEAR_destructor_object_list)) {
  609. $classname = get_class($objref);
  610. while ($classname) {
  611. $destructor = "_$classname";
  612. if (method_exists($objref, $destructor)) {
  613. $objref->$destructor();
  614. break;
  615. } else {
  616. $classname = get_parent_class($classname);
  617. }
  618. }
  619. }
  620. // Empty the object list to ensure that destructors are
  621. // not called more than once.
  622. $_PEAR_destructor_object_list = array();
  623. }
  624. // Now call the shutdown functions
  625. if (is_array($GLOBALS['_PEAR_shutdown_funcs']) AND !empty($GLOBALS['_PEAR_shutdown_funcs'])) {
  626. foreach ($GLOBALS['_PEAR_shutdown_funcs'] as $value) {
  627. call_user_func_array($value[0], $value[1]);
  628. }
  629. }
  630. }
  631. // }}}
  632. class PEAR_Error
  633. {
  634. // {{{ properties
  635. var $error_message_prefix = '';
  636. var $mode = PEAR_ERROR_RETURN;
  637. var $level = E_USER_NOTICE;
  638. var $code = -1;
  639. var $message = '';
  640. var $userinfo = '';
  641. var $backtrace = null;
  642. // }}}
  643. // {{{ constructor
  644. /**
  645. * PEAR_Error constructor
  646. *
  647. * @param string $message message
  648. *
  649. * @param int $code (optional) error code
  650. *
  651. * @param int $mode (optional) error mode, one of: PEAR_ERROR_RETURN,
  652. * PEAR_ERROR_PRINT, PEAR_ERROR_DIE, PEAR_ERROR_TRIGGER,
  653. * PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION
  654. *
  655. * @param mixed $options (optional) error level, _OR_ in the case of
  656. * PEAR_ERROR_CALLBACK, the callback function or object/method
  657. * tuple.
  658. *
  659. * @param string $userinfo (optional) additional user/debug info
  660. *
  661. * @access public
  662. *
  663. */
  664. function PEAR_Error($message = 'unknown error', $code = null,
  665. $mode = null, $options = null, $userinfo = null)
  666. {
  667. if ($mode === null) {
  668. $mode = PEAR_ERROR_RETURN;
  669. }
  670. $this->message = $message;
  671. $this->code = $code;
  672. $this->mode = $mode;
  673. $this->userinfo = $userinfo;
  674. if (function_exists("debug_backtrace")) {
  675. $this->backtrace = debug_backtrace();
  676. }
  677. if ($mode & PEAR_ERROR_CALLBACK) {
  678. $this->level = E_USER_NOTICE;
  679. $this->callback = $options;
  680. } else {
  681. if ($options === null) {
  682. $options = E_USER_NOTICE;
  683. }
  684. $this->level = $options;
  685. $this->callback = null;
  686. }
  687. if ($this->mode & PEAR_ERROR_PRINT) {
  688. if (is_null($options) || is_int($options)) {
  689. $format = "%s";
  690. } else {
  691. $format = $options;
  692. }
  693. printf($format, $this->getMessage());
  694. }
  695. if ($this->mode & PEAR_ERROR_TRIGGER) {
  696. trigger_error($this->getMessage(), $this->level);
  697. }
  698. if ($this->mode & PEAR_ERROR_DIE) {
  699. $msg = $this->getMessage();
  700. if (is_null($options) || is_int($options)) {
  701. $format = "%s";
  702. if (substr($msg, -1) != "\n") {
  703. $msg .= "\n";
  704. }
  705. } else {
  706. $format = $options;
  707. }
  708. die(sprintf($format, $msg));
  709. }
  710. if ($this->mode & PEAR_ERROR_CALLBACK) {
  711. if (is_callable($this->callback)) {
  712. call_user_func($this->callback, $this);
  713. }
  714. }
  715. if (PEAR_ZE2 && $this->mode & PEAR_ERROR_EXCEPTION) {
  716. eval('throw $this;');
  717. }
  718. }
  719. // }}}
  720. // {{{ getMode()
  721. /**
  722. * Get the error mode from an error object.
  723. *
  724. * @return int error mode
  725. * @access public
  726. */
  727. function getMode() {
  728. return $this->mode;
  729. }
  730. // }}}
  731. // {{{ getCallback()
  732. /**
  733. * Get the callback function/method from an error object.
  734. *
  735. * @return mixed callback function or object/method array
  736. * @access public
  737. */
  738. function getCallback() {
  739. return $this->callback;
  740. }
  741. // }}}
  742. // {{{ getMessage()
  743. /**
  744. * Get the error message from an error object.
  745. *
  746. * @return string full error message
  747. * @access public
  748. */
  749. function getMessage()
  750. {
  751. return ($this->error_message_prefix . $this->message);
  752. }
  753. // }}}
  754. // {{{ getCode()
  755. /**
  756. * Get error code from an error object
  757. *
  758. * @return int error code
  759. * @access public
  760. */
  761. function getCode()
  762. {
  763. return $this->code;
  764. }
  765. // }}}
  766. // {{{ getType()
  767. /**
  768. * Get the name of this error/exception.
  769. *
  770. * @return string error/exception name (type)
  771. * @access public
  772. */
  773. function getType()
  774. {
  775. return get_class($this);
  776. }
  777. // }}}
  778. // {{{ getUserInfo()
  779. /**
  780. * Get additional user-supplied information.
  781. *
  782. * @return string user-supplied information
  783. * @access public
  784. */
  785. function getUserInfo()
  786. {
  787. return $this->userinfo;
  788. }
  789. // }}}
  790. // {{{ getDebugInfo()
  791. /**
  792. * Get additional debug information supplied by the application.
  793. *
  794. * @return string debug information
  795. * @access public
  796. */
  797. function getDebugInfo()
  798. {
  799. return $this->getUserInfo();
  800. }
  801. // }}}
  802. // {{{ getBacktrace()
  803. /**
  804. * Get the call backtrace from where the error was generated.
  805. * Supported with PHP 4.3.0 or newer.
  806. *
  807. * @param int $frame (optional) what frame to fetch
  808. * @return array Backtrace, or NULL if not available.
  809. * @access public
  810. */
  811. function getBacktrace($frame = null)
  812. {
  813. if ($frame === null) {
  814. return $this->backtrace;
  815. }
  816. return $this->backtrace[$frame];
  817. }
  818. // }}}
  819. // {{{ addUserInfo()
  820. function addUserInfo($info)
  821. {
  822. if (empty($this->userinfo)) {
  823. $this->userinfo = $info;
  824. } else {
  825. $this->userinfo .= " ** $info";
  826. }
  827. }
  828. // }}}
  829. // {{{ toString()
  830. /**
  831. * Make a string representation of this object.
  832. *
  833. * @return string a string with an object summary
  834. * @access public
  835. */
  836. function toString() {
  837. $modes = array();
  838. $levels = array(E_USER_NOTICE => 'notice',
  839. E_USER_WARNING => 'warning',
  840. E_USER_ERROR => 'error');
  841. if ($this->mode & PEAR_ERROR_CALLBACK) {
  842. if (is_array($this->callback)) {
  843. $callback = get_class($this->callback[0]) . '::' .
  844. $this->callback[1];
  845. } else {
  846. $callback = $this->callback;
  847. }
  848. return sprintf('[%s: message="%s" code=%d mode=callback '.
  849. 'callback=%s prefix="%s" info="%s"]',
  850. get_class($this), $this->message, $this->code,
  851. $callback, $this->error_message_prefix,
  852. $this->userinfo);
  853. }
  854. if ($this->mode & PEAR_ERROR_PRINT) {
  855. $modes[] = 'print';
  856. }
  857. if ($this->mode & PEAR_ERROR_TRIGGER) {
  858. $modes[] = 'trigger';
  859. }
  860. if ($this->mode & PEAR_ERROR_DIE) {
  861. $modes[] = 'die';
  862. }
  863. if ($this->mode & PEAR_ERROR_RETURN) {
  864. $modes[] = 'return';
  865. }
  866. return sprintf('[%s: message="%s" code=%d mode=%s level=%s '.
  867. 'prefix="%s" info="%s"]',
  868. get_class($this), $this->message, $this->code,
  869. implode("|", $modes), $levels[$this->level],
  870. $this->error_message_prefix,
  871. $this->userinfo);
  872. }
  873. // }}}
  874. }
  875. register_shutdown_function("_PEAR_call_destructors");
  876. /*
  877. * Local Variables:
  878. * mode: php
  879. * tab-width: 4
  880. * c-basic-offset: 4
  881. * End:
  882. */
  883. ?>