Subversion-Projekte lars-tiefland.php_share

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

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