At least if it comes to internal classes. If you try to get informations about parameters from methods of internal classes - forget that. Examining several internal classes my key findings are: either there is no information about parameters available and the reflection API says the method does not have any parameters, or the information about the parameter is wrong. Some examples I retrieved with the following script:
$output = '';
foreach (get_declared_classes() as $class) {
$output .= $class . "\n";
$refClass = new ReflectionClass($class);
foreach ($refClass->getMethods() as $method) {
$output .= "\t" . $method->getName() . "()\n";
$params = $method->getParameters();
$output .= "\t\tParam count:" . count($params) . "\n";
foreach ($params as $param) {
$output .= "\t\t$" . $param->getName() . "\n";
$output .= "\t\t\tisOptional(): " . var_export($param->isOptional(), true) . "\n";
$output .= "\t\t\tallowsNull(): " . var_export($param->allowsNull(), true) . "\n";
$output .= "\t\t\tisDefaultValueAvailable(): " . var_export($param->isDefaultValueAvailable(), true) . "\n";
if ($param->isDefaultValueAvailable()) {
$output .= "\t\t\tgetDefaultValue(): " . var_export($param->getDefaultValue(), true) . "\n";
} else {
$output .= "\t\t\tgetDefaultValue(): n/a\n";
}
}
}
}
echo $output;
According to the reflection API, none of the methods of XSLTProcessor takes any arguments:
XSLTProcessor
importStylesheet()
Param count:0
transformToDoc()
Param count:0
transformToUri()
Param count:0
transformToXml()
Param count:0
setParameter()
Param count:0
getParameter()
Param count:0
removeParameter()
Param count:0
hasExsltSupport()
Param count:0
registerPHPFunctions()
Param count:0
Well, the
manual states otherwise.
Here is an example which contains wrong informations, it is from the PDOStatement class:
bindColumn()
Param count:5
$column
isOptional(): false
allowsNull(): false
isDefaultValueAvailable(): false
getDefaultValue(): n/a
$param
isOptional(): false
allowsNull(): false
isDefaultValueAvailable(): false
getDefaultValue(): n/a
$type
isOptional(): true
allowsNull(): false
isDefaultValueAvailable(): false
getDefaultValue(): n/a
$maxlen
isOptional(): true
allowsNull(): false
isDefaultValueAvailable(): false
getDefaultValue(): n/a
$driverdata
isOptional(): true
allowsNull(): false
isDefaultValueAvailable(): false
getDefaultValue(): n/a
Three of five parameters here are optional. But they do not have a default value. (By the way, did you know about the last two parameters? They are not listed in the
manual.) For comparison, here is the result of a user-defined class:
class OptionalParamTestClass
{
public function doSomething($foo, $bar = null)
{
return true;
}
}
OptionalParamTestClass
doSomething()
Param count: 2
$foo
isOptional(): false
allowsNull(): true
isDefaultValueAvailable(): false
getDefaultValue(): n/a
$bar
isOptional(): true
allowsNull(): true
isDefaultValueAvailable(): true
getDefaultValue(): NULL
Not only is the allowsNull() return value completely different, while none of the internal class methods allow NULL on any of their parameters, its allowed for both in the user-defined class. Additionally the information about the default value is completely different for optional values.
I stumbled upon this when I tried to create a mock object of the PDOStatement class. The mock complained about missing parameters as the mock creation algorithm did not find any default values for some of the parameters. It took me some time to find that PDOStatement::bindColumn() has more parameters then stated in the manual, and that the reflection API outsmarted the mock creation algorithm about the optional parameters. The quick solution is to satisfy all parameters not required with NULL, but this does only work until the next optional parameter is added, and it renders optional parameters useless. The more stable solution is to check not only for default values of parameters in the mock creation code, but to explicitly ask if a parameter is optional and to use NULL as its default value. This solves the problem, but from my point of view it just does not sound right that reflection information is different for internal and user-defined classes.
On the Stubbles blog, Frank Kleine offers some advice to developers ...
Tracked: Jan 28, 16:13