Well, i've thought of a few ways to allow localized overriding of
values returned by functions in case of an error.
I have yet to figure out what the exact advantages are of this
code-standard, but the overhead seems acceptable and i recon this,
when done, will beat the "trigger_error()-try-catch" paradigm.
I'd like to hear your comments.
// imo unsafe & prone to fatalities:
$r = funcA ( funcB ( funcC ($p) ), funcD ($q) );
// "safe"; make all notices, warnings and errors from any level
// in the call-chain fully visible, identifiable, and "survivable/fudgeable"
// by code at (all) higher levels in the call-chain.
// [disclaimer] the code below here doesn't pass 3rd-level (funcC())
// (meta-)results back to the first level (funcA()) yet, but this code
// is a start towards that;
$r = funcA (defaults(array(0=>'[funcB failed]',1=>'funcD failed'))),
funcB (defaults($onError_cCallvalue),
funcC (defaults($onError_pValue), $p)
),
funcD (defaults($onError_qValue), $q)
);
function funcA ($defaults, $returnedByFuncB, $returnedByFuncD) {
$returnedByFuncB = workWith ($defaults, $returnedByFuncB, 0);
$returnedByFuncD = workWith ($defaults, $returnedByFuncD, 1);
//all parameters (with idx>0) are meta-arrays containing the
"parameter-value" and all meta-info.
// workWith() always returns the actual parameter-value in
$p['workValue'];
//if any parameter $p (with idx>0) is not a meta-array,
// workWith($d, $r, $n) turns it into a meta array(
// 'workValue' => $p
// );
//if a param is a meta-array $p, and it contains an ['errors'] subarray,
// workWith() sets by-reference $p['workValue'] to one of these
(order of trying):
// $defaults['onError'][$n] (localized override)
// $p['onErrorDefault'], (functions own default value for
when an
error occurs)
//first call to workWith(,,0) will call beginErrorContext()
//beginErrorContext() will increase a global idx $callID (int),
// used to list all notices, warnings and errors, and their details in
// the global variable $callsErrors[$callID][$errorIdx++] = array(
// 'errorMsg' => 'for coders'
// (optional:)'userErrorMsg' => 'for laymen'
// 'backtrace' => array(....)
// )
// the never-fatal error handler specified with set_error_handler() will
// call getDebugInfo() and append full error info into
// $callsErrors[$callID][$errorIdx++]
//forwardDefaults() clones all meta-details for
// re-used parameters into a new $defaults array to be used
// by funcE().
//the 2nd parameter for forwardDefaults lists which parameter
// passed deeper refers to which parameter received by this here
function.
//the 3rd parameter for forwardDefaults is used to specify new defaults.
$returnedByFuncF = funcF('blablasetting');
$x = funcE (
forwardDefaults($defaults, array(0=>0,2=>1), array(1 =>
'defaultblabla')),
$returnedByFuncB, $returnedByFuncF, $returnedByFuncD
);
return goodResult($x);
}
function funcE ($defaults, $returnedByFuncB, $returnedByFuncF,
$returnedByFuncD) {
$returnedByFuncB = workWith ($defaults, $returnedByFuncB, 0);
$returnedByFuncF = workWith ($defaults, $returnedByFuncF, 2);
$returnedByFuncD = workWith ($defaults, $returnedByFuncD, 2);
// do a call that might raise E_WARNINGS or other crap;
// safeCall() is only a try-except struct to call in this case
// str_replace('xx','yy', ...) and if it fails,
// return the default instead of the actual result.
$x = safeCall (
defaults('returnedByFuncB not a string'),
'str_replace', 'xx','yy',$returnedByFuncB
);
if (is_string($returnedByFuncB) && is_string($returnedByFuncD)) {
return goodResult (
$returnedByFuncB . $returnedByFuncD . $x
);
// goodResult() and badResult() will both call
// endErrorContext(), and copy the errors in
// $callsErrors[$callID]
// to the array returned to the calling function.
// goodResult() and badResult() will call processErrors(),
// which is repsonsible for mailing / db-storage of any
// notices, warnings, errors, etc.
} else {
// badResult() will call getDebugInfo() to include
// a full trace, superglobals, lotsa details.
return badResult (array(
'errorMsg' => 'params 1 and 2 must be strings'
'onErrorDefault' => ''
));
//shorthand of the above:
return badResult ('params 1 and 2 must be strings', '');
}
}
function defaults () {
$r = array (
'isMetaForFuncs' => true
);
if (func_num_args()==1) {
return array_merge_recursive ($r,
array('onError'=>array(0=>func_get_arg(0))));
} else {
switch (func_get_arg(0)) {
case 'onError':
$p = func_get_arg(1);
if (is_array($p)) {
return array_merge_recursive ($r,
array('onError'=>$p));
} else {
return array_merge_recursive ($r,
array('onError'=>array(0=>$p)));
}
break;
}
}
}
I also considered the following constructs but rejected them for
clumsiness (first) or sheer uselessness (2nd).
$r = funcA ($bcalldef, funcB($ccalldef, funcC ($pdef, $p)),
$dcalldef, funcD($qdef, $q));
$r = funcA ( funcB ( funcC ( $p ) ), funcD ($q), array (
'isMetaForFuncs' => true,
0 => array (
'onError' => $bCallDefaultOnError,
0 => array (
'onError' => $cCallDefaultOnError,
0 => array (
'onError' => $pDefaultOnError,
)
)
),
1 => array (
'onError' => $qDefaultOnError
)
);
--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php