PEAR_Error Change Proposal
| From: | Zakaria | Date: | Thu, 03 May 2001 14:01:34 +0000 |
| Subject: | PEAR_Error Change Proposal | ||
| Groups: | php.pear.dev | ||
| Request: | Send a blank email to pear-dev+get-344@lists.php.net to get a copy of this message | ||
Assalamu'alaikum wr. wb.
After looking at PEAR.php I quickly found something in PEAR_Error
and PEAR::raiseError that could be improved. As the subject says
I hope to spark some discussion.
First about error mode. On PEAR_Error constructor it is look like
that we can bitwise combine PEAR_ERROR_* mode but in
the PEAR::raiseError the mode is handled as only one of
the PEAR_ERROR_*. I think the idea of combining PEAR_ERROR_* mode is
actually good, for example we could combine PEAR_ERROR_CALLBACK
and PEAR_ERROR_TRIGGER.
But the idea has some problem with it. Currently the $options parameter
is either single string for PEAR_ERROR_TRIGGER or an array of two string
for PEAR_ERROR_CALLBACK. So to enable us to combine those mode we need
to change the options into a array of (key => value). With some needed
key for some error mode. This setup is also make it easier to add
another error mode that need other options in the future. Offcourse
this setup break some code, but at the PEAR CVS only PEAR/Packager.php
that use $options.
So the question is: Is it OK to break existing code that relied
on $options is a scalar?
As an important library I think it is better to break it now than
latter.
Second thing is why is PEAR_Error constructor and PEAR::raiseError
has different behaviour. What I mean is the default modes and options.
Is it wise to make PEAR_Error constructor to take global default modes
and options?
To sum it up here is the code.
I purposely didn't sent the patch.
==========================================================================
define('PEAR_ERROR_ALL', 31);
.
.
$GLOBALS['_PEAR_default_error_options'] = array('level' =>
E_USER_NOTICE);
class PEAR
{
.
.
function setErrorHandling($mode, $options = null)
{
PEAR_Error::validateMode($mode, $options);
if (isset($this)) {
$this->_default_error_mode = $mode;
$this->_default_error_options = $options;
} else {
$GLOBALS['_PEAR_default_error_mode'] = $mode;
$GLOBALS['_PEAR_default_error_options'] = $options;
}
}
function &raiseError($message = null, $code = null, $mode = null,
$options = null, $userinfo = null,
$error_class = null, $skipmsg = false)
{
if ($mode === null) {
if (isset($this) && isset($this->_default_error_mode)) {
$mode = $this->_default_error_mode;
} else {
$mode = $GLOBALS['_PEAR_default_error_mode'];
}
}
if (($mode & PEAR_ERROR_TRIGGER || $mode & PEAR_ERROR_CALLBACK)
&& $options === null)
{
if (isset($this) && isset($this->_default_error_options)) {
$options = $this->_default_error_options;
} else {
$options = $GLOBALS['_PEAR_default_error_options'];
}
}
PEAR_Error::validateMode($mode, $options);
if ($error_class !== null) {
$ec = $error_class;
} elseif (isset($this) && isset($this->_error_class)) {
$ec = $this->_error_class;
} else {
$ec = 'PEAR_Error';
}
if ($skipmsg) {
return new $ec($code, $mode, $options, $userinfo);
} else {
return new $ec($message, $code, $mode, $options, $userinfo);
}
}
}
.
.
class PEAR_Error
{
.
.
var $options = array();
.
.
function PEAR_Error($message = "unknown error", $code = null,
$mode = null, $options = null, $userinfo = null)
{
if ($mode === null) {
$mode = $GLOBALS['_PEAR_default_error_mode'];
}
if ($options === null) {
$options = $GLOBALS['_PEAR_default_error_options'];
}
PEAR_Error::validateMode($mode, $options);
$this->message = $message;
$this->code = $code;
$this->userinfo = $userinfo;
$this->mode = $mode;
$this->options = $options;
if ($this->mode & PEAR_ERROR_PRINT) print $this->getMessage();
if ($mode & PEAR_ERROR_CALLBACK) {
if (isset($options['callback_obj'])) {
call_user_method($options['callback_obj']
, $options['callback_func'], $this);
} else {
call_user_func($options['callback_func'], $this);
}
}
if ($this->mode & PEAR_ERROR_TRIGGER) {
trigger_error($this->getMessage(), $options['level']);
}
if ($this->mode & PEAR_ERROR_DIE) {
$msg = $this->getMessage();
if (substr($msg, -1) != "\n") $msg .= "\n";
die($msg);
}
}
// {{{ validateMode()
/**
* Validate mode and options
*
* @access public
*/
function validateMode(&$mode, &$options) {
if ($mode & PEAR_ERROR_TRIGGER) {
if (!(is_array($options) && isset($options['level'])
&& in_array($options['level'], array(E_USER_NOTICE
, E_USER_WARNING, E_USER_ERROR))))
{
trigger_error('Invalid error trigger options'
, E_USER_WARNING);
$mode = $mode & ~PEAR_ERROR_TRIGGER;
}
}
if ($mode & PEAR_ERROR_CALLBACK) {
if (!(is_array($options) && isset($options['callback_func'])
&& ((isset($options['callback_obj'])
&& method_exists($options['callback_obj']
, $options['callback_func']))
|| function_exists($options['callback_func']))))
{
trigger_error('Invalid error callback options'
, E_USER_WARNING);
$mode = $mode & ~PEAR_ERROR_CALLBACK;
}
}
if (is_integer($mode) && $mode >= PEAR_ERROR_RETURN
&& $mode <= PEAR_ERROR_ALL)
{
trigger_error('Invalid error mode', E_USER_WARNING);
$mode = PEAR_ERROR_RETURN;
}
}
// }}}
.
.
}
==========================================================================
Any critics are welcome, including my English :)
Wassallam,
-- Zakaria
Work: zakaria@asia-karsa.com, http://asia-karsa.com
Private: z4k4ri4@bigfoot.com Yahoo!: z4k4ri4
http://pemula.linux.or.id