summaryrefslogtreecommitdiff
path: root/Zend/zend_reflection_api.c
diff options
context:
space:
mode:
authorMarcus Boerger <helly@php.net>2004-09-27 19:01:50 +0000
committerMarcus Boerger <helly@php.net>2004-09-27 19:01:50 +0000
commit2728e52d58545472c6a3e0ce2ad4797808f319f2 (patch)
treed3bf589e3192f72de32248d45b0d9d6110a668e8 /Zend/zend_reflection_api.c
parent96184fe715ae7918110992d33b7debea1a198ad4 (diff)
downloadphp-git-2728e52d58545472c6a3e0ce2ad4797808f319f2.tar.gz
MFH (discussed with Andi)
Diffstat (limited to 'Zend/zend_reflection_api.c')
-rw-r--r--Zend/zend_reflection_api.c257
1 files changed, 214 insertions, 43 deletions
diff --git a/Zend/zend_reflection_api.c b/Zend/zend_reflection_api.c
index eb8bf648be..0e72bac6fa 100644
--- a/Zend/zend_reflection_api.c
+++ b/Zend/zend_reflection_api.c
@@ -145,8 +145,10 @@ typedef struct _property_reference {
/* Struct for parameters */
typedef struct _parameter_reference {
- int offset;
+ zend_uint offset;
+ zend_uint required;
struct _zend_arg_info *arg_info;
+ zend_function *fptr;
} parameter_reference;
/* Struct for reflection objects */
@@ -155,6 +157,7 @@ typedef struct {
void *ptr;
unsigned int free_ptr:1;
zval *obj;
+ zend_class_entry *ce;
} reflection_object;
static zend_object_handlers reflection_object_handlers;
@@ -501,9 +504,14 @@ static void _const_string(string *str, char *name, zval *value, char *indent TSR
/* }}} */
/* {{{ _parameter_string */
-static void _parameter_string(string *str, struct _zend_arg_info *arg_info, int offset, char* indent TSRMLS_DC)
+static void _parameter_string(string *str, zend_function *fptr, struct _zend_arg_info *arg_info, zend_uint offset, zend_uint required, char* indent TSRMLS_DC)
{
string_printf(str, "Parameter #%d [ ", offset);
+ if (offset >= required) {
+ string_printf(str, "<optional> ");
+ } else {
+ string_printf(str, "<required> ");
+ }
if (arg_info->class_name) {
string_printf(str, "%s ", arg_info->class_name);
if (arg_info->allow_null) {
@@ -518,6 +526,32 @@ static void _parameter_string(string *str, struct _zend_arg_info *arg_info, int
} else {
string_printf(str, "$param%d", offset);
}
+ if (fptr->type == ZEND_USER_FUNCTION && offset >= required) {
+ zend_op *precv = &((zend_op_array*)fptr)->opcodes[offset*2 + 1];
+ if (precv->opcode == ZEND_RECV_INIT && precv->op2.op_type != IS_UNUSED) {
+ zval *zv, zv_copy;
+ int use_copy;
+ string_write(str, " = ", sizeof(" = ")-1);
+ zv_copy = precv->op2.u.constant;
+ zv = &zv_copy;
+ zval_update_constant(&zv, (void*)1 TSRMLS_CC);
+ if (Z_TYPE_P(zv) == IS_NULL) {
+ string_write(str, "NULL", sizeof("NULL")-1);
+ } else if (Z_TYPE_P(zv) == IS_STRING) {
+ string_write(str, "'", sizeof("'")-1);
+ string_write(str, Z_STRVAL_P(zv), MIN(Z_STRLEN_P(zv), 15));
+ if (Z_STRLEN_P(zv) > 15) {
+ string_write(str, "...", sizeof("...")-1);
+ }
+ string_write(str, "'", sizeof("'")-1);
+ } else {
+ zend_make_printable_zval(zv, &zv_copy, &use_copy);
+ string_write(str, Z_STRVAL(zv_copy), Z_STRLEN(zv_copy));
+ zval_dtor(&zv_copy);
+ }
+ zval_ptr_dtor(&zv);
+ }
+ }
string_write(str, " ]", sizeof(" ]")-1);
}
/* }}} */
@@ -525,8 +559,8 @@ static void _parameter_string(string *str, struct _zend_arg_info *arg_info, int
/* {{{ _function_parameter_string */
static void _function_parameter_string(string *str, zend_function *fptr, char* indent TSRMLS_DC)
{
- zend_uint i;
struct _zend_arg_info *arg_info = fptr->common.arg_info;
+ zend_uint i, required = fptr->common.required_num_args;
if (!arg_info) {
return;
@@ -536,7 +570,7 @@ static void _function_parameter_string(string *str, zend_function *fptr, char* i
string_printf(str, "%s- Parameters [%d] {\n", indent, fptr->common.num_args);
for (i = 0; i < fptr->common.num_args; i++) {
string_printf(str, "%s ", indent);
- _parameter_string(str, arg_info, i, indent TSRMLS_CC);
+ _parameter_string(str, fptr, arg_info, i, required, indent TSRMLS_CC);
string_write(str, "\n", sizeof("\n")-1);
arg_info++;
}
@@ -586,6 +620,9 @@ static void _function_string(string *str, zend_function *fptr, char* indent TSRM
case ZEND_ACC_PROTECTED:
string_printf(str, "protected ");
break;
+ default:
+ string_printf(str, "<visibilty error> ");
+ break;
}
string_printf(str, fptr->common.scope ? "method " : "function ");
@@ -791,6 +828,7 @@ static void reflection_class_factory(zend_class_entry *ce, zval *object TSRMLS_D
intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
intern->ptr = ce;
intern->free_ptr = 0;
+ intern->ce = ce;
zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL);
}
/* }}} */
@@ -818,12 +856,13 @@ static void reflection_extension_factory(zval *object, char *name_str TSRMLS_DC)
ZVAL_STRINGL(name, module->name, name_len, 1);
intern->ptr = module;
intern->free_ptr = 0;
+ intern->ce = NULL;
zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL);
}
/* }}} */
/* {{{ reflection_parameter_factory */
-static void reflection_parameter_factory(struct _zend_arg_info *arg_info, int offset, zval *object TSRMLS_DC)
+static void reflection_parameter_factory(zend_function *fptr, struct _zend_arg_info *arg_info, zend_uint offset, zend_uint required, zval *object TSRMLS_DC)
{
reflection_object *intern;
parameter_reference *reference;
@@ -840,8 +879,11 @@ static void reflection_parameter_factory(struct _zend_arg_info *arg_info, int of
reference = (parameter_reference*) emalloc(sizeof(parameter_reference));
reference->arg_info = arg_info;
reference->offset = offset;
+ reference->required = required;
+ reference->fptr = fptr;
intern->ptr = reference;
intern->free_ptr = 1;
+ intern->ce = fptr->common.scope;
zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL);
}
/* }}} */
@@ -859,6 +901,7 @@ static void reflection_function_factory(zend_function *function, zval *object TS
intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
intern->ptr = function;
intern->free_ptr = 0;
+ intern->ce = NULL;
zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL);
}
/* }}} */
@@ -878,6 +921,7 @@ static void reflection_method_factory(zend_class_entry *ce, zend_function *metho
intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
intern->ptr = method;
intern->free_ptr = 0;
+ intern->ce = ce;
zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL);
zend_hash_update(Z_OBJPROP_P(object), "class", sizeof("class"), (void **) &classname, sizeof(zval *), NULL);
}
@@ -923,6 +967,7 @@ static void reflection_property_factory(zend_class_entry *ce, zend_property_info
reference->prop = prop;
intern->ptr = reference;
intern->free_ptr = 1;
+ intern->ce = ce;
zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL);
zend_hash_update(Z_OBJPROP_P(object), "class", sizeof("class"), (void **) &classname, sizeof(zval *), NULL);
}
@@ -1152,6 +1197,7 @@ ZEND_METHOD(reflection_function, __construct)
zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL);
intern->ptr = fptr;
intern->free_ptr = 0;
+ intern->ce = NULL;
}
/* }}} */
@@ -1356,13 +1402,41 @@ ZEND_METHOD(reflection_function, returnsReference)
}
/* }}} */
-/* {{{ proto public ReflectionParameter[] ReflectionFunction::getParameters()
+/* {{{ proto public bool ReflectionFunction::getNumberOfParameters()
+ Gets the number of required parameters */
+ZEND_METHOD(reflection_function, getNumberOfParameters)
+{
+ reflection_object *intern;
+ zend_function *fptr;
+
+ METHOD_NOTSTATIC;
+ GET_REFLECTION_OBJECT_PTR(fptr);
+
+ RETURN_LONG(fptr->common.num_args);
+}
+/* }}} */
+
+/* {{{ proto public bool ReflectionFunction::getNumberOfRequiredParameters()
+ Gets the number of required parameters */
+ZEND_METHOD(reflection_function, getNumberOfRequiredParameters)
+{
+ reflection_object *intern;
+ zend_function *fptr;
+
+ METHOD_NOTSTATIC;
+ GET_REFLECTION_OBJECT_PTR(fptr);
+
+ RETURN_LONG(fptr->common.required_num_args);
+}
+/* }}} */
+
+/* {{{ proto public ReflectionParameter[] Reflection_Function::getParameters()
Returns an array of parameter objects for this function */
ZEND_METHOD(reflection_function, getParameters)
{
reflection_object *intern;
zend_function *fptr;
- int i;
+ zend_uint i;
struct _zend_arg_info *arg_info;
METHOD_NOTSTATIC;
@@ -1375,7 +1449,7 @@ ZEND_METHOD(reflection_function, getParameters)
zval *parameter;
ALLOC_ZVAL(parameter);
- reflection_parameter_factory(arg_info, i, parameter TSRMLS_CC);
+ reflection_parameter_factory(fptr, arg_info, i, fptr->common.required_num_args, parameter TSRMLS_CC);
add_next_index_zval(return_value, parameter);
arg_info++;
@@ -1403,6 +1477,7 @@ ZEND_METHOD(reflection_parameter, __construct)
zend_function *fptr;
struct _zend_arg_info *arg_info;
int position;
+ zend_class_entry *ce = NULL;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &reference, &parameter) == FAILURE) {
return;
@@ -1435,7 +1510,6 @@ ZEND_METHOD(reflection_parameter, __construct)
case IS_ARRAY: {
zval **classref;
zval **method;
- zend_class_entry *ce;
zend_class_entry **pce;
char *lcname;
@@ -1479,12 +1553,12 @@ ZEND_METHOD(reflection_parameter, __construct)
arg_info = fptr->common.arg_info;
if (Z_TYPE_P(parameter) == IS_LONG) {
position= Z_LVAL_P(parameter);
- if (position < 0 || position >= fptr->common.num_args) {
+ if (position < 0 || (zend_uint)position >= fptr->common.num_args) {
_DO_THROW("The parameter specified by its offset could not be found");
/* returns out of this function */
}
} else {
- int i;
+ zend_uint i;
position= -1;
convert_to_string_ex(&parameter);
@@ -1510,9 +1584,12 @@ ZEND_METHOD(reflection_parameter, __construct)
ref = (parameter_reference*) emalloc(sizeof(parameter_reference));
ref->arg_info = &arg_info[position];
- ref->offset = position;
+ ref->offset = (zend_uint)position;
+ ref->required = fptr->common.required_num_args;
+ ref->fptr = fptr;
intern->ptr = ref;
intern->free_ptr = 1;
+ intern->ce = ce;
}
/* }}} */
@@ -1527,7 +1604,7 @@ ZEND_METHOD(reflection_parameter, __toString)
METHOD_NOTSTATIC_NUMPARAMS(0);
GET_REFLECTION_OBJECT_PTR(param);
string_init(&str);
- _parameter_string(&str, param->arg_info, param->offset, "" TSRMLS_CC);
+ _parameter_string(&str, param->fptr, param->arg_info, param->offset, param->required, "" TSRMLS_CC);
RETURN_STRINGL(str.string, str.len - 1, 0);
}
/* }}} */
@@ -1597,6 +1674,80 @@ ZEND_METHOD(reflection_parameter, isPassedByReference)
}
/* }}} */
+/* {{{ proto public bool ReflectionParameter::isOptional()
+ Returns whether this parameter is an optional parameter */
+ZEND_METHOD(reflection_parameter, isOptional)
+{
+ reflection_object *intern;
+ parameter_reference *param;
+
+ METHOD_NOTSTATIC_NUMPARAMS(0);
+ GET_REFLECTION_OBJECT_PTR(param);
+
+ RETVAL_BOOL(param->offset >= param->required);
+}
+/* }}} */
+
+/* {{{ proto public bool ReflectionParameter::isDefaultValueAvailable()
+ Returns whether the default value of this parameter is available */
+ZEND_METHOD(reflection_parameter, isDefaultValueAvailable)
+{
+ reflection_object *intern;
+ parameter_reference *param;
+ zend_op *precv;
+
+ METHOD_NOTSTATIC_NUMPARAMS(0);
+ GET_REFLECTION_OBJECT_PTR(param);
+
+ if (param->fptr->type != ZEND_USER_FUNCTION)
+ {
+ RETURN_FALSE;
+ }
+ if (param->offset < param->required) {
+ RETURN_FALSE;
+ }
+ precv = &((zend_op_array*)param->fptr)->opcodes[param->offset*2 + 1];
+ if (precv->opcode != ZEND_RECV_INIT || precv->op2.op_type == IS_UNUSED) {
+ RETURN_FALSE;
+ }
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto public bool ReflectionParameter::getDefaultValue()
+ Returns the default value of this parameter or throws an exception */
+ZEND_METHOD(reflection_parameter, getDefaultValue)
+{
+ reflection_object *intern;
+ parameter_reference *param;
+ zend_op *precv;
+ zval *zv, zv_copy;
+
+ METHOD_NOTSTATIC_NUMPARAMS(0);
+ GET_REFLECTION_OBJECT_PTR(param);
+
+ if (param->fptr->type != ZEND_USER_FUNCTION)
+ {
+ zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Cannot determine default value for internal functions");
+ return;
+ }
+ if (param->offset < param->required) {
+ zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Parameter is not optional");
+ return;
+ }
+ precv = &((zend_op_array*)param->fptr)->opcodes[param->offset*2 + 1];
+ if (precv->opcode != ZEND_RECV_INIT || precv->op2.op_type == IS_UNUSED) {
+ zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Internal error");
+ return;
+ }
+
+ zv_copy = precv->op2.u.constant;
+ zv = &zv_copy;
+ zval_update_constant(&zv, (void*)1 TSRMLS_CC);
+ RETURN_ZVAL(zv, 1, 1);
+}
+/* }}} */
+
/* {{{ proto public static mixed ReflectionMethod::export(mixed class, string name, [, bool return]) throws ReflectionException
Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */
ZEND_METHOD(reflection_method, export)
@@ -1669,6 +1820,7 @@ ZEND_METHOD(reflection_method, __construct)
zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL);
intern->ptr = mptr;
intern->free_ptr = 0;
+ intern->ce = ce;
}
/* }}} */
@@ -1848,7 +2000,10 @@ ZEND_METHOD(reflection_method, isConstructor)
METHOD_NOTSTATIC_NUMPARAMS(0);
GET_REFLECTION_OBJECT_PTR(mptr);
- RETURN_BOOL(mptr->common.scope->constructor == mptr);
+ /* we need to check if the ctor is the ctor of the class level we we
+ * looking at since we might be looking at an inherited old style ctor
+ * defined in base class. */
+ RETURN_BOOL(mptr->common.fn_flags & ZEND_ACC_CTOR && intern->ce->constructor && intern->ce->constructor->common.scope == mptr->common.scope);
}
/* }}} */
@@ -1861,7 +2016,7 @@ ZEND_METHOD(reflection_method, isDestructor)
METHOD_NOTSTATIC_NUMPARAMS(0);
GET_REFLECTION_OBJECT_PTR(mptr);
- RETURN_BOOL(mptr->common.scope->destructor == mptr);
+ RETURN_BOOL(mptr->common.fn_flags && ZEND_ACC_DTOR);
}
/* }}} */
@@ -2530,7 +2685,7 @@ ZEND_METHOD(reflection_class, getParentClass)
}
/* }}} */
-/* {{{ proto public bool ReflectionClass::isSubclassOf(string|reflection_class class)
+/* {{{ proto public bool ReflectionClass::isSubclassOf(string|ReflectionClass class)
Returns whether this class is a subclass of another class */
ZEND_METHOD(reflection_class, isSubclassOf)
{
@@ -2576,7 +2731,7 @@ ZEND_METHOD(reflection_class, isSubclassOf)
}
/* }}} */
-/* {{{ proto public bool ReflectionClass::implementsInterface(string|reflection_class interface_name)
+/* {{{ proto public bool ReflectionClass::implementsInterface(string|ReflectionClass interface_name)
Returns whether this class is a subclass of another class */
ZEND_METHOD(reflection_class, implementsInterface)
{
@@ -2777,6 +2932,7 @@ ZEND_METHOD(reflection_property, __construct)
reference->prop = property_info;
intern->ptr = reference;
intern->free_ptr = 1;
+ intern->ce = ce;
}
/* }}} */
@@ -2869,7 +3025,7 @@ ZEND_METHOD(reflection_property, getModifiers)
}
/* }}} */
-/* {{{ proto public mixed ReflectionProperty::getValue(stdclass object)
+/* {{{ proto public mixed ReflectionProperty::getValue([stdclass object])
Returns this property's value */
ZEND_METHOD(reflection_property, getValue)
{
@@ -2886,16 +3042,15 @@ ZEND_METHOD(reflection_property, getValue)
/* Returns from this function */
}
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &object) == FAILURE) {
- return;
- }
-
if ((ref->prop->flags & ZEND_ACC_STATIC)) {
- if (zend_hash_quick_find(Z_OBJCE_P(object)->static_members, ref->prop->name, ref->prop->name_length + 1, ref->prop->h, (void **) &member) == FAILURE) {
+ if (zend_hash_quick_find(intern->ce->static_members, ref->prop->name, ref->prop->name_length + 1, ref->prop->h, (void **) &member) == FAILURE) {
zend_error(E_ERROR, "Internal error: Could not find the property %s", ref->prop->name);
/* Bails out */
}
} else {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &object) == FAILURE) {
+ return;
+ }
if (zend_hash_quick_find(Z_OBJPROP_P(object), ref->prop->name, ref->prop->name_length + 1, ref->prop->h, (void **) &member) == FAILURE) {
zend_error(E_ERROR, "Internal error: Could not find the property %s", ref->prop->name);
/* Bails out */
@@ -2907,7 +3062,7 @@ ZEND_METHOD(reflection_property, getValue)
}
/* }}} */
-/* {{{ proto public void ReflectionProperty::setValue(stdclass object, mixed value)
+/* {{{ proto public void ReflectionProperty::setValue([stdclass object,] mixed value)
Sets this property's value */
ZEND_METHOD(reflection_property, setValue)
{
@@ -2917,38 +3072,48 @@ ZEND_METHOD(reflection_property, setValue)
zval *object;
zval *value;
int setter_done = 0;
+ zval *tmp;
+ HashTable *prop_table;
METHOD_NOTSTATIC;
GET_REFLECTION_OBJECT_PTR(ref);
- if (ref->prop->flags & ~ZEND_ACC_PUBLIC) {
+ if (ref->prop->flags & ~(ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)) {
_DO_THROW("Cannot access non-public member");
/* Returns from this function */
}
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "oz", &object, &value) == FAILURE) {
- return;
- }
-
- if (zend_hash_quick_find(Z_OBJPROP_P(object), ref->prop->name, ref->prop->name_length + 1, ref->prop->h, (void **) &variable_ptr) == SUCCESS) {
- if (*variable_ptr == value) {
- setter_done = 1;
- } else {
- if (PZVAL_IS_REF(*variable_ptr)) {
- zval_dtor(*variable_ptr);
- (*variable_ptr)->type = value->type;
- (*variable_ptr)->value = value->value;
- if (value->refcount > 0) {
- zval_copy_ctor(*variable_ptr);
- }
- setter_done = 1;
+ if ((ref->prop->flags & ZEND_ACC_STATIC)) {
+ if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "z", &value) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &tmp, &value) == FAILURE) {
+ return;
}
}
+ prop_table = intern->ce->static_members;
} else {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "oz", &object, &value) == FAILURE) {
+ return;
+ }
+ prop_table = Z_OBJPROP_P(object);
+ }
+
+ if (zend_hash_quick_find(prop_table, ref->prop->name, ref->prop->name_length + 1, ref->prop->h, (void **) &variable_ptr) == FAILURE) {
zend_error(E_ERROR, "Internal error: Could not find the property %s", ref->prop->name);
/* Bails out */
}
-
+ if (*variable_ptr == value) {
+ setter_done = 1;
+ } else {
+ if (PZVAL_IS_REF(*variable_ptr)) {
+ zval_dtor(*variable_ptr);
+ (*variable_ptr)->type = value->type;
+ (*variable_ptr)->value = value->value;
+ if (value->refcount > 0) {
+ zval_copy_ctor(*variable_ptr);
+ }
+ setter_done = 1;
+ }
+ }
if (!setter_done) {
zval **foo;
@@ -2956,7 +3121,7 @@ ZEND_METHOD(reflection_property, setValue)
if (PZVAL_IS_REF(value)) {
SEPARATE_ZVAL(&value);
}
- zend_hash_quick_update(Z_OBJPROP_P(object), ref->prop->name, ref->prop->name_length+1, ref->prop->h, &value, sizeof(zval *), (void **) &foo);
+ zend_hash_quick_update(prop_table, ref->prop->name, ref->prop->name_length+1, ref->prop->h, &value, sizeof(zval *), (void **) &foo);
}
}
/* }}} */
@@ -3017,6 +3182,7 @@ ZEND_METHOD(reflection_extension, __construct)
zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL);
intern->ptr = module;
intern->free_ptr = 0;
+ intern->ce = NULL;
}
/* }}} */
@@ -3243,6 +3409,8 @@ static zend_function_entry reflection_function_functions[] = {
ZEND_ME(reflection_function, invoke, NULL, 0)
ZEND_ME(reflection_function, returnsReference, NULL, 0)
ZEND_ME(reflection_function, getParameters, NULL, 0)
+ ZEND_ME(reflection_function, getNumberOfParameters, NULL, 0)
+ ZEND_ME(reflection_function, getNumberOfRequiredParameters, NULL, 0)
{NULL, NULL, NULL}
};
@@ -3335,6 +3503,9 @@ static zend_function_entry reflection_parameter_functions[] = {
ZEND_ME(reflection_parameter, isPassedByReference, NULL, 0)
ZEND_ME(reflection_parameter, getClass, NULL, 0)
ZEND_ME(reflection_parameter, allowsNull, NULL, 0)
+ ZEND_ME(reflection_parameter, isOptional, NULL, 0)
+ ZEND_ME(reflection_parameter, isDefaultValueAvailable, NULL, 0)
+ ZEND_ME(reflection_parameter, getDefaultValue, NULL, 0)
{NULL, NULL, NULL}
};