summaryrefslogtreecommitdiff
path: root/ext/reflection
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@baserock.org>2013-03-14 05:42:27 +0000
committer <>2013-04-03 16:25:08 +0000
commitc4dd7a1a684490673e25aaf4fabec5df138854c4 (patch)
tree4d57c44caae4480efff02b90b9be86f44bf25409 /ext/reflection
downloadphp2-c4dd7a1a684490673e25aaf4fabec5df138854c4.tar.gz
Imported from /home/lorry/working-area/delta_php2/php-5.4.13.tar.bz2.HEADphp-5.4.13master
Diffstat (limited to 'ext/reflection')
-rwxr-xr-xext/reflection/CREDITS2
-rwxr-xr-xext/reflection/config.m45
-rwxr-xr-xext/reflection/config.w326
-rw-r--r--ext/reflection/php_reflection.c6195
-rw-r--r--ext/reflection/php_reflection.h57
-rw-r--r--ext/reflection/tests/001.phpt89
-rw-r--r--ext/reflection/tests/002.phpt63
-rw-r--r--ext/reflection/tests/003.phpt31
-rw-r--r--ext/reflection/tests/004.phpt42
-rw-r--r--ext/reflection/tests/005.phpt54
-rw-r--r--ext/reflection/tests/006.phpt103
-rw-r--r--ext/reflection/tests/007.phpt160
-rw-r--r--ext/reflection/tests/008.phpt39
-rw-r--r--ext/reflection/tests/009.phpt112
-rw-r--r--ext/reflection/tests/010.phpt21
-rw-r--r--ext/reflection/tests/011.phpt12
-rw-r--r--ext/reflection/tests/012.phpt16
-rw-r--r--ext/reflection/tests/013.phpt13
-rw-r--r--ext/reflection/tests/014.phpt13
-rw-r--r--ext/reflection/tests/015.phpt15
-rw-r--r--ext/reflection/tests/016.phpt20
-rw-r--r--ext/reflection/tests/017.phpt33
-rw-r--r--ext/reflection/tests/018.phpt15
-rw-r--r--ext/reflection/tests/019.phpt11
-rw-r--r--ext/reflection/tests/020.phpt27
-rw-r--r--ext/reflection/tests/021.phpt16
-rw-r--r--ext/reflection/tests/022.phpt16
-rw-r--r--ext/reflection/tests/023.phpt32
-rw-r--r--ext/reflection/tests/024.phpt45
-rw-r--r--ext/reflection/tests/025.phpt114
-rw-r--r--ext/reflection/tests/026.phpt34
-rw-r--r--ext/reflection/tests/ReflectionClass_CannotClone_basic.phpt15
-rw-r--r--ext/reflection/tests/ReflectionClass_FileInfo_basic.phpt33
-rw-r--r--ext/reflection/tests/ReflectionClass_FileInfo_error.phpt37
-rw-r--r--ext/reflection/tests/ReflectionClass_constructor_001.phpt33
-rw-r--r--ext/reflection/tests/ReflectionClass_constructor_002.phpt67
-rw-r--r--ext/reflection/tests/ReflectionClass_export_basic1.phpt62
-rw-r--r--ext/reflection/tests/ReflectionClass_export_basic2.phpt54
-rw-r--r--ext/reflection/tests/ReflectionClass_getConstant_basic.phpt41
-rw-r--r--ext/reflection/tests/ReflectionClass_getConstant_error.phpt37
-rw-r--r--ext/reflection/tests/ReflectionClass_getConstants_basic.phpt48
-rw-r--r--ext/reflection/tests/ReflectionClass_getConstants_error.phpt24
-rw-r--r--ext/reflection/tests/ReflectionClass_getConstructor_basic.phpt79
-rw-r--r--ext/reflection/tests/ReflectionClass_getConstructor_error.phpt23
-rw-r--r--ext/reflection/tests/ReflectionClass_getDefaultProperties_001.phpt194
-rw-r--r--ext/reflection/tests/ReflectionClass_getDefaultProperties_002.phpt44
-rw-r--r--ext/reflection/tests/ReflectionClass_getDocComment_001.phpt98
-rw-r--r--ext/reflection/tests/ReflectionClass_getDocComment_002.phpt26
-rw-r--r--ext/reflection/tests/ReflectionClass_getExtensionName_basic.phpt14
-rw-r--r--ext/reflection/tests/ReflectionClass_getExtensionName_variation.phpt18
-rw-r--r--ext/reflection/tests/ReflectionClass_getExtension_basic.phpt17
-rw-r--r--ext/reflection/tests/ReflectionClass_getExtension_variation.phpt18
-rw-r--r--ext/reflection/tests/ReflectionClass_getInterfaceNames_basic.phpt23
-rw-r--r--ext/reflection/tests/ReflectionClass_getInterfaces_001.phpt311
-rw-r--r--ext/reflection/tests/ReflectionClass_getInterfaces_002.phpt53
-rw-r--r--ext/reflection/tests/ReflectionClass_getInterfaces_003.phpt69
-rw-r--r--ext/reflection/tests/ReflectionClass_getInterfaces_004.phpt27
-rw-r--r--ext/reflection/tests/ReflectionClass_getMethod_001.phpt168
-rw-r--r--ext/reflection/tests/ReflectionClass_getMethod_002.phpt74
-rw-r--r--ext/reflection/tests/ReflectionClass_getMethods_001.phpt140
-rw-r--r--ext/reflection/tests/ReflectionClass_getMethods_002.phpt18
-rw-r--r--ext/reflection/tests/ReflectionClass_getMethods_003.phpt191
-rw-r--r--ext/reflection/tests/ReflectionClass_getModifierNames_basic.phpt139
-rw-r--r--ext/reflection/tests/ReflectionClass_getModifiers_basic.phpt37
-rw-r--r--ext/reflection/tests/ReflectionClass_getName_basic.phpt25
-rw-r--r--ext/reflection/tests/ReflectionClass_getName_error.phpt16
-rw-r--r--ext/reflection/tests/ReflectionClass_getName_error1.phpt8
-rw-r--r--ext/reflection/tests/ReflectionClass_getNamespaceName.phpt30
-rw-r--r--ext/reflection/tests/ReflectionClass_getParentClass.phpt21
-rw-r--r--ext/reflection/tests/ReflectionClass_getParentClass_001.phpt38
-rw-r--r--ext/reflection/tests/ReflectionClass_getProperties_001.phpt126
-rw-r--r--ext/reflection/tests/ReflectionClass_getProperties_002.phpt17
-rw-r--r--ext/reflection/tests/ReflectionClass_getProperties_003.phpt189
-rw-r--r--ext/reflection/tests/ReflectionClass_getProperty_001.phpt146
-rw-r--r--ext/reflection/tests/ReflectionClass_getProperty_002.phpt72
-rw-r--r--ext/reflection/tests/ReflectionClass_getProperty_003.phpt251
-rw-r--r--ext/reflection/tests/ReflectionClass_getProperty_004.phpt251
-rw-r--r--ext/reflection/tests/ReflectionClass_getStaticPropertyValue_001.phpt69
-rw-r--r--ext/reflection/tests/ReflectionClass_getStaticPropertyValue_001_2_4.phpt61
-rw-r--r--ext/reflection/tests/ReflectionClass_getStaticPropertyValue_002.phpt52
-rw-r--r--ext/reflection/tests/ReflectionClass_hasConstant_001.phpt36
-rw-r--r--ext/reflection/tests/ReflectionClass_hasConstant_002.phpt40
-rw-r--r--ext/reflection/tests/ReflectionClass_hasConstant_basic.phpt23
-rw-r--r--ext/reflection/tests/ReflectionClass_hasMethod_001.phpt75
-rw-r--r--ext/reflection/tests/ReflectionClass_hasMethod_002.phpt40
-rw-r--r--ext/reflection/tests/ReflectionClass_hasMethod_basic.phpt57
-rw-r--r--ext/reflection/tests/ReflectionClass_hasProperty_001.phpt75
-rw-r--r--ext/reflection/tests/ReflectionClass_hasProperty_002.phpt40
-rw-r--r--ext/reflection/tests/ReflectionClass_hasProperty_basic.phpt38
-rw-r--r--ext/reflection/tests/ReflectionClass_implementsInterface_001.phpt155
-rw-r--r--ext/reflection/tests/ReflectionClass_isAbstract_basic.phpt21
-rw-r--r--ext/reflection/tests/ReflectionClass_isCloneable_001.phpt71
-rw-r--r--ext/reflection/tests/ReflectionClass_isCloneable_002.phpt25
-rw-r--r--ext/reflection/tests/ReflectionClass_isFinal_basic.phpt21
-rw-r--r--ext/reflection/tests/ReflectionClass_isInstance_basic.phpt51
-rw-r--r--ext/reflection/tests/ReflectionClass_isInstance_error.phpt39
-rw-r--r--ext/reflection/tests/ReflectionClass_isInstantiable_basic.phpt40
-rw-r--r--ext/reflection/tests/ReflectionClass_isInstantiable_error.phpt19
-rw-r--r--ext/reflection/tests/ReflectionClass_isInstantiable_variation.phpt50
-rw-r--r--ext/reflection/tests/ReflectionClass_isInterface_basic.phpt25
-rw-r--r--ext/reflection/tests/ReflectionClass_isInternal_basic.phpt22
-rw-r--r--ext/reflection/tests/ReflectionClass_isInternal_error.phpt14
-rw-r--r--ext/reflection/tests/ReflectionClass_isIterateable_001.phpt89
-rw-r--r--ext/reflection/tests/ReflectionClass_isIterateable_basic.phpt34
-rw-r--r--ext/reflection/tests/ReflectionClass_isIterateable_variation1.phpt25
-rw-r--r--ext/reflection/tests/ReflectionClass_isSubclassOf_002.phpt49
-rw-r--r--ext/reflection/tests/ReflectionClass_isSubclassOf_basic.phpt103
-rw-r--r--ext/reflection/tests/ReflectionClass_isSubclassOf_error.phpt17
-rw-r--r--ext/reflection/tests/ReflectionClass_isSubclassOf_error1.phpt16
-rw-r--r--ext/reflection/tests/ReflectionClass_isUserDefined_basic.phpt22
-rw-r--r--ext/reflection/tests/ReflectionClass_isUserDefined_error.phpt14
-rw-r--r--ext/reflection/tests/ReflectionClass_modifiers_001.phpt44
-rw-r--r--ext/reflection/tests/ReflectionClass_modifiers_002.phpt27
-rw-r--r--ext/reflection/tests/ReflectionClass_newInstanceArgs_001.phpt98
-rw-r--r--ext/reflection/tests/ReflectionClass_newInstanceArgs_002.phpt20
-rw-r--r--ext/reflection/tests/ReflectionClass_newInstanceWithoutConstructor.phpt33
-rw-r--r--ext/reflection/tests/ReflectionClass_newInstance_001.phpt98
-rw-r--r--ext/reflection/tests/ReflectionClass_setStaticPropertyValue_001.phpt79
-rw-r--r--ext/reflection/tests/ReflectionClass_setStaticPropertyValue_001_2_4.phpt61
-rw-r--r--ext/reflection/tests/ReflectionClass_setStaticPropertyValue_002.phpt60
-rw-r--r--ext/reflection/tests/ReflectionClass_toString_001.phpt350
-rw-r--r--ext/reflection/tests/ReflectionClass_toString_002.phpt123
-rw-r--r--ext/reflection/tests/ReflectionClass_toString_003.phpt120
-rw-r--r--ext/reflection/tests/ReflectionExtension_constructor_basic.phpt15
-rw-r--r--ext/reflection/tests/ReflectionExtension_constructor_error.phpt16
-rw-r--r--ext/reflection/tests/ReflectionExtension_export_basic.phpt22
-rw-r--r--ext/reflection/tests/ReflectionExtension_getClassNames_basic.phpt20
-rw-r--r--ext/reflection/tests/ReflectionExtension_getClassNames_variation1.phpt14
-rw-r--r--ext/reflection/tests/ReflectionExtension_getClasses_basic.phpt74
-rw-r--r--ext/reflection/tests/ReflectionExtension_getDependencies_basic.phpt22
-rw-r--r--ext/reflection/tests/ReflectionExtension_getDependencies_variation2.phpt16
-rw-r--r--ext/reflection/tests/ReflectionExtension_getName_basic.phpt14
-rw-r--r--ext/reflection/tests/ReflectionExtension_getVersion_basic.phpt16
-rw-r--r--ext/reflection/tests/ReflectionExtension_info_basic.phpt19
-rw-r--r--ext/reflection/tests/ReflectionExtension_isPersistant.phpt11
-rw-r--r--ext/reflection/tests/ReflectionExtension_isTemporary.phpt11
-rw-r--r--ext/reflection/tests/ReflectionFunction_001.phpt67
-rw-r--r--ext/reflection/tests/ReflectionFunction_construct.001.phpt23
-rw-r--r--ext/reflection/tests/ReflectionFunction_getClosureScopeClass.phpt31
-rw-r--r--ext/reflection/tests/ReflectionFunction_getClosureThis.phpt17
-rw-r--r--ext/reflection/tests/ReflectionFunction_getClosure_basic.phpt37
-rw-r--r--ext/reflection/tests/ReflectionFunction_getClosure_error.phpt27
-rw-r--r--ext/reflection/tests/ReflectionFunction_getDocComment.001.phpt41
-rw-r--r--ext/reflection/tests/ReflectionFunction_getExtension.phpt19
-rw-r--r--ext/reflection/tests/ReflectionFunction_getExtensionName.phpt16
-rw-r--r--ext/reflection/tests/ReflectionFunction_getFileName.001.phpt18
-rw-r--r--ext/reflection/tests/ReflectionFunction_getFileName.002.phpt39
-rw-r--r--ext/reflection/tests/ReflectionFunction_getNamespaceName.phpt29
-rw-r--r--ext/reflection/tests/ReflectionFunction_isClosure_basic.phpt18
-rw-r--r--ext/reflection/tests/ReflectionFunction_isDeprecated_basic.phpt15
-rw-r--r--ext/reflection/tests/ReflectionFunction_isDisabled_basic.phpt17
-rw-r--r--ext/reflection/tests/ReflectionMethod_006.phpt100
-rw-r--r--ext/reflection/tests/ReflectionMethod_basic1.phpt298
-rw-r--r--ext/reflection/tests/ReflectionMethod_basic2.phpt188
-rw-r--r--ext/reflection/tests/ReflectionMethod_basic3.phpt167
-rw-r--r--ext/reflection/tests/ReflectionMethod_basic4.phpt170
-rw-r--r--ext/reflection/tests/ReflectionMethod_constructor_basic.phpt117
-rw-r--r--ext/reflection/tests/ReflectionMethod_constructor_error1.phpt103
-rw-r--r--ext/reflection/tests/ReflectionMethod_constructor_error2.phpt37
-rw-r--r--ext/reflection/tests/ReflectionMethod_getClosureThis.phpt53
-rw-r--r--ext/reflection/tests/ReflectionMethod_getClosure_basic.phpt55
-rw-r--r--ext/reflection/tests/ReflectionMethod_getClosure_error.phpt73
-rw-r--r--ext/reflection/tests/ReflectionMethod_getDeclaringClass_basic.phpt30
-rw-r--r--ext/reflection/tests/ReflectionMethod_getDocComment_basic.phpt113
-rw-r--r--ext/reflection/tests/ReflectionMethod_getDocComment_error.phpt15
-rw-r--r--ext/reflection/tests/ReflectionMethod_getModifiers_basic.phpt242
-rw-r--r--ext/reflection/tests/ReflectionMethod_getStaticVariables_basic.phpt63
-rw-r--r--ext/reflection/tests/ReflectionMethod_invokeArgs_basic.phpt73
-rw-r--r--ext/reflection/tests/ReflectionMethod_invokeArgs_error1.phpt36
-rw-r--r--ext/reflection/tests/ReflectionMethod_invokeArgs_error2.phpt27
-rw-r--r--ext/reflection/tests/ReflectionMethod_invokeArgs_error3.phpt117
-rw-r--r--ext/reflection/tests/ReflectionMethod_invoke_basic.phpt108
-rw-r--r--ext/reflection/tests/ReflectionMethod_invoke_error1.phpt71
-rw-r--r--ext/reflection/tests/ReflectionMethod_invoke_error2.phpt32
-rw-r--r--ext/reflection/tests/ReflectionMethod_returnsReference_basic.phpt23
-rw-r--r--ext/reflection/tests/ReflectionMethod_setAccessible.phpt111
-rw-r--r--ext/reflection/tests/ReflectionObject_FileInfo_basic.phpt25
-rw-r--r--ext/reflection/tests/ReflectionObject_FileInfo_error.phpt37
-rw-r--r--ext/reflection/tests/ReflectionObject___toString_basic1.phpt36
-rw-r--r--ext/reflection/tests/ReflectionObject___toString_basic2.phpt39
-rw-r--r--ext/reflection/tests/ReflectionObject_constructor_basic.phpt28
-rw-r--r--ext/reflection/tests/ReflectionObject_constructor_error.phpt49
-rw-r--r--ext/reflection/tests/ReflectionObject_export_basic1.phpt36
-rw-r--r--ext/reflection/tests/ReflectionObject_export_basic2.phpt39
-rw-r--r--ext/reflection/tests/ReflectionObject_export_basic3.phpt38
-rw-r--r--ext/reflection/tests/ReflectionObject_getConstant_basic.phpt41
-rw-r--r--ext/reflection/tests/ReflectionObject_getConstant_error.phpt34
-rw-r--r--ext/reflection/tests/ReflectionObject_getConstants_basic.phpt49
-rw-r--r--ext/reflection/tests/ReflectionObject_getConstants_error.phpt17
-rw-r--r--ext/reflection/tests/ReflectionObject_getConstructor_basic.phpt79
-rw-r--r--ext/reflection/tests/ReflectionObject_getConstructor_error.phpt23
-rw-r--r--ext/reflection/tests/ReflectionObject_getName_basic.phpt27
-rw-r--r--ext/reflection/tests/ReflectionObject_getName_error.phpt23
-rw-r--r--ext/reflection/tests/ReflectionObject_getName_error1.phpt8
-rw-r--r--ext/reflection/tests/ReflectionObject_isInstance_basic.phpt33
-rw-r--r--ext/reflection/tests/ReflectionObject_isInstance_error.phpt38
-rw-r--r--ext/reflection/tests/ReflectionObject_isInstantiable_basic.phpt36
-rw-r--r--ext/reflection/tests/ReflectionObject_isInstantiable_error.phpt22
-rw-r--r--ext/reflection/tests/ReflectionObject_isInstantiable_variation.phpt78
-rw-r--r--ext/reflection/tests/ReflectionObject_isInternal_basic.phpt23
-rw-r--r--ext/reflection/tests/ReflectionObject_isInternal_error.phpt15
-rw-r--r--ext/reflection/tests/ReflectionObject_isSubclassOf.002.phpt48
-rw-r--r--ext/reflection/tests/ReflectionObject_isSubclassOf_basic.phpt116
-rw-r--r--ext/reflection/tests/ReflectionObject_isSubclassOf_error.phpt24
-rw-r--r--ext/reflection/tests/ReflectionObject_isUserDefined_basic.phpt23
-rw-r--r--ext/reflection/tests/ReflectionObject_isUserDefined_error.phpt15
-rw-r--r--ext/reflection/tests/ReflectionParameter_001.phpt80
-rw-r--r--ext/reflection/tests/ReflectionParameter_002.phpt80
-rw-r--r--ext/reflection/tests/ReflectionParameter_003.phpt88
-rw-r--r--ext/reflection/tests/ReflectionParameter_DefaultValueConstant_basic1.phpt52
-rw-r--r--ext/reflection/tests/ReflectionParameter_DefaultValueConstant_basic2.phpt30
-rw-r--r--ext/reflection/tests/ReflectionParameter_DefaultValueConstant_error.phpt23
-rw-r--r--ext/reflection/tests/ReflectionParameter_canBePassedByValue.phpt84
-rw-r--r--ext/reflection/tests/ReflectionParameter_export_basic.phpt19
-rw-r--r--ext/reflection/tests/ReflectionParameter_export_error.phpt21
-rw-r--r--ext/reflection/tests/ReflectionParameter_export_error2.phpt31
-rw-r--r--ext/reflection/tests/ReflectionParameter_export_error3.phpt22
-rw-r--r--ext/reflection/tests/ReflectionParameter_getDeclaringFunction_basic.phpt37
-rw-r--r--ext/reflection/tests/ReflectionParameter_getPosition_basic.phpt21
-rw-r--r--ext/reflection/tests/ReflectionParameter_invalidMethodInConstructor.phpt31
-rw-r--r--ext/reflection/tests/ReflectionParameter_isDefault.phpt34
-rw-r--r--ext/reflection/tests/ReflectionParameter_toString_basic.phpt20
-rw-r--r--ext/reflection/tests/ReflectionProperty_basic1.phpt160
-rw-r--r--ext/reflection/tests/ReflectionProperty_basic2.phpt103
-rw-r--r--ext/reflection/tests/ReflectionProperty_constructor_error.phpt44
-rw-r--r--ext/reflection/tests/ReflectionProperty_constructor_variation1.phpt58
-rw-r--r--ext/reflection/tests/ReflectionProperty_error.phpt67
-rw-r--r--ext/reflection/tests/ReflectionProperty_export_basic.phpt16
-rw-r--r--ext/reflection/tests/ReflectionProperty_export_error.phpt54
-rw-r--r--ext/reflection/tests/ReflectionProperty_getDeclaringClass_variation1.phpt27
-rw-r--r--ext/reflection/tests/ReflectionProperty_getDocComment_basic.phpt100
-rw-r--r--ext/reflection/tests/ReflectionProperty_getDocComment_error.phpt28
-rw-r--r--ext/reflection/tests/ReflectionProperty_getModifiers.001.phpt66
-rw-r--r--ext/reflection/tests/ReflectionProperty_getModifiers_basic.phpt46
-rw-r--r--ext/reflection/tests/ReflectionProperty_getValue_error.phpt81
-rw-r--r--ext/reflection/tests/ReflectionProperty_isDefault_basic.phpt63
-rw-r--r--ext/reflection/tests/ReflectionProperty_setAccessible.phpt139
-rw-r--r--ext/reflection/tests/ReflectionProperty_setValue_error.phpt100
-rw-r--r--ext/reflection/tests/bug26640.phpt25
-rw-r--r--ext/reflection/tests/bug26695.phpt25
-rw-r--r--ext/reflection/tests/bug29268.phpt27
-rw-r--r--ext/reflection/tests/bug29523.phpt38
-rw-r--r--ext/reflection/tests/bug29828.phpt35
-rw-r--r--ext/reflection/tests/bug29986.phpt41
-rw-r--r--ext/reflection/tests/bug30146.phpt23
-rw-r--r--ext/reflection/tests/bug30148.phpt35
-rw-r--r--ext/reflection/tests/bug30209.phpt31
-rw-r--r--ext/reflection/tests/bug30856.phpt20
-rw-r--r--ext/reflection/tests/bug30961.phpt20
-rw-r--r--ext/reflection/tests/bug31651.phpt24
-rw-r--r--ext/reflection/tests/bug32981.phpt34
-rw-r--r--ext/reflection/tests/bug33312.phpt20
-rw-r--r--ext/reflection/tests/bug33389.phpt97
-rw-r--r--ext/reflection/tests/bug36308.phpt20
-rw-r--r--ext/reflection/tests/bug36337.phpt28
-rw-r--r--ext/reflection/tests/bug36434.phpt31
-rw-r--r--ext/reflection/tests/bug37816.phpt28
-rw-r--r--ext/reflection/tests/bug37964.phpt50
-rw-r--r--ext/reflection/tests/bug38132.phpt32
-rw-r--r--ext/reflection/tests/bug38194.phpt11
-rw-r--r--ext/reflection/tests/bug38217.phpt40
-rw-r--r--ext/reflection/tests/bug38465.phpt64
-rw-r--r--ext/reflection/tests/bug38653.phpt28
-rw-r--r--ext/reflection/tests/bug38942.phpt34
-rw-r--r--ext/reflection/tests/bug39001.phpt27
-rw-r--r--ext/reflection/tests/bug39067.phpt45
-rw-r--r--ext/reflection/tests/bug39884.phpt22
-rw-r--r--ext/reflection/tests/bug40431.phpt136
-rw-r--r--ext/reflection/tests/bug40794.phpt32
-rw-r--r--ext/reflection/tests/bug41061.phpt28
-rw-r--r--ext/reflection/tests/bug41884.phpt25
-rw-r--r--ext/reflection/tests/bug42976.phpt38
-rw-r--r--ext/reflection/tests/bug43926.phpt67
-rw-r--r--ext/reflection/tests/bug45139.phpt58
-rw-r--r--ext/reflection/tests/bug45571.phpt40
-rw-r--r--ext/reflection/tests/bug45765.phpt82
-rw-r--r--ext/reflection/tests/bug46064.phpt76
-rw-r--r--ext/reflection/tests/bug46064_2.phpt74
-rw-r--r--ext/reflection/tests/bug46205.phpt14
-rw-r--r--ext/reflection/tests/bug47254.phpt41
-rw-r--r--ext/reflection/tests/bug48336.phpt44
-rw-r--r--ext/reflection/tests/bug48757.phpt21
-rw-r--r--ext/reflection/tests/bug49074.phpt31
-rw-r--r--ext/reflection/tests/bug49092.phpt12
-rw-r--r--ext/reflection/tests/bug49719.phpt44
-rw-r--r--ext/reflection/tests/bug51905.phpt28
-rw-r--r--ext/reflection/tests/bug51911.phpt22
-rw-r--r--ext/reflection/tests/bug52057.phpt54
-rw-r--r--ext/reflection/tests/bug52854.phpt28
-rw-r--r--ext/reflection/tests/bug53366.phpt25
-rw-r--r--ext/reflection/tests/bug53915.phpt28
-rw-r--r--ext/reflection/tests/bug60357.phpt10
-rw-r--r--ext/reflection/tests/bug60367.phpt28
-rw-r--r--ext/reflection/tests/bug61388.phpt32
-rw-r--r--ext/reflection/tests/bug62384.phpt21
-rw-r--r--ext/reflection/tests/bug62715.phpt24
-rw-r--r--ext/reflection/tests/bug63399.phpt49
-rw-r--r--ext/reflection/tests/bug63614.phpt41
-rw-r--r--ext/reflection/tests/closures_001.phpt70
-rw-r--r--ext/reflection/tests/closures_002.phpt29
-rw-r--r--ext/reflection/tests/closures_003.phpt25
-rw-r--r--ext/reflection/tests/closures_003_v1.phpt25
-rw-r--r--ext/reflection/tests/closures_004.phpt43
-rw-r--r--ext/reflection/tests/exception.inc16
-rw-r--r--ext/reflection/tests/included4.inc9
-rw-r--r--ext/reflection/tests/parameters_001.phpt38
-rw-r--r--ext/reflection/tests/parameters_002.phpt207
-rw-r--r--ext/reflection/tests/property_exists.phpt222
-rw-r--r--ext/reflection/tests/static_properties_002.phpt60
-rw-r--r--ext/reflection/tests/traits001.phpt70
-rw-r--r--ext/reflection/tests/traits002.phpt54
-rw-r--r--ext/reflection/tests/traits003.phpt30
-rw-r--r--ext/reflection/tests/traits004.phpt58
-rw-r--r--ext/reflection/tests/traits005.phpt41
314 files changed, 22709 insertions, 0 deletions
diff --git a/ext/reflection/CREDITS b/ext/reflection/CREDITS
new file mode 100755
index 0000000..84be988
--- /dev/null
+++ b/ext/reflection/CREDITS
@@ -0,0 +1,2 @@
+Reflection
+Marcus Boerger, Timm Friebe, George Schlossnagle, Andrei Zmievski, Johannes Schlueter
diff --git a/ext/reflection/config.m4 b/ext/reflection/config.m4
new file mode 100755
index 0000000..7026636
--- /dev/null
+++ b/ext/reflection/config.m4
@@ -0,0 +1,5 @@
+dnl $Id$
+dnl config.m4 for extension reflection
+
+AC_DEFINE(HAVE_REFLECTION, 1, [Whether Reflection is enabled])
+PHP_NEW_EXTENSION(reflection, php_reflection.c, no)
diff --git a/ext/reflection/config.w32 b/ext/reflection/config.w32
new file mode 100755
index 0000000..724bf7b
--- /dev/null
+++ b/ext/reflection/config.w32
@@ -0,0 +1,6 @@
+// $Id$
+// vim:ft=javascript
+
+EXTENSION("reflection", "php_reflection.c", false /* never shared */);
+AC_DEFINE('HAVE_REFLECTION', 1, 'Reflection support enabled');
+PHP_REFLECTION="yes"; \ No newline at end of file
diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c
new file mode 100644
index 0000000..659f4be
--- /dev/null
+++ b/ext/reflection/php_reflection.c
@@ -0,0 +1,6195 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2013 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Timm Friebe <thekid@thekid.de> |
+ | George Schlossnagle <george@omniti.com> |
+ | Andrei Zmievski <andrei@gravitonic.com> |
+ | Marcus Boerger <helly@php.net> |
+ | Johannes Schlueter <johannes@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id: 25ecbad68e5a4573ffee43ea24a0591ea179492a $ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#include "php_ini.h"
+#include "php_reflection.h"
+#include "ext/standard/info.h"
+
+#include "zend.h"
+#include "zend_API.h"
+#include "zend_exceptions.h"
+#include "zend_operators.h"
+#include "zend_constants.h"
+#include "zend_ini.h"
+#include "zend_interfaces.h"
+#include "zend_closures.h"
+#include "zend_extensions.h"
+
+#define reflection_update_property(object, name, value) do { \
+ zval *member; \
+ MAKE_STD_ZVAL(member); \
+ ZVAL_STRINGL(member, name, sizeof(name)-1, 1); \
+ zend_std_write_property(object, member, value, NULL TSRMLS_CC); \
+ Z_DELREF_P(value); \
+ zval_ptr_dtor(&member); \
+ } while (0)
+
+/* Class entry pointers */
+PHPAPI zend_class_entry *reflector_ptr;
+PHPAPI zend_class_entry *reflection_exception_ptr;
+PHPAPI zend_class_entry *reflection_ptr;
+PHPAPI zend_class_entry *reflection_function_abstract_ptr;
+PHPAPI zend_class_entry *reflection_function_ptr;
+PHPAPI zend_class_entry *reflection_parameter_ptr;
+PHPAPI zend_class_entry *reflection_class_ptr;
+PHPAPI zend_class_entry *reflection_object_ptr;
+PHPAPI zend_class_entry *reflection_method_ptr;
+PHPAPI zend_class_entry *reflection_property_ptr;
+PHPAPI zend_class_entry *reflection_extension_ptr;
+PHPAPI zend_class_entry *reflection_zend_extension_ptr;
+
+#if MBO_0
+ZEND_BEGIN_MODULE_GLOBALS(reflection)
+ int dummy;
+ZEND_END_MODULE_GLOBALS(reflection)
+
+#ifdef ZTS
+# define REFLECTION_G(v) \
+ TSRMG(reflection_globals_id, zend_reflection_globals*, v)
+extern int reflection_globals_id;
+#else
+# define REFLECTION_G(v) (reflection_globals.v)
+extern zend_reflection_globals reflectionglobals;
+#endif
+
+ZEND_DECLARE_MODULE_GLOBALS(reflection)
+#endif /* MBO_0 */
+
+/* Method macros */
+
+#define METHOD_NOTSTATIC(ce) \
+ if (!this_ptr || !instanceof_function(Z_OBJCE_P(this_ptr), ce TSRMLS_CC)) { \
+ php_error_docref(NULL TSRMLS_CC, E_ERROR, "%s() cannot be called statically", get_active_function_name(TSRMLS_C)); \
+ return; \
+ } \
+
+/* Exception throwing macro */
+#define _DO_THROW(msg) \
+ zend_throw_exception(reflection_exception_ptr, msg, 0 TSRMLS_CC); \
+ return; \
+
+#define RETURN_ON_EXCEPTION \
+ if (EG(exception) && Z_OBJCE_P(EG(exception)) == reflection_exception_ptr) { \
+ return; \
+ }
+
+#define GET_REFLECTION_OBJECT_PTR(target) \
+ intern = (reflection_object *) zend_object_store_get_object(getThis() TSRMLS_CC); \
+ if (intern == NULL || intern->ptr == NULL) { \
+ RETURN_ON_EXCEPTION \
+ php_error_docref(NULL TSRMLS_CC, E_ERROR, "Internal error: Failed to retrieve the reflection object"); \
+ } \
+ target = intern->ptr; \
+
+/* Class constants */
+#define REGISTER_REFLECTION_CLASS_CONST_LONG(class_name, const_name, value) \
+ zend_declare_class_constant_long(reflection_ ## class_name ## _ptr, const_name, sizeof(const_name)-1, (long)value TSRMLS_CC);
+
+/* {{{ Smart string functions */
+typedef struct _string {
+ char *string;
+ int len;
+ int alloced;
+} string;
+
+static void string_init(string *str)
+{
+ str->string = (char *) emalloc(1024);
+ str->len = 1;
+ str->alloced = 1024;
+ *str->string = '\0';
+}
+
+static string *string_printf(string *str, const char *format, ...)
+{
+ int len;
+ va_list arg;
+ char *s_tmp;
+
+ va_start(arg, format);
+ len = zend_vspprintf(&s_tmp, 0, format, arg);
+ if (len) {
+ register int nlen = (str->len + len + (1024 - 1)) & ~(1024 - 1);
+ if (str->alloced < nlen) {
+ str->alloced = nlen;
+ str->string = erealloc(str->string, str->alloced);
+ }
+ memcpy(str->string + str->len - 1, s_tmp, len + 1);
+ str->len += len;
+ }
+ efree(s_tmp);
+ va_end(arg);
+ return str;
+}
+
+static string *string_write(string *str, char *buf, int len)
+{
+ register int nlen = (str->len + len + (1024 - 1)) & ~(1024 - 1);
+ if (str->alloced < nlen) {
+ str->alloced = nlen;
+ str->string = erealloc(str->string, str->alloced);
+ }
+ memcpy(str->string + str->len - 1, buf, len);
+ str->len += len;
+ str->string[str->len - 1] = '\0';
+ return str;
+}
+
+static string *string_append(string *str, string *append)
+{
+ if (append->len > 1) {
+ string_write(str, append->string, append->len - 1);
+ }
+ return str;
+}
+
+static void string_free(string *str)
+{
+ efree(str->string);
+ str->len = 0;
+ str->alloced = 0;
+ str->string = NULL;
+}
+/* }}} */
+
+/* {{{ Object structure */
+
+/* Struct for properties */
+typedef struct _property_reference {
+ zend_class_entry *ce;
+ zend_property_info prop;
+} property_reference;
+
+/* Struct for parameters */
+typedef struct _parameter_reference {
+ zend_uint offset;
+ zend_uint required;
+ struct _zend_arg_info *arg_info;
+ zend_function *fptr;
+} parameter_reference;
+
+typedef enum {
+ REF_TYPE_OTHER, /* Must be 0 */
+ REF_TYPE_FUNCTION,
+ REF_TYPE_PARAMETER,
+ REF_TYPE_PROPERTY,
+ REF_TYPE_DYNAMIC_PROPERTY
+} reflection_type_t;
+
+/* Struct for reflection objects */
+typedef struct {
+ zend_object zo;
+ void *ptr;
+ reflection_type_t ref_type;
+ zval *obj;
+ zend_class_entry *ce;
+ unsigned int ignore_visibility:1;
+} reflection_object;
+
+/* }}} */
+
+static zend_object_handlers reflection_object_handlers;
+
+static void _default_get_entry(zval *object, char *name, int name_len, zval *return_value TSRMLS_DC) /* {{{ */
+{
+ zval **value;
+
+ if (zend_hash_find(Z_OBJPROP_P(object), name, name_len, (void **) &value) == FAILURE) {
+ RETURN_FALSE;
+ }
+
+ MAKE_COPY_ZVAL(value, return_value);
+}
+/* }}} */
+
+#ifdef ilia_0
+static void _default_lookup_entry(zval *object, char *name, int name_len, zval **return_value TSRMLS_DC) /* {{{ */
+{
+ zval **value;
+
+ if (zend_hash_find(Z_OBJPROP_P(object), name, name_len, (void **) &value) == FAILURE) {
+ *return_value = NULL;
+ } else {
+ *return_value = *value;
+ }
+}
+/* }}} */
+#endif
+
+static void reflection_register_implement(zend_class_entry *class_entry, zend_class_entry *interface_entry TSRMLS_DC) /* {{{ */
+{
+ zend_uint num_interfaces = ++class_entry->num_interfaces;
+
+ class_entry->interfaces = (zend_class_entry **) realloc(class_entry->interfaces, sizeof(zend_class_entry *) * num_interfaces);
+ class_entry->interfaces[num_interfaces - 1] = interface_entry;
+}
+/* }}} */
+
+static zend_function *_copy_function(zend_function *fptr TSRMLS_DC) /* {{{ */
+{
+ if (fptr
+ && fptr->type == ZEND_INTERNAL_FUNCTION
+ && (fptr->internal_function.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0)
+ {
+ zend_function *copy_fptr;
+ copy_fptr = emalloc(sizeof(zend_function));
+ memcpy(copy_fptr, fptr, sizeof(zend_function));
+ copy_fptr->internal_function.function_name = estrdup(fptr->internal_function.function_name);
+ return copy_fptr;
+ } else {
+ /* no copy needed */
+ return fptr;
+ }
+}
+/* }}} */
+
+static void _free_function(zend_function *fptr TSRMLS_DC) /* {{{ */
+{
+ if (fptr
+ && fptr->type == ZEND_INTERNAL_FUNCTION
+ && (fptr->internal_function.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0)
+ {
+ efree((char*)fptr->internal_function.function_name);
+ efree(fptr);
+ }
+}
+/* }}} */
+
+static void reflection_free_objects_storage(void *object TSRMLS_DC) /* {{{ */
+{
+ reflection_object *intern = (reflection_object *) object;
+ parameter_reference *reference;
+ property_reference *prop_reference;
+
+ if (intern->ptr) {
+ switch (intern->ref_type) {
+ case REF_TYPE_PARAMETER:
+ reference = (parameter_reference*)intern->ptr;
+ _free_function(reference->fptr TSRMLS_CC);
+ efree(intern->ptr);
+ break;
+ case REF_TYPE_FUNCTION:
+ _free_function(intern->ptr TSRMLS_CC);
+ break;
+ case REF_TYPE_PROPERTY:
+ efree(intern->ptr);
+ break;
+ case REF_TYPE_DYNAMIC_PROPERTY:
+ prop_reference = (property_reference*)intern->ptr;
+ efree((char*)prop_reference->prop.name);
+ efree(intern->ptr);
+ break;
+ case REF_TYPE_OTHER:
+ break;
+ }
+ }
+ intern->ptr = NULL;
+ if (intern->obj) {
+ zval_ptr_dtor(&intern->obj);
+ }
+ zend_objects_free_object_storage(object TSRMLS_CC);
+}
+/* }}} */
+
+static zend_object_value reflection_objects_new(zend_class_entry *class_type TSRMLS_DC) /* {{{ */
+{
+ zend_object_value retval;
+ reflection_object *intern;
+
+ intern = ecalloc(1, sizeof(reflection_object));
+ intern->zo.ce = class_type;
+
+ zend_object_std_init(&intern->zo, class_type TSRMLS_CC);
+ object_properties_init(&intern->zo, class_type);
+ retval.handle = zend_objects_store_put(intern, NULL, reflection_free_objects_storage, NULL TSRMLS_CC);
+ retval.handlers = &reflection_object_handlers;
+ return retval;
+}
+/* }}} */
+
+static zval * reflection_instantiate(zend_class_entry *pce, zval *object TSRMLS_DC) /* {{{ */
+{
+ if (!object) {
+ ALLOC_ZVAL(object);
+ }
+ Z_TYPE_P(object) = IS_OBJECT;
+ object_init_ex(object, pce);
+ Z_SET_REFCOUNT_P(object, 1);
+ Z_SET_ISREF_P(object);
+ return object;
+}
+/* }}} */
+
+static void _const_string(string *str, char *name, zval *value, char *indent TSRMLS_DC);
+static void _function_string(string *str, zend_function *fptr, zend_class_entry *scope, char* indent TSRMLS_DC);
+static void _property_string(string *str, zend_property_info *prop, char *prop_name, char* indent TSRMLS_DC);
+static void _class_string(string *str, zend_class_entry *ce, zval *obj, char *indent TSRMLS_DC);
+static void _extension_string(string *str, zend_module_entry *module, char *indent TSRMLS_DC);
+static void _zend_extension_string(string *str, zend_extension *extension, char *indent TSRMLS_DC);
+
+/* {{{ _class_string */
+static void _class_string(string *str, zend_class_entry *ce, zval *obj, char *indent TSRMLS_DC)
+{
+ int count, count_static_props = 0, count_static_funcs = 0, count_shadow_props = 0;
+ string sub_indent;
+
+ string_init(&sub_indent);
+ string_printf(&sub_indent, "%s ", indent);
+
+ /* TBD: Repair indenting of doc comment (or is this to be done in the parser?) */
+ if (ce->type == ZEND_USER_CLASS && ce->info.user.doc_comment) {
+ string_printf(str, "%s%s", indent, ce->info.user.doc_comment);
+ string_write(str, "\n", 1);
+ }
+
+ if (obj) {
+ string_printf(str, "%sObject of class [ ", indent);
+ } else {
+ char *kind = "Class";
+ if (ce->ce_flags & ZEND_ACC_INTERFACE) {
+ kind = "Interface";
+ } else if ((ce->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) {
+ kind = "Trait";
+ }
+ string_printf(str, "%s%s [ ", indent, kind);
+ }
+ string_printf(str, (ce->type == ZEND_USER_CLASS) ? "<user" : "<internal");
+ if (ce->type == ZEND_INTERNAL_CLASS && ce->info.internal.module) {
+ string_printf(str, ":%s", ce->info.internal.module->name);
+ }
+ string_printf(str, "> ");
+ if (ce->get_iterator != NULL) {
+ string_printf(str, "<iterateable> ");
+ }
+ if (ce->ce_flags & ZEND_ACC_INTERFACE) {
+ string_printf(str, "interface ");
+ } else if ((ce->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) {
+ string_printf(str, "trait ");
+ } else {
+ if (ce->ce_flags & (ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) {
+ string_printf(str, "abstract ");
+ }
+ if (ce->ce_flags & ZEND_ACC_FINAL_CLASS) {
+ string_printf(str, "final ");
+ }
+ string_printf(str, "class ");
+ }
+ string_printf(str, "%s", ce->name);
+ if (ce->parent) {
+ string_printf(str, " extends %s", ce->parent->name);
+ }
+
+ if (ce->num_interfaces) {
+ zend_uint i;
+
+ if (ce->ce_flags & ZEND_ACC_INTERFACE) {
+ string_printf(str, " extends %s", ce->interfaces[0]->name);
+ } else {
+ string_printf(str, " implements %s", ce->interfaces[0]->name);
+ }
+ for (i = 1; i < ce->num_interfaces; ++i) {
+ string_printf(str, ", %s", ce->interfaces[i]->name);
+ }
+ }
+ string_printf(str, " ] {\n");
+
+ /* The information where a class is declared is only available for user classes */
+ if (ce->type == ZEND_USER_CLASS) {
+ string_printf(str, "%s @@ %s %d-%d\n", indent, ce->info.user.filename,
+ ce->info.user.line_start, ce->info.user.line_end);
+ }
+
+ /* Constants */
+ if (&ce->constants_table) {
+ zend_hash_apply_with_argument(&ce->constants_table, (apply_func_arg_t) zval_update_constant, (void*)1 TSRMLS_CC);
+ string_printf(str, "\n");
+ count = zend_hash_num_elements(&ce->constants_table);
+ string_printf(str, "%s - Constants [%d] {\n", indent, count);
+ if (count > 0) {
+ HashPosition pos;
+ zval **value;
+ char *key;
+ uint key_len;
+ ulong num_index;
+
+ zend_hash_internal_pointer_reset_ex(&ce->constants_table, &pos);
+
+ while (zend_hash_get_current_data_ex(&ce->constants_table, (void **) &value, &pos) == SUCCESS) {
+ zend_hash_get_current_key_ex(&ce->constants_table, &key, &key_len, &num_index, 0, &pos);
+
+ _const_string(str, key, *value, indent TSRMLS_CC);
+ zend_hash_move_forward_ex(&ce->constants_table, &pos);
+ }
+ }
+ string_printf(str, "%s }\n", indent);
+ }
+
+ /* Static properties */
+ if (&ce->properties_info) {
+ /* counting static properties */
+ count = zend_hash_num_elements(&ce->properties_info);
+ if (count > 0) {
+ HashPosition pos;
+ zend_property_info *prop;
+
+ zend_hash_internal_pointer_reset_ex(&ce->properties_info, &pos);
+
+ while (zend_hash_get_current_data_ex(&ce->properties_info, (void **) &prop, &pos) == SUCCESS) {
+ if(prop->flags & ZEND_ACC_SHADOW) {
+ count_shadow_props++;
+ } else if (prop->flags & ZEND_ACC_STATIC) {
+ count_static_props++;
+ }
+ zend_hash_move_forward_ex(&ce->properties_info, &pos);
+ }
+ }
+
+ /* static properties */
+ string_printf(str, "\n%s - Static properties [%d] {\n", indent, count_static_props);
+ if (count_static_props > 0) {
+ HashPosition pos;
+ zend_property_info *prop;
+
+ zend_hash_internal_pointer_reset_ex(&ce->properties_info, &pos);
+
+ while (zend_hash_get_current_data_ex(&ce->properties_info, (void **) &prop, &pos) == SUCCESS) {
+ if ((prop->flags & ZEND_ACC_STATIC) && !(prop->flags & ZEND_ACC_SHADOW)) {
+ _property_string(str, prop, NULL, sub_indent.string TSRMLS_CC);
+ }
+
+ zend_hash_move_forward_ex(&ce->properties_info, &pos);
+ }
+ }
+ string_printf(str, "%s }\n", indent);
+ }
+
+ /* Static methods */
+ if (&ce->function_table) {
+ /* counting static methods */
+ count = zend_hash_num_elements(&ce->function_table);
+ if (count > 0) {
+ HashPosition pos;
+ zend_function *mptr;
+
+ zend_hash_internal_pointer_reset_ex(&ce->function_table, &pos);
+
+ while (zend_hash_get_current_data_ex(&ce->function_table, (void **) &mptr, &pos) == SUCCESS) {
+ if (mptr->common.fn_flags & ZEND_ACC_STATIC
+ && ((mptr->common.fn_flags & ZEND_ACC_PRIVATE) == 0 || mptr->common.scope == ce))
+ {
+ count_static_funcs++;
+ }
+ zend_hash_move_forward_ex(&ce->function_table, &pos);
+ }
+ }
+
+ /* static methods */
+ string_printf(str, "\n%s - Static methods [%d] {", indent, count_static_funcs);
+ if (count_static_funcs > 0) {
+ HashPosition pos;
+ zend_function *mptr;
+
+ zend_hash_internal_pointer_reset_ex(&ce->function_table, &pos);
+
+ while (zend_hash_get_current_data_ex(&ce->function_table, (void **) &mptr, &pos) == SUCCESS) {
+ if (mptr->common.fn_flags & ZEND_ACC_STATIC
+ && ((mptr->common.fn_flags & ZEND_ACC_PRIVATE) == 0 || mptr->common.scope == ce))
+ {
+ string_printf(str, "\n");
+ _function_string(str, mptr, ce, sub_indent.string TSRMLS_CC);
+ }
+ zend_hash_move_forward_ex(&ce->function_table, &pos);
+ }
+ } else {
+ string_printf(str, "\n");
+ }
+ string_printf(str, "%s }\n", indent);
+ }
+
+ /* Default/Implicit properties */
+ if (&ce->properties_info) {
+ count = zend_hash_num_elements(&ce->properties_info) - count_static_props - count_shadow_props;
+ string_printf(str, "\n%s - Properties [%d] {\n", indent, count);
+ if (count > 0) {
+ HashPosition pos;
+ zend_property_info *prop;
+
+ zend_hash_internal_pointer_reset_ex(&ce->properties_info, &pos);
+
+ while (zend_hash_get_current_data_ex(&ce->properties_info, (void **) &prop, &pos) == SUCCESS) {
+ if (!(prop->flags & (ZEND_ACC_STATIC|ZEND_ACC_SHADOW))) {
+ _property_string(str, prop, NULL, sub_indent.string TSRMLS_CC);
+ }
+ zend_hash_move_forward_ex(&ce->properties_info, &pos);
+ }
+ }
+ string_printf(str, "%s }\n", indent);
+ }
+
+ if (obj && Z_OBJ_HT_P(obj)->get_properties) {
+ string dyn;
+ HashTable *properties = Z_OBJ_HT_P(obj)->get_properties(obj TSRMLS_CC);
+ HashPosition pos;
+ zval **prop;
+
+ string_init(&dyn);
+ count = 0;
+
+ if (properties && zend_hash_num_elements(properties)) {
+ zend_hash_internal_pointer_reset_ex(properties, &pos);
+
+ while (zend_hash_get_current_data_ex(properties, (void **) &prop, &pos) == SUCCESS) {
+ char *prop_name;
+ uint prop_name_size;
+ ulong index;
+
+ if (zend_hash_get_current_key_ex(properties, &prop_name, &prop_name_size, &index, 1, &pos) == HASH_KEY_IS_STRING) {
+ if (prop_name_size && prop_name[0]) { /* skip all private and protected properties */
+ if (!zend_hash_quick_exists(&ce->properties_info, prop_name, prop_name_size, zend_get_hash_value(prop_name, prop_name_size))) {
+ count++;
+ _property_string(&dyn, NULL, prop_name, sub_indent.string TSRMLS_CC);
+ }
+ }
+ efree(prop_name);
+ }
+ zend_hash_move_forward_ex(properties, &pos);
+ }
+ }
+
+ string_printf(str, "\n%s - Dynamic properties [%d] {\n", indent, count);
+ string_append(str, &dyn);
+ string_printf(str, "%s }\n", indent);
+ string_free(&dyn);
+ }
+
+ /* Non static methods */
+ if (&ce->function_table) {
+ count = zend_hash_num_elements(&ce->function_table) - count_static_funcs;
+ if (count > 0) {
+ HashPosition pos;
+ zend_function *mptr;
+ string dyn;
+
+ count = 0;
+ string_init(&dyn);
+ zend_hash_internal_pointer_reset_ex(&ce->function_table, &pos);
+
+ while (zend_hash_get_current_data_ex(&ce->function_table, (void **) &mptr, &pos) == SUCCESS) {
+ if ((mptr->common.fn_flags & ZEND_ACC_STATIC) == 0
+ && ((mptr->common.fn_flags & ZEND_ACC_PRIVATE) == 0 || mptr->common.scope == ce))
+ {
+ char *key;
+ uint key_len;
+ ulong num_index;
+ uint len = strlen(mptr->common.function_name);
+
+ /* Do not display old-style inherited constructors */
+ if ((mptr->common.fn_flags & ZEND_ACC_CTOR) == 0
+ || mptr->common.scope == ce
+ || zend_hash_get_current_key_ex(&ce->function_table, &key, &key_len, &num_index, 0, &pos) != HASH_KEY_IS_STRING
+ || zend_binary_strcasecmp(key, key_len-1, mptr->common.function_name, len) == 0)
+ {
+ zend_function *closure;
+ /* see if this is a closure */
+ if (ce == zend_ce_closure && obj && (len == sizeof(ZEND_INVOKE_FUNC_NAME)-1)
+ && memcmp(mptr->common.function_name, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0
+ && (closure = zend_get_closure_invoke_method(obj TSRMLS_CC)) != NULL)
+ {
+ mptr = closure;
+ } else {
+ closure = NULL;
+ }
+ string_printf(&dyn, "\n");
+ _function_string(&dyn, mptr, ce, sub_indent.string TSRMLS_CC);
+ count++;
+ _free_function(closure TSRMLS_CC);
+ }
+ }
+ zend_hash_move_forward_ex(&ce->function_table, &pos);
+ }
+ string_printf(str, "\n%s - Methods [%d] {", indent, count);
+ if (!count) {
+ string_printf(str, "\n");
+ }
+ string_append(str, &dyn);
+ string_free(&dyn);
+ } else {
+ string_printf(str, "\n%s - Methods [0] {\n", indent);
+ }
+ string_printf(str, "%s }\n", indent);
+ }
+
+ string_printf(str, "%s}\n", indent);
+ string_free(&sub_indent);
+}
+/* }}} */
+
+/* {{{ _const_string */
+static void _const_string(string *str, char *name, zval *value, char *indent TSRMLS_DC)
+{
+ char *type;
+ zval value_copy;
+ int use_copy;
+
+ type = zend_zval_type_name(value);
+
+ zend_make_printable_zval(value, &value_copy, &use_copy);
+ if (use_copy) {
+ value = &value_copy;
+ }
+
+ string_printf(str, "%s Constant [ %s %s ] { %s }\n",
+ indent, type, name, Z_STRVAL_P(value));
+
+ if (use_copy) {
+ zval_dtor(value);
+ }
+}
+/* }}} */
+
+/* {{{ _get_recv_opcode */
+static zend_op* _get_recv_op(zend_op_array *op_array, zend_uint offset)
+{
+ zend_op *op = op_array->opcodes;
+ zend_op *end = op + op_array->last;
+
+ ++offset;
+ while (op < end) {
+ if ((op->opcode == ZEND_RECV || op->opcode == ZEND_RECV_INIT)
+ && op->op1.num == (long)offset)
+ {
+ return op;
+ }
+ ++op;
+ }
+ return NULL;
+}
+/* }}} */
+
+/* {{{ _parameter_string */
+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) {
+ string_printf(str, "or NULL ");
+ }
+ } else if (arg_info->type_hint) {
+ string_printf(str, "%s ", zend_get_type_by_const(arg_info->type_hint));
+ if (arg_info->allow_null) {
+ string_printf(str, "or NULL ");
+ }
+ }
+ if (arg_info->pass_by_reference) {
+ string_write(str, "&", sizeof("&")-1);
+ }
+ if (arg_info->name) {
+ string_printf(str, "$%s", arg_info->name);
+ } else {
+ string_printf(str, "$param%d", offset);
+ }
+ if (fptr->type == ZEND_USER_FUNCTION && offset >= required) {
+ zend_op *precv = _get_recv_op((zend_op_array*)fptr, offset);
+ if (precv && precv->opcode == ZEND_RECV_INIT && precv->op2_type != IS_UNUSED) {
+ zval *zv, zv_copy;
+ int use_copy;
+ string_write(str, " = ", sizeof(" = ")-1);
+ ALLOC_ZVAL(zv);
+ *zv = *precv->op2.zv;
+ zval_copy_ctor(zv);
+ INIT_PZVAL(zv);
+ zval_update_constant_ex(&zv, (void*)1, fptr->common.scope TSRMLS_CC);
+ if (Z_TYPE_P(zv) == IS_BOOL) {
+ if (Z_LVAL_P(zv)) {
+ string_write(str, "true", sizeof("true")-1);
+ } else {
+ string_write(str, "false", sizeof("false")-1);
+ }
+ } else 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 if (Z_TYPE_P(zv) == IS_ARRAY) {
+ string_write(str, "Array", sizeof("Array")-1);
+ } else {
+ zend_make_printable_zval(zv, &zv_copy, &use_copy);
+ string_write(str, Z_STRVAL(zv_copy), Z_STRLEN(zv_copy));
+ if (use_copy) {
+ zval_dtor(&zv_copy);
+ }
+ }
+ zval_ptr_dtor(&zv);
+ }
+ }
+ string_write(str, " ]", sizeof(" ]")-1);
+}
+/* }}} */
+
+/* {{{ _function_parameter_string */
+static void _function_parameter_string(string *str, zend_function *fptr, char* indent TSRMLS_DC)
+{
+ struct _zend_arg_info *arg_info = fptr->common.arg_info;
+ zend_uint i, required = fptr->common.required_num_args;
+
+ if (!arg_info) {
+ return;
+ }
+
+ string_printf(str, "\n");
+ 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, fptr, arg_info, i, required, indent TSRMLS_CC);
+ string_write(str, "\n", sizeof("\n")-1);
+ arg_info++;
+ }
+ string_printf(str, "%s}\n", indent);
+}
+/* }}} */
+
+/* {{{ _function_closure_string */
+static void _function_closure_string(string *str, zend_function *fptr, char* indent TSRMLS_DC)
+{
+ zend_uint i, count;
+ ulong num_index;
+ char *key;
+ uint key_len;
+ HashTable *static_variables;
+ HashPosition pos;
+
+ if (fptr->type != ZEND_USER_FUNCTION || !fptr->op_array.static_variables) {
+ return;
+ }
+
+ static_variables = fptr->op_array.static_variables;
+ count = zend_hash_num_elements(static_variables);
+
+ if (!count) {
+ return;
+ }
+
+ string_printf(str, "\n");
+ string_printf(str, "%s- Bound Variables [%d] {\n", indent, zend_hash_num_elements(static_variables));
+ zend_hash_internal_pointer_reset_ex(static_variables, &pos);
+ i = 0;
+ while (i < count) {
+ zend_hash_get_current_key_ex(static_variables, &key, &key_len, &num_index, 0, &pos);
+ string_printf(str, "%s Variable #%d [ $%s ]\n", indent, i++, key);
+ zend_hash_move_forward_ex(static_variables, &pos);
+ }
+ string_printf(str, "%s}\n", indent);
+}
+/* }}} */
+
+/* {{{ _function_string */
+static void _function_string(string *str, zend_function *fptr, zend_class_entry *scope, char* indent TSRMLS_DC)
+{
+ string param_indent;
+ zend_function *overwrites;
+ char *lc_name;
+ unsigned int lc_name_len;
+
+ /* TBD: Repair indenting of doc comment (or is this to be done in the parser?)
+ * What's "wrong" is that any whitespace before the doc comment start is
+ * swallowed, leading to an unaligned comment.
+ */
+ if (fptr->type == ZEND_USER_FUNCTION && fptr->op_array.doc_comment) {
+ string_printf(str, "%s%s\n", indent, fptr->op_array.doc_comment);
+ }
+
+ string_write(str, indent, strlen(indent));
+ string_printf(str, fptr->common.fn_flags & ZEND_ACC_CLOSURE ? "Closure [ " : (fptr->common.scope ? "Method [ " : "Function [ "));
+ string_printf(str, (fptr->type == ZEND_USER_FUNCTION) ? "<user" : "<internal");
+ if (fptr->common.fn_flags & ZEND_ACC_DEPRECATED) {
+ string_printf(str, ", deprecated");
+ }
+ if (fptr->type == ZEND_INTERNAL_FUNCTION && ((zend_internal_function*)fptr)->module) {
+ string_printf(str, ":%s", ((zend_internal_function*)fptr)->module->name);
+ }
+
+ if (scope && fptr->common.scope) {
+ if (fptr->common.scope != scope) {
+ string_printf(str, ", inherits %s", fptr->common.scope->name);
+ } else if (fptr->common.scope->parent) {
+ lc_name_len = strlen(fptr->common.function_name);
+ lc_name = zend_str_tolower_dup(fptr->common.function_name, lc_name_len);
+ if (zend_hash_find(&fptr->common.scope->parent->function_table, lc_name, lc_name_len + 1, (void**) &overwrites) == SUCCESS) {
+ if (fptr->common.scope != overwrites->common.scope) {
+ string_printf(str, ", overwrites %s", overwrites->common.scope->name);
+ }
+ }
+ efree(lc_name);
+ }
+ }
+ if (fptr->common.prototype && fptr->common.prototype->common.scope) {
+ string_printf(str, ", prototype %s", fptr->common.prototype->common.scope->name);
+ }
+ if (fptr->common.fn_flags & ZEND_ACC_CTOR) {
+ string_printf(str, ", ctor");
+ }
+ if (fptr->common.fn_flags & ZEND_ACC_DTOR) {
+ string_printf(str, ", dtor");
+ }
+ string_printf(str, "> ");
+
+ if (fptr->common.fn_flags & ZEND_ACC_ABSTRACT) {
+ string_printf(str, "abstract ");
+ }
+ if (fptr->common.fn_flags & ZEND_ACC_FINAL) {
+ string_printf(str, "final ");
+ }
+ if (fptr->common.fn_flags & ZEND_ACC_STATIC) {
+ string_printf(str, "static ");
+ }
+
+ if (fptr->common.scope) {
+ /* These are mutually exclusive */
+ switch (fptr->common.fn_flags & ZEND_ACC_PPP_MASK) {
+ case ZEND_ACC_PUBLIC:
+ string_printf(str, "public ");
+ break;
+ case ZEND_ACC_PRIVATE:
+ string_printf(str, "private ");
+ break;
+ case ZEND_ACC_PROTECTED:
+ string_printf(str, "protected ");
+ break;
+ default:
+ string_printf(str, "<visibility error> ");
+ break;
+ }
+ string_printf(str, "method ");
+ } else {
+ string_printf(str, "function ");
+ }
+
+ if (fptr->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ string_printf(str, "&");
+ }
+ string_printf(str, "%s ] {\n", fptr->common.function_name);
+ /* The information where a function is declared is only available for user classes */
+ if (fptr->type == ZEND_USER_FUNCTION) {
+ string_printf(str, "%s @@ %s %d - %d\n", indent,
+ fptr->op_array.filename,
+ fptr->op_array.line_start,
+ fptr->op_array.line_end);
+ }
+ string_init(&param_indent);
+ string_printf(&param_indent, "%s ", indent);
+ if (fptr->common.fn_flags & ZEND_ACC_CLOSURE) {
+ _function_closure_string(str, fptr, param_indent.string TSRMLS_CC);
+ }
+ _function_parameter_string(str, fptr, param_indent.string TSRMLS_CC);
+ string_free(&param_indent);
+ string_printf(str, "%s}\n", indent);
+}
+/* }}} */
+
+/* {{{ _property_string */
+static void _property_string(string *str, zend_property_info *prop, char *prop_name, char* indent TSRMLS_DC)
+{
+ const char *class_name;
+
+ string_printf(str, "%sProperty [ ", indent);
+ if (!prop) {
+ string_printf(str, "<dynamic> public $%s", prop_name);
+ } else {
+ if (!(prop->flags & ZEND_ACC_STATIC)) {
+ if (prop->flags & ZEND_ACC_IMPLICIT_PUBLIC) {
+ string_write(str, "<implicit> ", sizeof("<implicit> ") - 1);
+ } else {
+ string_write(str, "<default> ", sizeof("<default> ") - 1);
+ }
+ }
+
+ /* These are mutually exclusive */
+ switch (prop->flags & ZEND_ACC_PPP_MASK) {
+ case ZEND_ACC_PUBLIC:
+ string_printf(str, "public ");
+ break;
+ case ZEND_ACC_PRIVATE:
+ string_printf(str, "private ");
+ break;
+ case ZEND_ACC_PROTECTED:
+ string_printf(str, "protected ");
+ break;
+ }
+ if(prop->flags & ZEND_ACC_STATIC) {
+ string_printf(str, "static ");
+ }
+
+ zend_unmangle_property_name(prop->name, prop->name_length, &class_name, (const char**)&prop_name);
+ string_printf(str, "$%s", prop_name);
+ }
+
+ string_printf(str, " ]\n");
+}
+/* }}} */
+
+static int _extension_ini_string(zend_ini_entry *ini_entry TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */
+{
+ string *str = va_arg(args, string *);
+ char *indent = va_arg(args, char *);
+ int number = va_arg(args, int);
+ char *comma = "";
+
+ if (number == ini_entry->module_number) {
+ string_printf(str, " %sEntry [ %s <", indent, ini_entry->name);
+ if (ini_entry->modifiable == ZEND_INI_ALL) {
+ string_printf(str, "ALL");
+ } else {
+ if (ini_entry->modifiable & ZEND_INI_USER) {
+ string_printf(str, "USER");
+ comma = ",";
+ }
+ if (ini_entry->modifiable & ZEND_INI_PERDIR) {
+ string_printf(str, "%sPERDIR", comma);
+ comma = ",";
+ }
+ if (ini_entry->modifiable & ZEND_INI_SYSTEM) {
+ string_printf(str, "%sSYSTEM", comma);
+ }
+ }
+
+ string_printf(str, "> ]\n");
+ string_printf(str, " %s Current = '%s'\n", indent, ini_entry->value ? ini_entry->value : "");
+ if (ini_entry->modified) {
+ string_printf(str, " %s Default = '%s'\n", indent, ini_entry->orig_value ? ini_entry->orig_value : "");
+ }
+ string_printf(str, " %s}\n", indent);
+ }
+ return ZEND_HASH_APPLY_KEEP;
+}
+/* }}} */
+
+static int _extension_class_string(zend_class_entry **pce TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */
+{
+ string *str = va_arg(args, string *);
+ char *indent = va_arg(args, char *);
+ struct _zend_module_entry *module = va_arg(args, struct _zend_module_entry*);
+ int *num_classes = va_arg(args, int*);
+
+ if (((*pce)->type == ZEND_INTERNAL_CLASS) && (*pce)->info.internal.module && !strcasecmp((*pce)->info.internal.module->name, module->name)) {
+ string_printf(str, "\n");
+ _class_string(str, *pce, NULL, indent TSRMLS_CC);
+ (*num_classes)++;
+ }
+ return ZEND_HASH_APPLY_KEEP;
+}
+/* }}} */
+
+static int _extension_const_string(zend_constant *constant TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */
+{
+ string *str = va_arg(args, string *);
+ char *indent = va_arg(args, char *);
+ struct _zend_module_entry *module = va_arg(args, struct _zend_module_entry*);
+ int *num_classes = va_arg(args, int*);
+
+ if (constant->module_number == module->module_number) {
+ _const_string(str, constant->name, &constant->value, indent TSRMLS_CC);
+ (*num_classes)++;
+ }
+ return ZEND_HASH_APPLY_KEEP;
+}
+/* }}} */
+
+/* {{{ _extension_string */
+static void _extension_string(string *str, zend_module_entry *module, char *indent TSRMLS_DC)
+{
+ string_printf(str, "%sExtension [ ", indent);
+ if (module->type == MODULE_PERSISTENT) {
+ string_printf(str, "<persistent>");
+ }
+ if (module->type == MODULE_TEMPORARY) {
+ string_printf(str, "<temporary>" );
+ }
+ string_printf(str, " extension #%d %s version %s ] {\n",
+ module->module_number, module->name,
+ (module->version == NO_VERSION_YET) ? "<no_version>" : module->version);
+
+ if (module->deps) {
+ const zend_module_dep* dep = module->deps;
+
+ string_printf(str, "\n - Dependencies {\n");
+
+ while(dep->name) {
+ string_printf(str, "%s Dependency [ %s (", indent, dep->name);
+
+ switch(dep->type) {
+ case MODULE_DEP_REQUIRED:
+ string_write(str, "Required", sizeof("Required") - 1);
+ break;
+ case MODULE_DEP_CONFLICTS:
+ string_write(str, "Conflicts", sizeof("Conflicts") - 1);
+ break;
+ case MODULE_DEP_OPTIONAL:
+ string_write(str, "Optional", sizeof("Optional") - 1);
+ break;
+ default:
+ string_write(str, "Error", sizeof("Error") - 1); /* shouldn't happen */
+ break;
+ }
+
+ if (dep->rel) {
+ string_printf(str, " %s", dep->rel);
+ }
+ if (dep->version) {
+ string_printf(str, " %s", dep->version);
+ }
+ string_write(str, ") ]\n", sizeof(") ]\n") - 1);
+ dep++;
+ }
+ string_printf(str, "%s }\n", indent);
+ }
+
+ {
+ string str_ini;
+ string_init(&str_ini);
+ zend_hash_apply_with_arguments(EG(ini_directives) TSRMLS_CC, (apply_func_args_t) _extension_ini_string, 3, &str_ini, indent, module->module_number);
+ if (str_ini.len > 1) {
+ string_printf(str, "\n - INI {\n");
+ string_append(str, &str_ini);
+ string_printf(str, "%s }\n", indent);
+ }
+ string_free(&str_ini);
+ }
+
+ {
+ string str_constants;
+ int num_constants = 0;
+
+ string_init(&str_constants);
+ zend_hash_apply_with_arguments(EG(zend_constants) TSRMLS_CC, (apply_func_args_t) _extension_const_string, 4, &str_constants, indent, module, &num_constants);
+ if (num_constants) {
+ string_printf(str, "\n - Constants [%d] {\n", num_constants);
+ string_append(str, &str_constants);
+ string_printf(str, "%s }\n", indent);
+ }
+ string_free(&str_constants);
+ }
+
+ if (module->functions && module->functions->fname) {
+ zend_function *fptr;
+ const zend_function_entry *func = module->functions;
+
+ string_printf(str, "\n - Functions {\n");
+
+ /* Is there a better way of doing this? */
+ while (func->fname) {
+ int fname_len = strlen(func->fname);
+ char *lc_name = zend_str_tolower_dup(func->fname, fname_len);
+
+ if (zend_hash_find(EG(function_table), lc_name, fname_len + 1, (void**) &fptr) == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Internal error: Cannot find extension function %s in global function table", func->fname);
+ func++;
+ efree(lc_name);
+ continue;
+ }
+
+ _function_string(str, fptr, NULL, " " TSRMLS_CC);
+ efree(lc_name);
+ func++;
+ }
+ string_printf(str, "%s }\n", indent);
+ }
+
+ {
+ string str_classes;
+ string sub_indent;
+ int num_classes = 0;
+
+ string_init(&sub_indent);
+ string_printf(&sub_indent, "%s ", indent);
+ string_init(&str_classes);
+ zend_hash_apply_with_arguments(EG(class_table) TSRMLS_CC, (apply_func_args_t) _extension_class_string, 4, &str_classes, sub_indent.string, module, &num_classes);
+ if (num_classes) {
+ string_printf(str, "\n - Classes [%d] {", num_classes);
+ string_append(str, &str_classes);
+ string_printf(str, "%s }\n", indent);
+ }
+ string_free(&str_classes);
+ string_free(&sub_indent);
+ }
+
+ string_printf(str, "%s}\n", indent);
+}
+/* }}} */
+
+static void _zend_extension_string(string *str, zend_extension *extension, char *indent TSRMLS_DC) /* {{{ */
+{
+ string_printf(str, "%sZend Extension [ %s ", indent, extension->name);
+
+ if (extension->version) {
+ string_printf(str, "%s ", extension->version);
+ }
+ if (extension->copyright) {
+ string_printf(str, "%s ", extension->copyright);
+ }
+ if (extension->author) {
+ string_printf(str, "by %s ", extension->author);
+ }
+ if (extension->URL) {
+ string_printf(str, "<%s> ", extension->URL);
+ }
+
+ string_printf(str, "]\n");
+}
+/* }}} */
+
+/* {{{ _function_check_flag */
+static void _function_check_flag(INTERNAL_FUNCTION_PARAMETERS, int mask)
+{
+ reflection_object *intern;
+ zend_function *mptr;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(mptr);
+ RETURN_BOOL(mptr->common.fn_flags & mask);
+}
+/* }}} */
+
+/* {{{ zend_reflection_class_factory */
+PHPAPI void zend_reflection_class_factory(zend_class_entry *ce, zval *object TSRMLS_DC)
+{
+ reflection_object *intern;
+ zval *name;
+
+ MAKE_STD_ZVAL(name);
+ ZVAL_STRINGL(name, ce->name, ce->name_length, 1);
+ reflection_instantiate(reflection_class_ptr, object TSRMLS_CC);
+ intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
+ intern->ptr = ce;
+ intern->ref_type = REF_TYPE_OTHER;
+ intern->ce = ce;
+ reflection_update_property(object, "name", name);
+}
+/* }}} */
+
+/* {{{ reflection_extension_factory */
+static void reflection_extension_factory(zval *object, const char *name_str TSRMLS_DC)
+{
+ reflection_object *intern;
+ zval *name;
+ int name_len = strlen(name_str);
+ char *lcname;
+ struct _zend_module_entry *module;
+ ALLOCA_FLAG(use_heap)
+
+ lcname = do_alloca(name_len + 1, use_heap);
+ zend_str_tolower_copy(lcname, name_str, name_len);
+ if (zend_hash_find(&module_registry, lcname, name_len + 1, (void **)&module) == FAILURE) {
+ free_alloca(lcname, use_heap);
+ return;
+ }
+ free_alloca(lcname, use_heap);
+
+ reflection_instantiate(reflection_extension_ptr, object TSRMLS_CC);
+ intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
+ MAKE_STD_ZVAL(name);
+ ZVAL_STRINGL(name, module->name, name_len, 1);
+ intern->ptr = module;
+ intern->ref_type = REF_TYPE_OTHER;
+ intern->ce = NULL;
+ reflection_update_property(object, "name", name);
+}
+/* }}} */
+
+/* {{{ reflection_parameter_factory */
+static void reflection_parameter_factory(zend_function *fptr, zval *closure_object, struct _zend_arg_info *arg_info, zend_uint offset, zend_uint required, zval *object TSRMLS_DC)
+{
+ reflection_object *intern;
+ parameter_reference *reference;
+ zval *name;
+
+ if (closure_object) {
+ Z_ADDREF_P(closure_object);
+ }
+ MAKE_STD_ZVAL(name);
+ if (arg_info->name) {
+ ZVAL_STRINGL(name, arg_info->name, arg_info->name_len, 1);
+ } else {
+ ZVAL_NULL(name);
+ }
+ reflection_instantiate(reflection_parameter_ptr, object TSRMLS_CC);
+ intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
+ 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->ref_type = REF_TYPE_PARAMETER;
+ intern->ce = fptr->common.scope;
+ intern->obj = closure_object;
+ reflection_update_property(object, "name", name);
+}
+/* }}} */
+
+/* {{{ reflection_function_factory */
+static void reflection_function_factory(zend_function *function, zval *closure_object, zval *object TSRMLS_DC)
+{
+ reflection_object *intern;
+ zval *name;
+
+ if (closure_object) {
+ Z_ADDREF_P(closure_object);
+ }
+ MAKE_STD_ZVAL(name);
+ ZVAL_STRING(name, function->common.function_name, 1);
+
+ reflection_instantiate(reflection_function_ptr, object TSRMLS_CC);
+ intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
+ intern->ptr = function;
+ intern->ref_type = REF_TYPE_FUNCTION;
+ intern->ce = NULL;
+ intern->obj = closure_object;
+ reflection_update_property(object, "name", name);
+}
+/* }}} */
+
+/* {{{ reflection_method_factory */
+static void reflection_method_factory(zend_class_entry *ce, zend_function *method, zval *closure_object, zval *object TSRMLS_DC)
+{
+ reflection_object *intern;
+ zval *name;
+ zval *classname;
+
+ if (closure_object) {
+ Z_ADDREF_P(closure_object);
+ }
+ MAKE_STD_ZVAL(name);
+ MAKE_STD_ZVAL(classname);
+ ZVAL_STRING(name, method->common.function_name, 1);
+ ZVAL_STRINGL(classname, method->common.scope->name, method->common.scope->name_length, 1);
+ reflection_instantiate(reflection_method_ptr, object TSRMLS_CC);
+ intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
+ intern->ptr = method;
+ intern->ref_type = REF_TYPE_FUNCTION;
+ intern->ce = ce;
+ intern->obj = closure_object;
+ reflection_update_property(object, "name", name);
+ reflection_update_property(object, "class", classname);
+}
+/* }}} */
+
+/* {{{ reflection_property_factory */
+static void reflection_property_factory(zend_class_entry *ce, zend_property_info *prop, zval *object TSRMLS_DC)
+{
+ reflection_object *intern;
+ zval *name;
+ zval *classname;
+ property_reference *reference;
+ const char *class_name, *prop_name;
+
+ zend_unmangle_property_name(prop->name, prop->name_length, &class_name, &prop_name);
+
+ if (!(prop->flags & ZEND_ACC_PRIVATE)) {
+ /* we have to search the class hierarchy for this (implicit) public or protected property */
+ zend_class_entry *tmp_ce = ce, *store_ce = ce;
+ zend_property_info *tmp_info = NULL;
+
+ while (tmp_ce && zend_hash_find(&tmp_ce->properties_info, prop_name, strlen(prop_name) + 1, (void **) &tmp_info) != SUCCESS) {
+ ce = tmp_ce;
+ tmp_ce = tmp_ce->parent;
+ }
+
+ if (tmp_info && !(tmp_info->flags & ZEND_ACC_SHADOW)) { /* found something and it's not a parent's private */
+ prop = tmp_info;
+ } else { /* not found, use initial value */
+ ce = store_ce;
+ }
+ }
+
+ MAKE_STD_ZVAL(name);
+ MAKE_STD_ZVAL(classname);
+ ZVAL_STRING(name, prop_name, 1);
+ ZVAL_STRINGL(classname, prop->ce->name, prop->ce->name_length, 1);
+
+ reflection_instantiate(reflection_property_ptr, object TSRMLS_CC);
+ intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
+ reference = (property_reference*) emalloc(sizeof(property_reference));
+ reference->ce = ce;
+ reference->prop = *prop;
+ intern->ptr = reference;
+ intern->ref_type = REF_TYPE_PROPERTY;
+ intern->ce = ce;
+ intern->ignore_visibility = 0;
+ reflection_update_property(object, "name", name);
+ reflection_update_property(object, "class", classname);
+}
+/* }}} */
+
+/* {{{ _reflection_export */
+static void _reflection_export(INTERNAL_FUNCTION_PARAMETERS, zend_class_entry *ce_ptr, int ctor_argc)
+{
+ zval *reflector_ptr;
+ zval output, *output_ptr = &output;
+ zval *argument_ptr, *argument2_ptr;
+ zval *retval_ptr, **params[2];
+ int result;
+ int return_output = 0;
+ zend_fcall_info fci;
+ zend_fcall_info_cache fcc;
+ zval fname;
+
+ if (ctor_argc == 1) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|b", &argument_ptr, &return_output) == FAILURE) {
+ return;
+ }
+ } else {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz|b", &argument_ptr, &argument2_ptr, &return_output) == FAILURE) {
+ return;
+ }
+ }
+
+ INIT_PZVAL(&output);
+
+ /* Create object */
+ MAKE_STD_ZVAL(reflector_ptr);
+ if (object_and_properties_init(reflector_ptr, ce_ptr, NULL) == FAILURE) {
+ _DO_THROW("Could not create reflector");
+ }
+
+ /* Call __construct() */
+ params[0] = &argument_ptr;
+ params[1] = &argument2_ptr;
+
+ fci.size = sizeof(fci);
+ fci.function_table = NULL;
+ fci.function_name = NULL;
+ fci.symbol_table = NULL;
+ fci.object_ptr = reflector_ptr;
+ fci.retval_ptr_ptr = &retval_ptr;
+ fci.param_count = ctor_argc;
+ fci.params = params;
+ fci.no_separation = 1;
+
+ fcc.initialized = 1;
+ fcc.function_handler = ce_ptr->constructor;
+ fcc.calling_scope = ce_ptr;
+ fcc.called_scope = Z_OBJCE_P(reflector_ptr);
+ fcc.object_ptr = reflector_ptr;
+
+ result = zend_call_function(&fci, &fcc TSRMLS_CC);
+
+ if (retval_ptr) {
+ zval_ptr_dtor(&retval_ptr);
+ }
+
+ if (EG(exception)) {
+ zval_ptr_dtor(&reflector_ptr);
+ return;
+ }
+ if (result == FAILURE) {
+ zval_ptr_dtor(&reflector_ptr);
+ _DO_THROW("Could not create reflector");
+ }
+
+ /* Call static reflection::export */
+ ZVAL_BOOL(&output, return_output);
+ params[0] = &reflector_ptr;
+ params[1] = &output_ptr;
+
+ ZVAL_STRINGL(&fname, "reflection::export", sizeof("reflection::export") - 1, 0);
+ fci.function_table = &reflection_ptr->function_table;
+ fci.function_name = &fname;
+ fci.object_ptr = NULL;
+ fci.retval_ptr_ptr = &retval_ptr;
+ fci.param_count = 2;
+ fci.params = params;
+ fci.no_separation = 1;
+
+ result = zend_call_function(&fci, NULL TSRMLS_CC);
+
+ if (result == FAILURE && EG(exception) == NULL) {
+ zval_ptr_dtor(&reflector_ptr);
+ zval_ptr_dtor(&retval_ptr);
+ _DO_THROW("Could not execute reflection::export()");
+ }
+
+ if (return_output) {
+ COPY_PZVAL_TO_ZVAL(*return_value, retval_ptr);
+ } else {
+ zval_ptr_dtor(&retval_ptr);
+ }
+
+ /* Destruct reflector which is no longer needed */
+ zval_ptr_dtor(&reflector_ptr);
+}
+/* }}} */
+
+/* {{{ _reflection_param_get_default_param */
+static parameter_reference *_reflection_param_get_default_param(INTERNAL_FUNCTION_PARAMETERS)
+{
+ reflection_object *intern;
+ parameter_reference *param;
+
+ intern = (reflection_object *) zend_object_store_get_object(getThis() TSRMLS_CC);
+ if (intern == NULL || intern->ptr == NULL) {
+ if (EG(exception) && Z_OBJCE_P(EG(exception)) == reflection_exception_ptr) {
+ return NULL;
+ }
+ php_error_docref(NULL TSRMLS_CC, E_ERROR, "Internal error: Failed to retrieve the reflection object");
+ }
+
+ param = intern->ptr;
+ 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 NULL;
+ }
+
+ return param;
+}
+/* }}} */
+
+/* {{{ _reflection_param_get_default_precv */
+static zend_op *_reflection_param_get_default_precv(INTERNAL_FUNCTION_PARAMETERS, parameter_reference *param)
+{
+ zend_op *precv;
+
+ if (param == NULL) {
+ return NULL;
+ }
+
+ precv = _get_recv_op((zend_op_array*)param->fptr, param->offset);
+ if (!precv || precv->opcode != ZEND_RECV_INIT || precv->op2_type == IS_UNUSED) {
+ zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Internal error: Failed to retrieve the default value");
+ return NULL;
+ }
+
+ return precv;
+}
+/* }}} */
+
+/* {{{ Preventing __clone from being called */
+ZEND_METHOD(reflection, __clone)
+{
+ /* Should never be executable */
+ _DO_THROW("Cannot clone object using __clone()");
+}
+/* }}} */
+
+/* {{{ proto public static mixed Reflection::export(Reflector r [, bool return])
+ Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */
+ZEND_METHOD(reflection, export)
+{
+ zval *object, fname, *retval_ptr;
+ int result;
+ zend_bool return_output = 0;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|b", &object, reflector_ptr, &return_output) == FAILURE) {
+ return;
+ }
+
+ /* Invoke the __toString() method */
+ ZVAL_STRINGL(&fname, "__tostring", sizeof("__tostring") - 1, 1);
+ result= call_user_function_ex(NULL, &object, &fname, &retval_ptr, 0, NULL, 0, NULL TSRMLS_CC);
+ zval_dtor(&fname);
+
+ if (result == FAILURE) {
+ _DO_THROW("Invocation of method __toString() failed");
+ /* Returns from this function */
+ }
+
+ if (!retval_ptr) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s::__toString() did not return anything", Z_OBJCE_P(object)->name);
+ RETURN_FALSE;
+ }
+
+ if (return_output) {
+ COPY_PZVAL_TO_ZVAL(*return_value, retval_ptr);
+ } else {
+ /* No need for _r variant, return of __toString should always be a string */
+ zend_print_zval(retval_ptr, 0);
+ zend_printf("\n");
+ zval_ptr_dtor(&retval_ptr);
+ }
+}
+/* }}} */
+
+/* {{{ proto public static array Reflection::getModifierNames(int modifiers)
+ Returns an array of modifier names */
+ZEND_METHOD(reflection, getModifierNames)
+{
+ long modifiers;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &modifiers) == FAILURE) {
+ return;
+ }
+
+ array_init(return_value);
+
+ if (modifiers & (ZEND_ACC_ABSTRACT | ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) {
+ add_next_index_stringl(return_value, "abstract", sizeof("abstract")-1, 1);
+ }
+ if (modifiers & (ZEND_ACC_FINAL | ZEND_ACC_FINAL_CLASS)) {
+ add_next_index_stringl(return_value, "final", sizeof("final")-1, 1);
+ }
+ if (modifiers & ZEND_ACC_IMPLICIT_PUBLIC) {
+ add_next_index_stringl(return_value, "public", sizeof("public")-1, 1);
+ }
+
+ /* These are mutually exclusive */
+ switch (modifiers & ZEND_ACC_PPP_MASK) {
+ case ZEND_ACC_PUBLIC:
+ add_next_index_stringl(return_value, "public", sizeof("public")-1, 1);
+ break;
+ case ZEND_ACC_PRIVATE:
+ add_next_index_stringl(return_value, "private", sizeof("private")-1, 1);
+ break;
+ case ZEND_ACC_PROTECTED:
+ add_next_index_stringl(return_value, "protected", sizeof("protected")-1, 1);
+ break;
+ }
+
+ if (modifiers & ZEND_ACC_STATIC) {
+ add_next_index_stringl(return_value, "static", sizeof("static")-1, 1);
+ }
+}
+/* }}} */
+
+/* {{{ proto public static mixed ReflectionFunction::export(string name [, bool return])
+ Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */
+ZEND_METHOD(reflection_function, export)
+{
+ _reflection_export(INTERNAL_FUNCTION_PARAM_PASSTHRU, reflection_function_ptr, 1);
+}
+/* }}} */
+
+/* {{{ proto public void ReflectionFunction::__construct(string name)
+ Constructor. Throws an Exception in case the given function does not exist */
+ZEND_METHOD(reflection_function, __construct)
+{
+ zval *name;
+ zval *object;
+ zval *closure = NULL;
+ char *lcname;
+ reflection_object *intern;
+ zend_function *fptr;
+ char *name_str;
+ int name_len;
+
+ object = getThis();
+ intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
+ if (intern == NULL) {
+ return;
+ }
+
+ if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "O", &closure, zend_ce_closure) == SUCCESS) {
+ fptr = (zend_function*)zend_get_closure_method_def(closure TSRMLS_CC);
+ Z_ADDREF_P(closure);
+ } else if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name_str, &name_len) == SUCCESS) {
+ char *nsname;
+
+ lcname = zend_str_tolower_dup(name_str, name_len);
+
+ /* Ignore leading "\" */
+ nsname = lcname;
+ if (lcname[0] == '\\') {
+ nsname = &lcname[1];
+ name_len--;
+ }
+
+ if (zend_hash_find(EG(function_table), nsname, name_len + 1, (void **)&fptr) == FAILURE) {
+ efree(lcname);
+ zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
+ "Function %s() does not exist", name_str);
+ return;
+ }
+ efree(lcname);
+ } else {
+ return;
+ }
+
+ MAKE_STD_ZVAL(name);
+ ZVAL_STRING(name, fptr->common.function_name, 1);
+ reflection_update_property(object, "name", name);
+ intern->ptr = fptr;
+ intern->ref_type = REF_TYPE_FUNCTION;
+ intern->obj = closure;
+ intern->ce = NULL;
+}
+/* }}} */
+
+/* {{{ proto public string ReflectionFunction::__toString()
+ Returns a string representation */
+ZEND_METHOD(reflection_function, __toString)
+{
+ reflection_object *intern;
+ zend_function *fptr;
+ string str;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(fptr);
+ string_init(&str);
+ _function_string(&str, fptr, intern->ce, "" TSRMLS_CC);
+ RETURN_STRINGL(str.string, str.len - 1, 0);
+}
+/* }}} */
+
+/* {{{ proto public string ReflectionFunction::getName()
+ Returns this function's name */
+ZEND_METHOD(reflection_function, getName)
+{
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ _default_get_entry(getThis(), "name", sizeof("name"), return_value TSRMLS_CC);
+}
+/* }}} */
+
+/* {{{ proto public bool ReflectionFunction::isClosure()
+ Returns whether this is a closure */
+ZEND_METHOD(reflection_function, isClosure)
+{
+ reflection_object *intern;
+ zend_function *fptr;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(fptr);
+ RETURN_BOOL(fptr->common.fn_flags & ZEND_ACC_CLOSURE);
+}
+/* }}} */
+
+/* {{{ proto public bool ReflectionFunction::getClosureThis()
+ Returns this pointer bound to closure */
+ZEND_METHOD(reflection_function, getClosureThis)
+{
+ reflection_object *intern;
+ zend_function *fptr;
+ zval* closure_this;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(fptr);
+ if (intern->obj) {
+ closure_this = zend_get_closure_this_ptr(intern->obj TSRMLS_CC);
+ if (closure_this) {
+ RETURN_ZVAL(closure_this, 1, 0);
+ }
+ }
+}
+/* }}} */
+
+/* {{{ proto public ReflectionClass ReflectionFunction::getClosureScopeClass()
+ Returns the scope associated to the closure */
+ZEND_METHOD(reflection_function, getClosureScopeClass)
+{
+ reflection_object *intern;
+ zend_function *fptr;
+ const zend_function *closure_func;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(fptr);
+ if (intern->obj) {
+ closure_func = zend_get_closure_method_def(intern->obj TSRMLS_CC);
+ if (closure_func && closure_func->common.scope) {
+ zend_reflection_class_factory(closure_func->common.scope, return_value TSRMLS_CC);
+ }
+ }
+}
+/* }}} */
+
+/* {{{ proto public mixed ReflectionFunction::getClosure()
+ Returns a dynamically created closure for the function */
+ZEND_METHOD(reflection_function, getClosure)
+{
+ reflection_object *intern;
+ zend_function *fptr;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(fptr);
+
+ zend_create_closure(return_value, fptr, NULL, NULL TSRMLS_CC);
+}
+/* }}} */
+
+
+/* {{{ proto public bool ReflectionFunction::isInternal()
+ Returns whether this is an internal function */
+ZEND_METHOD(reflection_function, isInternal)
+{
+ reflection_object *intern;
+ zend_function *fptr;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(fptr);
+ RETURN_BOOL(fptr->type == ZEND_INTERNAL_FUNCTION);
+}
+/* }}} */
+
+/* {{{ proto public bool ReflectionFunction::isUserDefined()
+ Returns whether this is an user-defined function */
+ZEND_METHOD(reflection_function, isUserDefined)
+{
+ reflection_object *intern;
+ zend_function *fptr;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(fptr);
+ RETURN_BOOL(fptr->type == ZEND_USER_FUNCTION);
+}
+/* }}} */
+
+/* {{{ proto public bool ReflectionFunction::isDisabled()
+ Returns whether this function has been disabled or not */
+ZEND_METHOD(reflection_function, isDisabled)
+{
+ reflection_object *intern;
+ zend_function *fptr;
+
+ METHOD_NOTSTATIC(reflection_function_ptr);
+ GET_REFLECTION_OBJECT_PTR(fptr);
+ RETURN_BOOL(fptr->type == ZEND_INTERNAL_FUNCTION && fptr->internal_function.handler == zif_display_disabled_function);
+}
+/* }}} */
+
+/* {{{ proto public string ReflectionFunction::getFileName()
+ Returns the filename of the file this function was declared in */
+ZEND_METHOD(reflection_function, getFileName)
+{
+ reflection_object *intern;
+ zend_function *fptr;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(fptr);
+ if (fptr->type == ZEND_USER_FUNCTION) {
+ RETURN_STRING(fptr->op_array.filename, 1);
+ }
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto public int ReflectionFunction::getStartLine()
+ Returns the line this function's declaration starts at */
+ZEND_METHOD(reflection_function, getStartLine)
+{
+ reflection_object *intern;
+ zend_function *fptr;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(fptr);
+ if (fptr->type == ZEND_USER_FUNCTION) {
+ RETURN_LONG(fptr->op_array.line_start);
+ }
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto public int ReflectionFunction::getEndLine()
+ Returns the line this function's declaration ends at */
+ZEND_METHOD(reflection_function, getEndLine)
+{
+ reflection_object *intern;
+ zend_function *fptr;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(fptr);
+ if (fptr->type == ZEND_USER_FUNCTION) {
+ RETURN_LONG(fptr->op_array.line_end);
+ }
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto public string ReflectionFunction::getDocComment()
+ Returns the doc comment for this function */
+ZEND_METHOD(reflection_function, getDocComment)
+{
+ reflection_object *intern;
+ zend_function *fptr;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(fptr);
+ if (fptr->type == ZEND_USER_FUNCTION && fptr->op_array.doc_comment) {
+ RETURN_STRINGL(fptr->op_array.doc_comment, fptr->op_array.doc_comment_len, 1);
+ }
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto public array ReflectionFunction::getStaticVariables()
+ Returns an associative array containing this function's static variables and their values */
+ZEND_METHOD(reflection_function, getStaticVariables)
+{
+ zval *tmp_copy;
+ reflection_object *intern;
+ zend_function *fptr;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(fptr);
+
+ /* Return an empty array in case no static variables exist */
+ array_init(return_value);
+ if (fptr->type == ZEND_USER_FUNCTION && fptr->op_array.static_variables != NULL) {
+ zend_hash_apply_with_argument(fptr->op_array.static_variables, (apply_func_arg_t) zval_update_constant_inline_change, fptr->common.scope TSRMLS_CC);
+ zend_hash_copy(Z_ARRVAL_P(return_value), fptr->op_array.static_variables, (copy_ctor_func_t) zval_add_ref, (void *) &tmp_copy, sizeof(zval *));
+ }
+}
+/* }}} */
+
+/* {{{ proto public mixed ReflectionFunction::invoke([mixed* args])
+ Invokes the function */
+ZEND_METHOD(reflection_function, invoke)
+{
+ zval *retval_ptr;
+ zval ***params = NULL;
+ int result, num_args = 0;
+ zend_fcall_info fci;
+ zend_fcall_info_cache fcc;
+ reflection_object *intern;
+ zend_function *fptr;
+
+ METHOD_NOTSTATIC(reflection_function_ptr);
+ GET_REFLECTION_OBJECT_PTR(fptr);
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "*", &params, &num_args) == FAILURE) {
+ return;
+ }
+
+ fci.size = sizeof(fci);
+ fci.function_table = NULL;
+ fci.function_name = NULL;
+ fci.symbol_table = NULL;
+ fci.object_ptr = NULL;
+ fci.retval_ptr_ptr = &retval_ptr;
+ fci.param_count = num_args;
+ fci.params = params;
+ fci.no_separation = 1;
+
+ fcc.initialized = 1;
+ fcc.function_handler = fptr;
+ fcc.calling_scope = EG(scope);
+ fcc.called_scope = NULL;
+ fcc.object_ptr = NULL;
+
+ result = zend_call_function(&fci, &fcc TSRMLS_CC);
+
+ if (num_args) {
+ efree(params);
+ }
+
+ if (result == FAILURE) {
+ zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
+ "Invocation of function %s() failed", fptr->common.function_name);
+ return;
+ }
+
+ if (retval_ptr) {
+ COPY_PZVAL_TO_ZVAL(*return_value, retval_ptr);
+ }
+}
+/* }}} */
+
+static int _zval_array_to_c_array(zval **arg, zval ****params TSRMLS_DC) /* {{{ */
+{
+ *(*params)++ = arg;
+ return ZEND_HASH_APPLY_KEEP;
+} /* }}} */
+
+/* {{{ proto public mixed ReflectionFunction::invokeArgs(array args)
+ Invokes the function and pass its arguments as array. */
+ZEND_METHOD(reflection_function, invokeArgs)
+{
+ zval *retval_ptr;
+ zval ***params;
+ int result;
+ int argc;
+ zend_fcall_info fci;
+ zend_fcall_info_cache fcc;
+ reflection_object *intern;
+ zend_function *fptr;
+ zval *param_array;
+
+ METHOD_NOTSTATIC(reflection_function_ptr);
+ GET_REFLECTION_OBJECT_PTR(fptr);
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &param_array) == FAILURE) {
+ return;
+ }
+
+ argc = zend_hash_num_elements(Z_ARRVAL_P(param_array));
+
+ params = safe_emalloc(sizeof(zval **), argc, 0);
+ zend_hash_apply_with_argument(Z_ARRVAL_P(param_array), (apply_func_arg_t)_zval_array_to_c_array, &params TSRMLS_CC);
+ params -= argc;
+
+ fci.size = sizeof(fci);
+ fci.function_table = NULL;
+ fci.function_name = NULL;
+ fci.symbol_table = NULL;
+ fci.object_ptr = NULL;
+ fci.retval_ptr_ptr = &retval_ptr;
+ fci.param_count = argc;
+ fci.params = params;
+ fci.no_separation = 1;
+
+ fcc.initialized = 1;
+ fcc.function_handler = fptr;
+ fcc.calling_scope = EG(scope);
+ fcc.called_scope = NULL;
+ fcc.object_ptr = NULL;
+
+ result = zend_call_function(&fci, &fcc TSRMLS_CC);
+
+ efree(params);
+
+ if (result == FAILURE) {
+ zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
+ "Invocation of function %s() failed", fptr->common.function_name);
+ return;
+ }
+
+ if (retval_ptr) {
+ COPY_PZVAL_TO_ZVAL(*return_value, retval_ptr);
+ }
+}
+/* }}} */
+
+/* {{{ proto public bool ReflectionFunction::returnsReference()
+ Gets whether this function returns a reference */
+ZEND_METHOD(reflection_function, returnsReference)
+{
+ reflection_object *intern;
+ zend_function *fptr;
+
+ METHOD_NOTSTATIC(reflection_function_abstract_ptr);
+ GET_REFLECTION_OBJECT_PTR(fptr);
+
+ RETURN_BOOL((fptr->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0);
+}
+/* }}} */
+
+/* {{{ proto public bool ReflectionFunction::getNumberOfParameters()
+ Gets the number of required parameters */
+ZEND_METHOD(reflection_function, getNumberOfParameters)
+{
+ reflection_object *intern;
+ zend_function *fptr;
+
+ METHOD_NOTSTATIC(reflection_function_abstract_ptr);
+ 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(reflection_function_abstract_ptr);
+ GET_REFLECTION_OBJECT_PTR(fptr);
+
+ RETURN_LONG(fptr->common.required_num_args);
+}
+/* }}} */
+
+/* {{{ proto public ReflectionParameter[] ReflectionFunction::getParameters()
+ Returns an array of parameter objects for this function */
+ZEND_METHOD(reflection_function, getParameters)
+{
+ reflection_object *intern;
+ zend_function *fptr;
+ zend_uint i;
+ struct _zend_arg_info *arg_info;
+
+ METHOD_NOTSTATIC(reflection_function_abstract_ptr);
+ GET_REFLECTION_OBJECT_PTR(fptr);
+
+ arg_info= fptr->common.arg_info;
+
+ array_init(return_value);
+ for (i = 0; i < fptr->common.num_args; i++) {
+ zval *parameter;
+
+ ALLOC_ZVAL(parameter);
+ reflection_parameter_factory(_copy_function(fptr TSRMLS_CC), intern->obj, arg_info, i, fptr->common.required_num_args, parameter TSRMLS_CC);
+ add_next_index_zval(return_value, parameter);
+
+ arg_info++;
+ }
+}
+/* }}} */
+
+/* {{{ proto public ReflectionExtension|NULL ReflectionFunction::getExtension()
+ Returns NULL or the extension the function belongs to */
+ZEND_METHOD(reflection_function, getExtension)
+{
+ reflection_object *intern;
+ zend_function *fptr;
+ zend_internal_function *internal;
+
+ METHOD_NOTSTATIC(reflection_function_abstract_ptr);
+ GET_REFLECTION_OBJECT_PTR(fptr);
+
+ if (fptr->type != ZEND_INTERNAL_FUNCTION) {
+ RETURN_NULL();
+ }
+
+ internal = (zend_internal_function *)fptr;
+ if (internal->module) {
+ reflection_extension_factory(return_value, internal->module->name TSRMLS_CC);
+ } else {
+ RETURN_NULL();
+ }
+}
+/* }}} */
+
+/* {{{ proto public string|false ReflectionFunction::getExtensionName()
+ Returns false or the name of the extension the function belongs to */
+ZEND_METHOD(reflection_function, getExtensionName)
+{
+ reflection_object *intern;
+ zend_function *fptr;
+ zend_internal_function *internal;
+
+ METHOD_NOTSTATIC(reflection_function_abstract_ptr);
+ GET_REFLECTION_OBJECT_PTR(fptr);
+
+ if (fptr->type != ZEND_INTERNAL_FUNCTION) {
+ RETURN_FALSE;
+ }
+
+ internal = (zend_internal_function *)fptr;
+ if (internal->module) {
+ RETURN_STRING(internal->module->name, 1);
+ } else {
+ RETURN_FALSE;
+ }
+}
+/* }}} */
+
+/* {{{ proto public static mixed ReflectionParameter::export(mixed function, mixed parameter [, bool return]) throws ReflectionException
+ Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */
+ZEND_METHOD(reflection_parameter, export)
+{
+ _reflection_export(INTERNAL_FUNCTION_PARAM_PASSTHRU, reflection_parameter_ptr, 2);
+}
+/* }}} */
+
+/* {{{ proto public void ReflectionParameter::__construct(mixed function, mixed parameter)
+ Constructor. Throws an Exception in case the given method does not exist */
+ZEND_METHOD(reflection_parameter, __construct)
+{
+ parameter_reference *ref;
+ zval *reference, **parameter;
+ zval *object;
+ zval *name;
+ reflection_object *intern;
+ zend_function *fptr;
+ struct _zend_arg_info *arg_info;
+ int position;
+ zend_class_entry *ce = NULL;
+ zend_bool is_closure = 0;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zZ", &reference, &parameter) == FAILURE) {
+ return;
+ }
+
+ object = getThis();
+ intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
+ if (intern == NULL) {
+ return;
+ }
+
+ /* First, find the function */
+ switch (Z_TYPE_P(reference)) {
+ case IS_STRING: {
+ unsigned int lcname_len;
+ char *lcname;
+
+ lcname_len = Z_STRLEN_P(reference);
+ lcname = zend_str_tolower_dup(Z_STRVAL_P(reference), lcname_len);
+ if (zend_hash_find(EG(function_table), lcname, lcname_len + 1, (void**) &fptr) == FAILURE) {
+ efree(lcname);
+ zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
+ "Function %s() does not exist", Z_STRVAL_P(reference));
+ return;
+ }
+ efree(lcname);
+ }
+ ce = fptr->common.scope;
+ break;
+
+ case IS_ARRAY: {
+ zval **classref;
+ zval **method;
+ zend_class_entry **pce;
+ unsigned int lcname_len;
+ char *lcname;
+
+ if ((zend_hash_index_find(Z_ARRVAL_P(reference), 0, (void **) &classref) == FAILURE)
+ || (zend_hash_index_find(Z_ARRVAL_P(reference), 1, (void **) &method) == FAILURE))
+ {
+ _DO_THROW("Expected array($object, $method) or array($classname, $method)");
+ /* returns out of this function */
+ }
+
+ if (Z_TYPE_PP(classref) == IS_OBJECT) {
+ ce = Z_OBJCE_PP(classref);
+ } else {
+ convert_to_string_ex(classref);
+ if (zend_lookup_class(Z_STRVAL_PP(classref), Z_STRLEN_PP(classref), &pce TSRMLS_CC) == FAILURE) {
+ zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
+ "Class %s does not exist", Z_STRVAL_PP(classref));
+ return;
+ }
+ ce = *pce;
+ }
+
+ convert_to_string_ex(method);
+ lcname_len = Z_STRLEN_PP(method);
+ lcname = zend_str_tolower_dup(Z_STRVAL_PP(method), lcname_len);
+ if (ce == zend_ce_closure && Z_TYPE_PP(classref) == IS_OBJECT
+ && (lcname_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1)
+ && memcmp(lcname, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0
+ && (fptr = zend_get_closure_invoke_method(*classref TSRMLS_CC)) != NULL)
+ {
+ /* nothing to do. don't set is_closure since is the invoke handler,
+- not the closure itself */
+ } else if (zend_hash_find(&ce->function_table, lcname, lcname_len + 1, (void **) &fptr) == FAILURE) {
+ efree(lcname);
+ zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
+ "Method %s::%s() does not exist", ce->name, Z_STRVAL_PP(method));
+ return;
+ }
+ efree(lcname);
+ }
+ break;
+
+ case IS_OBJECT: {
+ ce = Z_OBJCE_P(reference);
+
+ if (instanceof_function(ce, zend_ce_closure TSRMLS_CC)) {
+ fptr = (zend_function *)zend_get_closure_method_def(reference TSRMLS_CC);
+ Z_ADDREF_P(reference);
+ is_closure = 1;
+ } else if (zend_hash_find(&ce->function_table, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME), (void **)&fptr) == FAILURE) {
+ zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
+ "Method %s::%s() does not exist", ce->name, ZEND_INVOKE_FUNC_NAME);
+ return;
+ }
+ }
+ break;
+
+ default:
+ _DO_THROW("The parameter class is expected to be either a string, an array(class, method) or a callable object");
+ /* returns out of this function */
+ }
+
+ /* Now, search for the parameter */
+ arg_info = fptr->common.arg_info;
+ if (Z_TYPE_PP(parameter) == IS_LONG) {
+ position= Z_LVAL_PP(parameter);
+ if (position < 0 || (zend_uint)position >= fptr->common.num_args) {
+ if (fptr->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) {
+ if (fptr->type != ZEND_OVERLOADED_FUNCTION) {
+ efree((char*)fptr->common.function_name);
+ }
+ efree(fptr);
+ }
+ if (is_closure) {
+ zval_ptr_dtor(&reference);
+ }
+ _DO_THROW("The parameter specified by its offset could not be found");
+ /* returns out of this function */
+ }
+ } else {
+ zend_uint i;
+
+ position= -1;
+ convert_to_string_ex(parameter);
+ for (i = 0; i < fptr->common.num_args; i++) {
+ if (arg_info[i].name && strcmp(arg_info[i].name, Z_STRVAL_PP(parameter)) == 0) {
+ position= i;
+ break;
+ }
+ }
+ if (position == -1) {
+ if (fptr->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) {
+ if (fptr->type != ZEND_OVERLOADED_FUNCTION) {
+ efree((char*)fptr->common.function_name);
+ }
+ efree(fptr);
+ }
+ if (is_closure) {
+ zval_ptr_dtor(&reference);
+ }
+ _DO_THROW("The parameter specified by its name could not be found");
+ /* returns out of this function */
+ }
+ }
+
+ MAKE_STD_ZVAL(name);
+ if (arg_info[position].name) {
+ ZVAL_STRINGL(name, arg_info[position].name, arg_info[position].name_len, 1);
+ } else {
+ ZVAL_NULL(name);
+ }
+ reflection_update_property(object, "name", name);
+
+ ref = (parameter_reference*) emalloc(sizeof(parameter_reference));
+ ref->arg_info = &arg_info[position];
+ ref->offset = (zend_uint)position;
+ ref->required = fptr->common.required_num_args;
+ ref->fptr = fptr;
+ /* TODO: copy fptr */
+ intern->ptr = ref;
+ intern->ref_type = REF_TYPE_PARAMETER;
+ intern->ce = ce;
+ if (reference && is_closure) {
+ intern->obj = reference;
+ }
+}
+/* }}} */
+
+/* {{{ proto public string ReflectionParameter::__toString()
+ Returns a string representation */
+ZEND_METHOD(reflection_parameter, __toString)
+{
+ reflection_object *intern;
+ parameter_reference *param;
+ string str;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(param);
+ string_init(&str);
+ _parameter_string(&str, param->fptr, param->arg_info, param->offset, param->required, "" TSRMLS_CC);
+ RETURN_STRINGL(str.string, str.len - 1, 0);
+}
+/* }}} */
+
+/* {{{ proto public string ReflectionParameter::getName()
+ Returns this parameters's name */
+ZEND_METHOD(reflection_parameter, getName)
+{
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ _default_get_entry(getThis(), "name", sizeof("name"), return_value TSRMLS_CC);
+}
+/* }}} */
+
+/* {{{ proto public ReflectionFunction ReflectionParameter::getDeclaringFunction()
+ Returns the ReflectionFunction for the function of this parameter */
+ZEND_METHOD(reflection_parameter, getDeclaringFunction)
+{
+ reflection_object *intern;
+ parameter_reference *param;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(param);
+
+ if (!param->fptr->common.scope) {
+ reflection_function_factory(_copy_function(param->fptr TSRMLS_CC), intern->obj, return_value TSRMLS_CC);
+ } else {
+ reflection_method_factory(param->fptr->common.scope, _copy_function(param->fptr TSRMLS_CC), intern->obj, return_value TSRMLS_CC);
+ }
+}
+/* }}} */
+
+/* {{{ proto public ReflectionClass|NULL ReflectionParameter::getDeclaringClass()
+ Returns in which class this parameter is defined (not the typehint of the parameter) */
+ZEND_METHOD(reflection_parameter, getDeclaringClass)
+{
+ reflection_object *intern;
+ parameter_reference *param;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(param);
+
+ if (param->fptr->common.scope) {
+ zend_reflection_class_factory(param->fptr->common.scope, return_value TSRMLS_CC);
+ }
+}
+/* }}} */
+
+/* {{{ proto public ReflectionClass|NULL ReflectionParameter::getClass()
+ Returns this parameters's class hint or NULL if there is none */
+ZEND_METHOD(reflection_parameter, getClass)
+{
+ reflection_object *intern;
+ parameter_reference *param;
+ zend_class_entry **pce, *ce;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(param);
+
+ if (param->arg_info->class_name) {
+ /* Class name is stored as a string, we might also get "self" or "parent"
+ * - For "self", simply use the function scope. If scope is NULL then
+ * the function is global and thus self does not make any sense
+ *
+ * - For "parent", use the function scope's parent. If scope is NULL then
+ * the function is global and thus parent does not make any sense.
+ * If the parent is NULL then the class does not extend anything and
+ * thus parent does not make any sense, either.
+ *
+ * TODO: Think about moving these checks to the compiler or some sort of
+ * lint-mode.
+ */
+ if (0 == zend_binary_strcasecmp(param->arg_info->class_name, param->arg_info->class_name_len, "self", sizeof("self")- 1)) {
+ ce = param->fptr->common.scope;
+ if (!ce) {
+ zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
+ "Parameter uses 'self' as type hint but function is not a class member!");
+ return;
+ }
+ pce= &ce;
+ } else if (0 == zend_binary_strcasecmp(param->arg_info->class_name, param->arg_info->class_name_len, "parent", sizeof("parent")- 1)) {
+ ce = param->fptr->common.scope;
+ if (!ce) {
+ zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
+ "Parameter uses 'parent' as type hint but function is not a class member!");
+ return;
+ }
+ if (!ce->parent) {
+ zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
+ "Parameter uses 'parent' as type hint although class does not have a parent!");
+ return;
+ }
+ pce= &ce->parent;
+ } else if (zend_lookup_class(param->arg_info->class_name, param->arg_info->class_name_len, &pce TSRMLS_CC) == FAILURE) {
+ zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
+ "Class %s does not exist", param->arg_info->class_name);
+ return;
+ }
+ zend_reflection_class_factory(*pce, return_value TSRMLS_CC);
+ }
+}
+/* }}} */
+
+/* {{{ proto public bool ReflectionParameter::isArray()
+ Returns whether parameter MUST be an array */
+ZEND_METHOD(reflection_parameter, isArray)
+{
+ reflection_object *intern;
+ parameter_reference *param;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(param);
+
+ RETVAL_BOOL(param->arg_info->type_hint == IS_ARRAY);
+}
+/* }}} */
+
+/* {{{ proto public bool ReflectionParameter::isCallable()
+ Returns whether parameter MUST be callable */
+ZEND_METHOD(reflection_parameter, isCallable)
+{
+ reflection_object *intern;
+ parameter_reference *param;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(param);
+
+ RETVAL_BOOL(param->arg_info->type_hint == IS_CALLABLE);
+}
+/* }}} */
+
+/* {{{ proto public bool ReflectionParameter::allowsNull()
+ Returns whether NULL is allowed as this parameters's value */
+ZEND_METHOD(reflection_parameter, allowsNull)
+{
+ reflection_object *intern;
+ parameter_reference *param;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(param);
+
+ RETVAL_BOOL(param->arg_info->allow_null);
+}
+/* }}} */
+
+/* {{{ proto public bool ReflectionParameter::isPassedByReference()
+ Returns whether this parameters is passed to by reference */
+ZEND_METHOD(reflection_parameter, isPassedByReference)
+{
+ reflection_object *intern;
+ parameter_reference *param;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(param);
+
+ RETVAL_BOOL(param->arg_info->pass_by_reference);
+}
+/* }}} */
+
+/* {{{ proto public bool ReflectionParameter::canBePassedByValue()
+ Returns whether this parameter can be passed by value */
+ZEND_METHOD(reflection_parameter, canBePassedByValue)
+{
+ reflection_object *intern;
+ parameter_reference *param;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(param);
+
+ /* true if it's ZEND_SEND_BY_VAL or ZEND_SEND_PREFER_REF */
+ RETVAL_BOOL(param->arg_info->pass_by_reference != ZEND_SEND_BY_REF);
+}
+/* }}} */
+
+/* {{{ proto public bool ReflectionParameter::getPosition()
+ Returns whether this parameter is an optional parameter */
+ZEND_METHOD(reflection_parameter, getPosition)
+{
+ reflection_object *intern;
+ parameter_reference *param;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(param);
+
+ RETVAL_LONG(param->offset);
+}
+/* }}} */
+
+/* {{{ proto public bool ReflectionParameter::isOptional()
+ Returns whether this parameter is an optional parameter */
+ZEND_METHOD(reflection_parameter, isOptional)
+{
+ reflection_object *intern;
+ parameter_reference *param;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ 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;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(param);
+
+ if (param->fptr->type != ZEND_USER_FUNCTION)
+ {
+ RETURN_FALSE;
+ }
+
+ precv = _get_recv_op((zend_op_array*)param->fptr, param->offset);
+ if (!precv || precv->opcode != ZEND_RECV_INIT || precv->op2_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)
+{
+ parameter_reference *param;
+ zend_op *precv;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+
+ param = _reflection_param_get_default_param(INTERNAL_FUNCTION_PARAM_PASSTHRU);
+ if (!param) {
+ return;
+ }
+
+ precv = _reflection_param_get_default_precv(INTERNAL_FUNCTION_PARAM_PASSTHRU, param);
+ if (!precv) {
+ return;
+ }
+
+ *return_value = *precv->op2.zv;
+ INIT_PZVAL(return_value);
+ if ((Z_TYPE_P(return_value) & IS_CONSTANT_TYPE_MASK) != IS_CONSTANT
+ && (Z_TYPE_P(return_value) & IS_CONSTANT_TYPE_MASK) != IS_CONSTANT_ARRAY) {
+ zval_copy_ctor(return_value);
+ }
+ zval_update_constant_ex(&return_value, (void*)0, param->fptr->common.scope TSRMLS_CC);
+}
+/* }}} */
+
+/* {{{ proto public bool ReflectionParameter::isDefaultValueConstant()
+ Returns whether the default value of this parameter is constant */
+ZEND_METHOD(reflection_parameter, isDefaultValueConstant)
+{
+ zend_op *precv;
+ parameter_reference *param;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+
+ param = _reflection_param_get_default_param(INTERNAL_FUNCTION_PARAM_PASSTHRU);
+ if (!param) {
+ RETURN_FALSE;
+ }
+
+ precv = _reflection_param_get_default_precv(INTERNAL_FUNCTION_PARAM_PASSTHRU, param);
+ if (precv && (Z_TYPE_P(precv->op2.zv) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT) {
+ RETURN_TRUE;
+ }
+
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto public mixed ReflectionParameter::getDefaultValueConstantName()
+ Returns the default value's constant name if default value is constant or null */
+ZEND_METHOD(reflection_parameter, getDefaultValueConstantName)
+{
+ zend_op *precv;
+ parameter_reference *param;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+
+ param = _reflection_param_get_default_param(INTERNAL_FUNCTION_PARAM_PASSTHRU);
+ if (!param) {
+ return;
+ }
+
+ precv = _reflection_param_get_default_precv(INTERNAL_FUNCTION_PARAM_PASSTHRU, param);
+ if (precv && (Z_TYPE_P(precv->op2.zv) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT) {
+ RETURN_STRINGL(Z_STRVAL_P(precv->op2.zv), Z_STRLEN_P(precv->op2.zv), 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)
+{
+ _reflection_export(INTERNAL_FUNCTION_PARAM_PASSTHRU, reflection_method_ptr, 2);
+}
+/* }}} */
+
+/* {{{ proto public void ReflectionMethod::__construct(mixed class_or_method [, string name])
+ Constructor. Throws an Exception in case the given method does not exist */
+ZEND_METHOD(reflection_method, __construct)
+{
+ zval *name, *classname;
+ zval *object, *orig_obj;
+ reflection_object *intern;
+ char *lcname;
+ zend_class_entry **pce;
+ zend_class_entry *ce;
+ zend_function *mptr;
+ char *name_str, *tmp;
+ int name_len, tmp_len;
+ zval ztmp;
+
+ if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "zs", &classname, &name_str, &name_len) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name_str, &name_len) == FAILURE) {
+ return;
+ }
+ if ((tmp = strstr(name_str, "::")) == NULL) {
+ zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Invalid method name %s", name_str);
+ return;
+ }
+ classname = &ztmp;
+ tmp_len = tmp - name_str;
+ ZVAL_STRINGL(classname, name_str, tmp_len, 1);
+ name_len = name_len - (tmp_len + 2);
+ name_str = tmp + 2;
+ orig_obj = NULL;
+ } else if (Z_TYPE_P(classname) == IS_OBJECT) {
+ orig_obj = classname;
+ } else {
+ orig_obj = NULL;
+ }
+
+ object = getThis();
+ intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
+ if (intern == NULL) {
+ return;
+ }
+
+ /* Find the class entry */
+ switch (Z_TYPE_P(classname)) {
+ case IS_STRING:
+ if (zend_lookup_class(Z_STRVAL_P(classname), Z_STRLEN_P(classname), &pce TSRMLS_CC) == FAILURE) {
+ zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
+ "Class %s does not exist", Z_STRVAL_P(classname));
+ if (classname == &ztmp) {
+ zval_dtor(&ztmp);
+ }
+ return;
+ }
+ ce = *pce;
+ break;
+
+ case IS_OBJECT:
+ ce = Z_OBJCE_P(classname);
+ break;
+
+ default:
+ if (classname == &ztmp) {
+ zval_dtor(&ztmp);
+ }
+ _DO_THROW("The parameter class is expected to be either a string or an object");
+ /* returns out of this function */
+ }
+
+ if (classname == &ztmp) {
+ zval_dtor(&ztmp);
+ }
+
+ lcname = zend_str_tolower_dup(name_str, name_len);
+
+ if (ce == zend_ce_closure && orig_obj && (name_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1)
+ && memcmp(lcname, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0
+ && (mptr = zend_get_closure_invoke_method(orig_obj TSRMLS_CC)) != NULL)
+ {
+ /* do nothing, mptr already set */
+ } else if (zend_hash_find(&ce->function_table, lcname, name_len + 1, (void **) &mptr) == FAILURE) {
+ efree(lcname);
+ zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
+ "Method %s::%s() does not exist", ce->name, name_str);
+ return;
+ }
+ efree(lcname);
+
+ MAKE_STD_ZVAL(classname);
+ ZVAL_STRINGL(classname, mptr->common.scope->name, mptr->common.scope->name_length, 1);
+
+ reflection_update_property(object, "class", classname);
+
+ MAKE_STD_ZVAL(name);
+ ZVAL_STRING(name, mptr->common.function_name, 1);
+ reflection_update_property(object, "name", name);
+ intern->ptr = mptr;
+ intern->ref_type = REF_TYPE_FUNCTION;
+ intern->ce = ce;
+}
+/* }}} */
+
+/* {{{ proto public string ReflectionMethod::__toString()
+ Returns a string representation */
+ZEND_METHOD(reflection_method, __toString)
+{
+ reflection_object *intern;
+ zend_function *mptr;
+ string str;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(mptr);
+ string_init(&str);
+ _function_string(&str, mptr, intern->ce, "" TSRMLS_CC);
+ RETURN_STRINGL(str.string, str.len - 1, 0);
+}
+/* }}} */
+
+/* {{{ proto public mixed ReflectionMethod::getClosure([mixed object])
+ Invokes the function */
+ZEND_METHOD(reflection_method, getClosure)
+{
+ reflection_object *intern;
+ zval *obj;
+ zend_function *mptr;
+
+ METHOD_NOTSTATIC(reflection_method_ptr);
+ GET_REFLECTION_OBJECT_PTR(mptr);
+
+ if (mptr->common.fn_flags & ZEND_ACC_STATIC) {
+ zend_create_closure(return_value, mptr, mptr->common.scope, NULL TSRMLS_CC);
+ } else {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &obj) == FAILURE) {
+ return;
+ }
+
+ if (!instanceof_function(Z_OBJCE_P(obj), mptr->common.scope TSRMLS_CC)) {
+ _DO_THROW("Given object is not an instance of the class this method was declared in");
+ /* Returns from this function */
+ }
+
+ /* This is an original closure object and __invoke is to be called. */
+ if (Z_OBJCE_P(obj) == zend_ce_closure && mptr->type == ZEND_INTERNAL_FUNCTION &&
+ (mptr->internal_function.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0)
+ {
+ RETURN_ZVAL(obj, 1, 0);
+ } else {
+ zend_create_closure(return_value, mptr, mptr->common.scope, obj TSRMLS_CC);
+ }
+ }
+}
+/* }}} */
+
+/* {{{ proto public mixed ReflectionMethod::invoke(mixed object, mixed* args)
+ Invokes the method. */
+ZEND_METHOD(reflection_method, invoke)
+{
+ zval *retval_ptr;
+ zval ***params = NULL;
+ zval *object_ptr;
+ reflection_object *intern;
+ zend_function *mptr;
+ int result, num_args = 0;
+ zend_fcall_info fci;
+ zend_fcall_info_cache fcc;
+ zend_class_entry *obj_ce;
+
+ METHOD_NOTSTATIC(reflection_method_ptr);
+
+ GET_REFLECTION_OBJECT_PTR(mptr);
+
+ if ((!(mptr->common.fn_flags & ZEND_ACC_PUBLIC)
+ || (mptr->common.fn_flags & ZEND_ACC_ABSTRACT))
+ && intern->ignore_visibility == 0)
+ {
+ if (mptr->common.fn_flags & ZEND_ACC_ABSTRACT) {
+ zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
+ "Trying to invoke abstract method %s::%s()",
+ mptr->common.scope->name, mptr->common.function_name);
+ } else {
+ zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
+ "Trying to invoke %s method %s::%s() from scope %s",
+ mptr->common.fn_flags & ZEND_ACC_PROTECTED ? "protected" : "private",
+ mptr->common.scope->name, mptr->common.function_name,
+ Z_OBJCE_P(getThis())->name);
+ }
+ return;
+ }
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "+", &params, &num_args) == FAILURE) {
+ return;
+ }
+
+ /* In case this is a static method, we should'nt pass an object_ptr
+ * (which is used as calling context aka $this). We can thus ignore the
+ * first parameter.
+ *
+ * Else, we verify that the given object is an instance of the class.
+ */
+ if (mptr->common.fn_flags & ZEND_ACC_STATIC) {
+ object_ptr = NULL;
+ obj_ce = mptr->common.scope;
+ } else {
+ if (Z_TYPE_PP(params[0]) != IS_OBJECT) {
+ efree(params);
+ _DO_THROW("Non-object passed to Invoke()");
+ /* Returns from this function */
+ }
+
+ obj_ce = Z_OBJCE_PP(params[0]);
+
+ if (!instanceof_function(obj_ce, mptr->common.scope TSRMLS_CC)) {
+ if (params) {
+ efree(params);
+ }
+ _DO_THROW("Given object is not an instance of the class this method was declared in");
+ /* Returns from this function */
+ }
+
+ object_ptr = *params[0];
+ }
+
+ fci.size = sizeof(fci);
+ fci.function_table = NULL;
+ fci.function_name = NULL;
+ fci.symbol_table = NULL;
+ fci.object_ptr = object_ptr;
+ fci.retval_ptr_ptr = &retval_ptr;
+ fci.param_count = num_args - 1;
+ fci.params = params + 1;
+ fci.no_separation = 1;
+
+ fcc.initialized = 1;
+ fcc.function_handler = mptr;
+ fcc.calling_scope = obj_ce;
+ fcc.called_scope = intern->ce;
+ fcc.object_ptr = object_ptr;
+
+ result = zend_call_function(&fci, &fcc TSRMLS_CC);
+
+ if (params) {
+ efree(params);
+ }
+
+ if (result == FAILURE) {
+ zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
+ "Invocation of method %s::%s() failed", mptr->common.scope->name, mptr->common.function_name);
+ return;
+ }
+
+ if (retval_ptr) {
+ COPY_PZVAL_TO_ZVAL(*return_value, retval_ptr);
+ }
+}
+/* }}} */
+
+/* {{{ proto public mixed ReflectionMethod::invokeArgs(mixed object, array args)
+ Invokes the function and pass its arguments as array. */
+ZEND_METHOD(reflection_method, invokeArgs)
+{
+ zval *retval_ptr;
+ zval ***params;
+ zval *object;
+ reflection_object *intern;
+ zend_function *mptr;
+ int argc;
+ int result;
+ zend_fcall_info fci;
+ zend_fcall_info_cache fcc;
+ zend_class_entry *obj_ce;
+ zval *param_array;
+
+ METHOD_NOTSTATIC(reflection_method_ptr);
+
+ GET_REFLECTION_OBJECT_PTR(mptr);
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o!a", &object, &param_array) == FAILURE) {
+ return;
+ }
+
+ if ((!(mptr->common.fn_flags & ZEND_ACC_PUBLIC)
+ || (mptr->common.fn_flags & ZEND_ACC_ABSTRACT))
+ && intern->ignore_visibility == 0)
+ {
+ if (mptr->common.fn_flags & ZEND_ACC_ABSTRACT) {
+ zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
+ "Trying to invoke abstract method %s::%s()",
+ mptr->common.scope->name, mptr->common.function_name);
+ } else {
+ zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
+ "Trying to invoke %s method %s::%s() from scope %s",
+ mptr->common.fn_flags & ZEND_ACC_PROTECTED ? "protected" : "private",
+ mptr->common.scope->name, mptr->common.function_name,
+ Z_OBJCE_P(getThis())->name);
+ }
+ return;
+ }
+
+ argc = zend_hash_num_elements(Z_ARRVAL_P(param_array));
+
+ params = safe_emalloc(sizeof(zval **), argc, 0);
+ zend_hash_apply_with_argument(Z_ARRVAL_P(param_array), (apply_func_arg_t)_zval_array_to_c_array, &params TSRMLS_CC);
+ params -= argc;
+
+ /* In case this is a static method, we should'nt pass an object_ptr
+ * (which is used as calling context aka $this). We can thus ignore the
+ * first parameter.
+ *
+ * Else, we verify that the given object is an instance of the class.
+ */
+ if (mptr->common.fn_flags & ZEND_ACC_STATIC) {
+ object = NULL;
+ obj_ce = mptr->common.scope;
+ } else {
+ if (!object) {
+ efree(params);
+ zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
+ "Trying to invoke non static method %s::%s() without an object",
+ mptr->common.scope->name, mptr->common.function_name);
+ return;
+ }
+
+ obj_ce = Z_OBJCE_P(object);
+
+ if (!instanceof_function(obj_ce, mptr->common.scope TSRMLS_CC)) {
+ efree(params);
+ _DO_THROW("Given object is not an instance of the class this method was declared in");
+ /* Returns from this function */
+ }
+ }
+
+ fci.size = sizeof(fci);
+ fci.function_table = NULL;
+ fci.function_name = NULL;
+ fci.symbol_table = NULL;
+ fci.object_ptr = object;
+ fci.retval_ptr_ptr = &retval_ptr;
+ fci.param_count = argc;
+ fci.params = params;
+ fci.no_separation = 1;
+
+ fcc.initialized = 1;
+ fcc.function_handler = mptr;
+ fcc.calling_scope = obj_ce;
+ fcc.called_scope = intern->ce;
+ fcc.object_ptr = object;
+
+ /*
+ * Copy the zend_function when calling via handler (e.g. Closure::__invoke())
+ */
+ if (mptr->type == ZEND_INTERNAL_FUNCTION &&
+ (mptr->internal_function.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0) {
+ fcc.function_handler = _copy_function(mptr TSRMLS_CC);
+ }
+
+ result = zend_call_function(&fci, &fcc TSRMLS_CC);
+
+ efree(params);
+
+ if (result == FAILURE) {
+ zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
+ "Invocation of method %s::%s() failed", mptr->common.scope->name, mptr->common.function_name);
+ return;
+ }
+
+ if (retval_ptr) {
+ COPY_PZVAL_TO_ZVAL(*return_value, retval_ptr);
+ }
+}
+/* }}} */
+
+/* {{{ proto public bool ReflectionMethod::isFinal()
+ Returns whether this method is final */
+ZEND_METHOD(reflection_method, isFinal)
+{
+ _function_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_FINAL);
+}
+/* }}} */
+
+/* {{{ proto public bool ReflectionMethod::isAbstract()
+ Returns whether this method is abstract */
+ZEND_METHOD(reflection_method, isAbstract)
+{
+ _function_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_ABSTRACT);
+}
+/* }}} */
+
+/* {{{ proto public bool ReflectionMethod::isPublic()
+ Returns whether this method is public */
+ZEND_METHOD(reflection_method, isPublic)
+{
+ _function_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_PUBLIC);
+}
+/* }}} */
+
+/* {{{ proto public bool ReflectionMethod::isPrivate()
+ Returns whether this method is private */
+ZEND_METHOD(reflection_method, isPrivate)
+{
+ _function_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_PRIVATE);
+}
+/* }}} */
+
+/* {{{ proto public bool ReflectionMethod::isProtected()
+ Returns whether this method is protected */
+ZEND_METHOD(reflection_method, isProtected)
+{
+ _function_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_PROTECTED);
+}
+/* }}} */
+
+/* {{{ proto public bool ReflectionMethod::isStatic()
+ Returns whether this method is static */
+ZEND_METHOD(reflection_method, isStatic)
+{
+ _function_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_STATIC);
+}
+/* }}} */
+
+/* {{{ proto public bool ReflectionFunction::isDeprecated()
+ Returns whether this function is deprecated */
+ZEND_METHOD(reflection_function, isDeprecated)
+{
+ _function_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_DEPRECATED);
+}
+/* }}} */
+
+/* {{{ proto public bool ReflectionFunction::inNamespace()
+ Returns whether this function is defined in namespace */
+ZEND_METHOD(reflection_function, inNamespace)
+{
+ zval **name;
+ const char *backslash;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ if (zend_hash_find(Z_OBJPROP_P(getThis()), "name", sizeof("name"), (void **) &name) == FAILURE) {
+ RETURN_FALSE;
+ }
+ if (Z_TYPE_PP(name) == IS_STRING
+ && (backslash = zend_memrchr(Z_STRVAL_PP(name), '\\', Z_STRLEN_PP(name)))
+ && backslash > Z_STRVAL_PP(name))
+ {
+ RETURN_TRUE;
+ }
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto public string ReflectionFunction::getNamespaceName()
+ Returns the name of namespace where this function is defined */
+ZEND_METHOD(reflection_function, getNamespaceName)
+{
+ zval **name;
+ const char *backslash;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ if (zend_hash_find(Z_OBJPROP_P(getThis()), "name", sizeof("name"), (void **) &name) == FAILURE) {
+ RETURN_FALSE;
+ }
+ if (Z_TYPE_PP(name) == IS_STRING
+ && (backslash = zend_memrchr(Z_STRVAL_PP(name), '\\', Z_STRLEN_PP(name)))
+ && backslash > Z_STRVAL_PP(name))
+ {
+ RETURN_STRINGL(Z_STRVAL_PP(name), backslash - Z_STRVAL_PP(name), 1);
+ }
+ RETURN_EMPTY_STRING();
+}
+/* }}} */
+
+/* {{{ proto public string ReflectionFunction::getShortName()
+ Returns the short name of the function (without namespace part) */
+ZEND_METHOD(reflection_function, getShortName)
+{
+ zval **name;
+ const char *backslash;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ if (zend_hash_find(Z_OBJPROP_P(getThis()), "name", sizeof("name"), (void **) &name) == FAILURE) {
+ RETURN_FALSE;
+ }
+ if (Z_TYPE_PP(name) == IS_STRING
+ && (backslash = zend_memrchr(Z_STRVAL_PP(name), '\\', Z_STRLEN_PP(name)))
+ && backslash > Z_STRVAL_PP(name))
+ {
+ RETURN_STRINGL(backslash + 1, Z_STRLEN_PP(name) - (backslash - Z_STRVAL_PP(name) + 1), 1);
+ }
+ RETURN_ZVAL(*name, 1, 0);
+}
+/* }}} */
+
+/* {{{ proto public bool ReflectionMethod::isConstructor()
+ Returns whether this method is the constructor */
+ZEND_METHOD(reflection_method, isConstructor)
+{
+ reflection_object *intern;
+ zend_function *mptr;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(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);
+}
+/* }}} */
+
+/* {{{ proto public bool ReflectionMethod::isDestructor()
+ Returns whether this method is static */
+ZEND_METHOD(reflection_method, isDestructor)
+{
+ reflection_object *intern;
+ zend_function *mptr;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(mptr);
+ RETURN_BOOL(mptr->common.fn_flags & ZEND_ACC_DTOR);
+}
+/* }}} */
+
+/* {{{ proto public int ReflectionMethod::getModifiers()
+ Returns a bitfield of the access modifiers for this method */
+ZEND_METHOD(reflection_method, getModifiers)
+{
+ reflection_object *intern;
+ zend_function *mptr;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(mptr);
+
+ RETURN_LONG(mptr->common.fn_flags);
+}
+/* }}} */
+
+/* {{{ proto public ReflectionClass ReflectionMethod::getDeclaringClass()
+ Get the declaring class */
+ZEND_METHOD(reflection_method, getDeclaringClass)
+{
+ reflection_object *intern;
+ zend_function *mptr;
+
+ METHOD_NOTSTATIC(reflection_method_ptr);
+ GET_REFLECTION_OBJECT_PTR(mptr);
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+
+ zend_reflection_class_factory(mptr->common.scope, return_value TSRMLS_CC);
+}
+/* }}} */
+
+/* {{{ proto public ReflectionClass ReflectionMethod::getPrototype()
+ Get the prototype */
+ZEND_METHOD(reflection_method, getPrototype)
+{
+ reflection_object *intern;
+ zend_function *mptr;
+
+ METHOD_NOTSTATIC(reflection_method_ptr);
+ GET_REFLECTION_OBJECT_PTR(mptr);
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+
+ if (!mptr->common.prototype) {
+ zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
+ "Method %s::%s does not have a prototype", intern->ce->name, mptr->common.function_name);
+ return;
+ }
+
+ reflection_method_factory(mptr->common.prototype->common.scope, mptr->common.prototype, NULL, return_value TSRMLS_CC);
+}
+/* }}} */
+
+/* {{{ proto public void ReflectionMethod::setAccessible(bool visible)
+ Sets whether non-public methods can be invoked */
+ZEND_METHOD(reflection_method, setAccessible)
+{
+ reflection_object *intern;
+ zend_bool visible;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &visible) == FAILURE) {
+ return;
+ }
+
+ intern = (reflection_object *) zend_object_store_get_object(getThis() TSRMLS_CC);
+
+ if (intern == NULL) {
+ return;
+ }
+
+ intern->ignore_visibility = visible;
+}
+/* }}} */
+
+/* {{{ proto public static mixed ReflectionClass::export(mixed argument [, bool return]) throws ReflectionException
+ Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */
+ZEND_METHOD(reflection_class, export)
+{
+ _reflection_export(INTERNAL_FUNCTION_PARAM_PASSTHRU, reflection_class_ptr, 1);
+}
+/* }}} */
+
+/* {{{ reflection_class_object_ctor */
+static void reflection_class_object_ctor(INTERNAL_FUNCTION_PARAMETERS, int is_object)
+{
+ zval *argument;
+ zval *object;
+ zval *classname;
+ reflection_object *intern;
+ zend_class_entry **ce;
+
+ if (is_object) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &argument) == FAILURE) {
+ return;
+ }
+ } else {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z/", &argument) == FAILURE) {
+ return;
+ }
+ }
+
+ object = getThis();
+ intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
+ if (intern == NULL) {
+ return;
+ }
+
+ if (Z_TYPE_P(argument) == IS_OBJECT) {
+ MAKE_STD_ZVAL(classname);
+ ZVAL_STRINGL(classname, Z_OBJCE_P(argument)->name, Z_OBJCE_P(argument)->name_length, 1);
+ reflection_update_property(object, "name", classname);
+ intern->ptr = Z_OBJCE_P(argument);
+ if (is_object) {
+ intern->obj = argument;
+ zval_add_ref(&argument);
+ }
+ } else {
+ convert_to_string_ex(&argument);
+ if (zend_lookup_class(Z_STRVAL_P(argument), Z_STRLEN_P(argument), &ce TSRMLS_CC) == FAILURE) {
+ if (!EG(exception)) {
+ zend_throw_exception_ex(reflection_exception_ptr, -1 TSRMLS_CC, "Class %s does not exist", Z_STRVAL_P(argument));
+ }
+ return;
+ }
+
+ MAKE_STD_ZVAL(classname);
+ ZVAL_STRINGL(classname, (*ce)->name, (*ce)->name_length, 1);
+ reflection_update_property(object, "name", classname);
+
+ intern->ptr = *ce;
+ }
+ intern->ref_type = REF_TYPE_OTHER;
+}
+/* }}} */
+
+/* {{{ proto public void ReflectionClass::__construct(mixed argument) throws ReflectionException
+ Constructor. Takes a string or an instance as an argument */
+ZEND_METHOD(reflection_class, __construct)
+{
+ reflection_class_object_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
+}
+/* }}} */
+
+/* {{{ add_class_vars */
+static void add_class_vars(zend_class_entry *ce, int statics, zval *return_value TSRMLS_DC)
+{
+ HashPosition pos;
+ zend_property_info *prop_info;
+ zval *prop, *prop_copy;
+ char *key;
+ uint key_len;
+ ulong num_index;
+
+ zend_hash_internal_pointer_reset_ex(&ce->properties_info, &pos);
+ while (zend_hash_get_current_data_ex(&ce->properties_info, (void **) &prop_info, &pos) == SUCCESS) {
+ zend_hash_get_current_key_ex(&ce->properties_info, &key, &key_len, &num_index, 0, &pos);
+ zend_hash_move_forward_ex(&ce->properties_info, &pos);
+ if (((prop_info->flags & ZEND_ACC_SHADOW) &&
+ prop_info->ce != ce) ||
+ ((prop_info->flags & ZEND_ACC_PROTECTED) &&
+ !zend_check_protected(prop_info->ce, ce)) ||
+ ((prop_info->flags & ZEND_ACC_PRIVATE) &&
+ prop_info->ce != ce)) {
+ continue;
+ }
+ prop = NULL;
+ if (prop_info->offset >= 0) {
+ if (statics && (prop_info->flags & ZEND_ACC_STATIC) != 0) {
+ prop = ce->default_static_members_table[prop_info->offset];
+ } else if (!statics && (prop_info->flags & ZEND_ACC_STATIC) == 0) {
+ prop = ce->default_properties_table[prop_info->offset];
+ }
+ }
+ if (!prop) {
+ continue;
+ }
+
+ /* copy: enforce read only access */
+ ALLOC_ZVAL(prop_copy);
+ *prop_copy = *prop;
+ zval_copy_ctor(prop_copy);
+ INIT_PZVAL(prop_copy);
+
+ /* this is necessary to make it able to work with default array
+ * properties, returned to user */
+ if (Z_TYPE_P(prop_copy) == IS_CONSTANT_ARRAY || (Z_TYPE_P(prop_copy) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT) {
+ zval_update_constant(&prop_copy, (void *) 1 TSRMLS_CC);
+ }
+
+ add_assoc_zval(return_value, key, prop_copy);
+ }
+}
+/* }}} */
+
+/* {{{ proto public array ReflectionClass::getStaticProperties()
+ Returns an associative array containing all static property values of the class */
+ZEND_METHOD(reflection_class, getStaticProperties)
+{
+ reflection_object *intern;
+ zend_class_entry *ce;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+
+ GET_REFLECTION_OBJECT_PTR(ce);
+
+ zend_update_class_constants(ce TSRMLS_CC);
+
+ array_init(return_value);
+ add_class_vars(ce, 1, return_value TSRMLS_CC);
+}
+/* }}} */
+
+/* {{{ proto public mixed ReflectionClass::getStaticPropertyValue(string name [, mixed default])
+ Returns the value of a static property */
+ZEND_METHOD(reflection_class, getStaticPropertyValue)
+{
+ reflection_object *intern;
+ zend_class_entry *ce;
+ char *name;
+ int name_len;
+ zval **prop, *def_value = NULL;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|z", &name, &name_len, &def_value) == FAILURE) {
+ return;
+ }
+
+ GET_REFLECTION_OBJECT_PTR(ce);
+
+ zend_update_class_constants(ce TSRMLS_CC);
+ prop = zend_std_get_static_property(ce, name, name_len, 1, NULL TSRMLS_CC);
+ if (!prop) {
+ if (def_value) {
+ RETURN_ZVAL(def_value, 1, 0);
+ } else {
+ zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
+ "Class %s does not have a property named %s", ce->name, name);
+ }
+ return;
+ } else {
+ RETURN_ZVAL(*prop, 1, 0);
+ }
+}
+/* }}} */
+
+/* {{{ proto public void ReflectionClass::setStaticPropertyValue($name, $value)
+ Sets the value of a static property */
+ZEND_METHOD(reflection_class, setStaticPropertyValue)
+{
+ reflection_object *intern;
+ zend_class_entry *ce;
+ char *name;
+ int name_len;
+ zval **variable_ptr, *value;
+ int refcount;
+ zend_uchar is_ref;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz", &name, &name_len, &value) == FAILURE) {
+ return;
+ }
+
+ GET_REFLECTION_OBJECT_PTR(ce);
+
+ zend_update_class_constants(ce TSRMLS_CC);
+ variable_ptr = zend_std_get_static_property(ce, name, name_len, 1, NULL TSRMLS_CC);
+ if (!variable_ptr) {
+ zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
+ "Class %s does not have a property named %s", ce->name, name);
+ return;
+ }
+ refcount = Z_REFCOUNT_PP(variable_ptr);
+ is_ref = Z_ISREF_PP(variable_ptr);
+ zval_dtor(*variable_ptr);
+ **variable_ptr = *value;
+ zval_copy_ctor(*variable_ptr);
+ Z_SET_REFCOUNT_PP(variable_ptr, refcount);
+ Z_SET_ISREF_TO_PP(variable_ptr, is_ref);
+
+}
+/* }}} */
+
+/* {{{ proto public array ReflectionClass::getDefaultProperties()
+ Returns an associative array containing copies of all default property values of the class */
+ZEND_METHOD(reflection_class, getDefaultProperties)
+{
+ reflection_object *intern;
+ zend_class_entry *ce;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(ce);
+ array_init(return_value);
+ zend_update_class_constants(ce TSRMLS_CC);
+ add_class_vars(ce, 1, return_value TSRMLS_CC);
+ add_class_vars(ce, 0, return_value TSRMLS_CC);
+}
+/* }}} */
+
+/* {{{ proto public string ReflectionClass::__toString()
+ Returns a string representation */
+ZEND_METHOD(reflection_class, __toString)
+{
+ reflection_object *intern;
+ zend_class_entry *ce;
+ string str;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(ce);
+ string_init(&str);
+ _class_string(&str, ce, intern->obj, "" TSRMLS_CC);
+ RETURN_STRINGL(str.string, str.len - 1, 0);
+}
+/* }}} */
+
+/* {{{ proto public string ReflectionClass::getName()
+ Returns the class' name */
+ZEND_METHOD(reflection_class, getName)
+{
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ _default_get_entry(getThis(), "name", sizeof("name"), return_value TSRMLS_CC);
+}
+/* }}} */
+
+/* {{{ proto public bool ReflectionClass::isInternal()
+ Returns whether this class is an internal class */
+ZEND_METHOD(reflection_class, isInternal)
+{
+ reflection_object *intern;
+ zend_class_entry *ce;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(ce);
+ RETURN_BOOL(ce->type == ZEND_INTERNAL_CLASS);
+}
+/* }}} */
+
+/* {{{ proto public bool ReflectionClass::isUserDefined()
+ Returns whether this class is user-defined */
+ZEND_METHOD(reflection_class, isUserDefined)
+{
+ reflection_object *intern;
+ zend_class_entry *ce;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(ce);
+ RETURN_BOOL(ce->type == ZEND_USER_CLASS);
+}
+/* }}} */
+
+/* {{{ proto public string ReflectionClass::getFileName()
+ Returns the filename of the file this class was declared in */
+ZEND_METHOD(reflection_class, getFileName)
+{
+ reflection_object *intern;
+ zend_class_entry *ce;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(ce);
+ if (ce->type == ZEND_USER_CLASS) {
+ RETURN_STRING(ce->info.user.filename, 1);
+ }
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto public int ReflectionClass::getStartLine()
+ Returns the line this class' declaration starts at */
+ZEND_METHOD(reflection_class, getStartLine)
+{
+ reflection_object *intern;
+ zend_class_entry *ce;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(ce);
+ if (ce->type == ZEND_USER_FUNCTION) {
+ RETURN_LONG(ce->info.user.line_start);
+ }
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto public int ReflectionClass::getEndLine()
+ Returns the line this class' declaration ends at */
+ZEND_METHOD(reflection_class, getEndLine)
+{
+ reflection_object *intern;
+ zend_class_entry *ce;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(ce);
+ if (ce->type == ZEND_USER_CLASS) {
+ RETURN_LONG(ce->info.user.line_end);
+ }
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto public string ReflectionClass::getDocComment()
+ Returns the doc comment for this class */
+ZEND_METHOD(reflection_class, getDocComment)
+{
+ reflection_object *intern;
+ zend_class_entry *ce;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(ce);
+ if (ce->type == ZEND_USER_CLASS && ce->info.user.doc_comment) {
+ RETURN_STRINGL(ce->info.user.doc_comment, ce->info.user.doc_comment_len, 1);
+ }
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto public ReflectionMethod ReflectionClass::getConstructor()
+ Returns the class' constructor if there is one, NULL otherwise */
+ZEND_METHOD(reflection_class, getConstructor)
+{
+ reflection_object *intern;
+ zend_class_entry *ce;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(ce);
+
+ if (ce->constructor) {
+ reflection_method_factory(ce, ce->constructor, NULL, return_value TSRMLS_CC);
+ } else {
+ RETURN_NULL();
+ }
+}
+/* }}} */
+
+/* {{{ proto public bool ReflectionClass::hasMethod(string name)
+ Returns whether a method exists or not */
+ZEND_METHOD(reflection_class, hasMethod)
+{
+ reflection_object *intern;
+ zend_class_entry *ce;
+ char *name, *lc_name;
+ int name_len;
+
+ METHOD_NOTSTATIC(reflection_class_ptr);
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
+ return;
+ }
+
+ GET_REFLECTION_OBJECT_PTR(ce);
+ lc_name = zend_str_tolower_dup(name, name_len);
+ if ((ce == zend_ce_closure && (name_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1)
+ && memcmp(lc_name, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0)
+ || zend_hash_exists(&ce->function_table, lc_name, name_len + 1)) {
+ efree(lc_name);
+ RETURN_TRUE;
+ } else {
+ efree(lc_name);
+ RETURN_FALSE;
+ }
+}
+/* }}} */
+
+/* {{{ proto public ReflectionMethod ReflectionClass::getMethod(string name) throws ReflectionException
+ Returns the class' method specified by its name */
+ZEND_METHOD(reflection_class, getMethod)
+{
+ reflection_object *intern;
+ zend_class_entry *ce;
+ zend_function *mptr;
+ zval obj_tmp;
+ char *name, *lc_name;
+ int name_len;
+
+ METHOD_NOTSTATIC(reflection_class_ptr);
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
+ return;
+ }
+
+ GET_REFLECTION_OBJECT_PTR(ce);
+ lc_name = zend_str_tolower_dup(name, name_len);
+ if (ce == zend_ce_closure && intern->obj && (name_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1)
+ && memcmp(lc_name, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0
+ && (mptr = zend_get_closure_invoke_method(intern->obj TSRMLS_CC)) != NULL)
+ {
+ /* don't assign closure_object since we only reflect the invoke handler
+ method and not the closure definition itself */
+ reflection_method_factory(ce, mptr, NULL, return_value TSRMLS_CC);
+ efree(lc_name);
+ } else if (ce == zend_ce_closure && !intern->obj && (name_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1)
+ && memcmp(lc_name, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0
+ && object_init_ex(&obj_tmp, ce) == SUCCESS && (mptr = zend_get_closure_invoke_method(&obj_tmp TSRMLS_CC)) != NULL) {
+ /* don't assign closure_object since we only reflect the invoke handler
+ method and not the closure definition itself */
+ reflection_method_factory(ce, mptr, NULL, return_value TSRMLS_CC);
+ zval_dtor(&obj_tmp);
+ efree(lc_name);
+ } else if (zend_hash_find(&ce->function_table, lc_name, name_len + 1, (void**) &mptr) == SUCCESS) {
+ reflection_method_factory(ce, mptr, NULL, return_value TSRMLS_CC);
+ efree(lc_name);
+ } else {
+ efree(lc_name);
+ zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
+ "Method %s does not exist", name);
+ return;
+ }
+}
+/* }}} */
+
+/* {{{ _addmethod */
+static void _addmethod(zend_function *mptr, zend_class_entry *ce, zval *retval, long filter, zval *obj TSRMLS_DC)
+{
+ zval *method;
+ uint len = strlen(mptr->common.function_name);
+ zend_function *closure;
+
+ if (mptr->common.fn_flags & filter) {
+ ALLOC_ZVAL(method);
+ if (ce == zend_ce_closure && obj && (len == sizeof(ZEND_INVOKE_FUNC_NAME)-1)
+ && memcmp(mptr->common.function_name, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0
+ && (closure = zend_get_closure_invoke_method(obj TSRMLS_CC)) != NULL)
+ {
+ mptr = closure;
+ }
+ /* don't assign closure_object since we only reflect the invoke handler
+ method and not the closure definition itself, even if we have a
+ closure */
+ reflection_method_factory(ce, mptr, NULL, method TSRMLS_CC);
+ add_next_index_zval(retval, method);
+ }
+}
+/* }}} */
+
+/* {{{ _addmethod */
+static int _addmethod_va(zend_function *mptr TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key)
+{
+ zend_class_entry *ce = *va_arg(args, zend_class_entry**);
+ zval *retval = va_arg(args, zval*);
+ long filter = va_arg(args, long);
+ zval *obj = va_arg(args, zval *);
+
+ _addmethod(mptr, ce, retval, filter, obj TSRMLS_CC);
+ return ZEND_HASH_APPLY_KEEP;
+}
+/* }}} */
+
+/* {{{ proto public ReflectionMethod[] ReflectionClass::getMethods([long $filter])
+ Returns an array of this class' methods */
+ZEND_METHOD(reflection_class, getMethods)
+{
+ reflection_object *intern;
+ zend_class_entry *ce;
+ long filter = 0;
+ int argc = ZEND_NUM_ARGS();
+
+ METHOD_NOTSTATIC(reflection_class_ptr);
+ if (argc) {
+ if (zend_parse_parameters(argc TSRMLS_CC, "|l", &filter) == FAILURE) {
+ return;
+ }
+ } else {
+ /* No parameters given, default to "return all" */
+ filter = ZEND_ACC_PPP_MASK | ZEND_ACC_ABSTRACT | ZEND_ACC_FINAL | ZEND_ACC_STATIC;
+ }
+
+ GET_REFLECTION_OBJECT_PTR(ce);
+
+ array_init(return_value);
+ zend_hash_apply_with_arguments(&ce->function_table TSRMLS_CC, (apply_func_args_t) _addmethod_va, 4, &ce, return_value, filter, intern->obj);
+ if (intern->obj && instanceof_function(ce, zend_ce_closure TSRMLS_CC)) {
+ zend_function *closure = zend_get_closure_invoke_method(intern->obj TSRMLS_CC);
+ if (closure) {
+ _addmethod(closure, ce, return_value, filter, intern->obj TSRMLS_CC);
+ _free_function(closure TSRMLS_CC);
+ }
+ }
+}
+/* }}} */
+
+/* {{{ proto public bool ReflectionClass::hasProperty(string name)
+ Returns whether a property exists or not */
+ZEND_METHOD(reflection_class, hasProperty)
+{
+ reflection_object *intern;
+ zend_property_info *property_info;
+ zend_class_entry *ce;
+ char *name;
+ int name_len;
+ zval *property;
+
+ METHOD_NOTSTATIC(reflection_class_ptr);
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
+ return;
+ }
+
+ GET_REFLECTION_OBJECT_PTR(ce);
+ if (zend_hash_find(&ce->properties_info, name, name_len+1, (void **) &property_info) == SUCCESS) {
+ if (property_info->flags & ZEND_ACC_SHADOW) {
+ RETURN_FALSE;
+ }
+ RETURN_TRUE;
+ } else {
+ if (intern->obj && Z_OBJ_HANDLER_P(intern->obj, has_property)) {
+ MAKE_STD_ZVAL(property);
+ ZVAL_STRINGL(property, name, name_len, 1);
+ if (Z_OBJ_HANDLER_P(intern->obj, has_property)(intern->obj, property, 2, 0 TSRMLS_CC)) {
+ zval_ptr_dtor(&property);
+ RETURN_TRUE;
+ }
+ zval_ptr_dtor(&property);
+ }
+ RETURN_FALSE;
+ }
+}
+/* }}} */
+
+/* {{{ proto public ReflectionProperty ReflectionClass::getProperty(string name) throws ReflectionException
+ Returns the class' property specified by its name */
+ZEND_METHOD(reflection_class, getProperty)
+{
+ reflection_object *intern;
+ zend_class_entry *ce, **pce;
+ zend_property_info *property_info;
+ char *name, *tmp, *classname;
+ int name_len, classname_len;
+
+ METHOD_NOTSTATIC(reflection_class_ptr);
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
+ return;
+ }
+
+ GET_REFLECTION_OBJECT_PTR(ce);
+ if (zend_hash_find(&ce->properties_info, name, name_len + 1, (void**) &property_info) == SUCCESS) {
+ if ((property_info->flags & ZEND_ACC_SHADOW) == 0) {
+ reflection_property_factory(ce, property_info, return_value TSRMLS_CC);
+ return;
+ }
+ } else if (intern->obj) {
+ /* Check for dynamic properties */
+ if (zend_hash_exists(Z_OBJ_HT_P(intern->obj)->get_properties(intern->obj TSRMLS_CC), name, name_len+1)) {
+ zend_property_info property_info_tmp;
+ property_info_tmp.flags = ZEND_ACC_IMPLICIT_PUBLIC;
+ property_info_tmp.name = estrndup(name, name_len);
+ property_info_tmp.name_length = name_len;
+ property_info_tmp.h = zend_get_hash_value(name, name_len+1);
+ property_info_tmp.doc_comment = NULL;
+ property_info_tmp.ce = ce;
+
+ reflection_property_factory(ce, &property_info_tmp, return_value TSRMLS_CC);
+ intern = (reflection_object *) zend_object_store_get_object(return_value TSRMLS_CC);
+ intern->ref_type = REF_TYPE_DYNAMIC_PROPERTY;
+ return;
+ }
+ }
+ if ((tmp = strstr(name, "::")) != NULL) {
+ classname_len = tmp - name;
+ classname = zend_str_tolower_dup(name, classname_len);
+ classname[classname_len] = '\0';
+ name_len = name_len - (classname_len + 2);
+ name = tmp + 2;
+
+ if (zend_lookup_class(classname, classname_len, &pce TSRMLS_CC) == FAILURE) {
+ if (!EG(exception)) {
+ zend_throw_exception_ex(reflection_exception_ptr, -1 TSRMLS_CC, "Class %s does not exist", classname);
+ }
+ efree(classname);
+ return;
+ }
+ efree(classname);
+
+ if (!instanceof_function(ce, *pce TSRMLS_CC)) {
+ zend_throw_exception_ex(reflection_exception_ptr, -1 TSRMLS_CC, "Fully qualified property name %s::%s does not specify a base class of %s", (*pce)->name, name, ce->name);
+ return;
+ }
+ ce = *pce;
+
+ if (zend_hash_find(&ce->properties_info, name, name_len + 1, (void**) &property_info) == SUCCESS && (property_info->flags & ZEND_ACC_SHADOW) == 0) {
+ reflection_property_factory(ce, property_info, return_value TSRMLS_CC);
+ return;
+ }
+ }
+ zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
+ "Property %s does not exist", name);
+}
+/* }}} */
+
+/* {{{ _addproperty */
+static int _addproperty(zend_property_info *pptr TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key)
+{
+ zval *property;
+ zend_class_entry *ce = *va_arg(args, zend_class_entry**);
+ zval *retval = va_arg(args, zval*);
+ long filter = va_arg(args, long);
+
+ if (pptr->flags & ZEND_ACC_SHADOW) {
+ return 0;
+ }
+
+ if (pptr->flags & filter) {
+ ALLOC_ZVAL(property);
+ reflection_property_factory(ce, pptr, property TSRMLS_CC);
+ add_next_index_zval(retval, property);
+ }
+ return 0;
+}
+/* }}} */
+
+/* {{{ _adddynproperty */
+static int _adddynproperty(zval **pptr TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key)
+{
+ zval *property;
+ zend_class_entry *ce = *va_arg(args, zend_class_entry**);
+ zval *retval = va_arg(args, zval*), member;
+
+ /* under some circumstances, the properties hash table may contain numeric
+ * properties (e.g. when casting from array). This is a WONT FIX bug, at
+ * least for the moment. Ignore these */
+ if (hash_key->nKeyLength == 0) {
+ return 0;
+ }
+
+ if (hash_key->arKey[0] == '\0') {
+ return 0; /* non public cannot be dynamic */
+ }
+
+ ZVAL_STRINGL(&member, hash_key->arKey, hash_key->nKeyLength-1, 0);
+ if (zend_get_property_info(ce, &member, 1 TSRMLS_CC) == &EG(std_property_info)) {
+ MAKE_STD_ZVAL(property);
+ EG(std_property_info).flags = ZEND_ACC_IMPLICIT_PUBLIC;
+ reflection_property_factory(ce, &EG(std_property_info), property TSRMLS_CC);
+ add_next_index_zval(retval, property);
+ }
+ return 0;
+}
+/* }}} */
+
+/* {{{ proto public ReflectionProperty[] ReflectionClass::getProperties([long $filter])
+ Returns an array of this class' properties */
+ZEND_METHOD(reflection_class, getProperties)
+{
+ reflection_object *intern;
+ zend_class_entry *ce;
+ long filter = 0;
+ int argc = ZEND_NUM_ARGS();
+
+ METHOD_NOTSTATIC(reflection_class_ptr);
+ if (argc) {
+ if (zend_parse_parameters(argc TSRMLS_CC, "|l", &filter) == FAILURE) {
+ return;
+ }
+ } else {
+ /* No parameters given, default to "return all" */
+ filter = ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC;
+ }
+
+ GET_REFLECTION_OBJECT_PTR(ce);
+
+ array_init(return_value);
+ zend_hash_apply_with_arguments(&ce->properties_info TSRMLS_CC, (apply_func_args_t) _addproperty, 3, &ce, return_value, filter);
+
+ if (intern->obj && (filter & ZEND_ACC_PUBLIC) != 0 && Z_OBJ_HT_P(intern->obj)->get_properties) {
+ HashTable *properties = Z_OBJ_HT_P(intern->obj)->get_properties(intern->obj TSRMLS_CC);
+ zend_hash_apply_with_arguments(properties TSRMLS_CC, (apply_func_args_t) _adddynproperty, 2, &ce, return_value);
+ }
+}
+/* }}} */
+
+/* {{{ proto public bool ReflectionClass::hasConstant(string name)
+ Returns whether a constant exists or not */
+ZEND_METHOD(reflection_class, hasConstant)
+{
+ reflection_object *intern;
+ zend_class_entry *ce;
+ char *name;
+ int name_len;
+
+ METHOD_NOTSTATIC(reflection_class_ptr);
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
+ return;
+ }
+
+ GET_REFLECTION_OBJECT_PTR(ce);
+ if (zend_hash_exists(&ce->constants_table, name, name_len + 1)) {
+ RETURN_TRUE;
+ } else {
+ RETURN_FALSE;
+ }
+}
+/* }}} */
+
+/* {{{ proto public array ReflectionClass::getConstants()
+ Returns an associative array containing this class' constants and their values */
+ZEND_METHOD(reflection_class, getConstants)
+{
+ zval *tmp_copy;
+ reflection_object *intern;
+ zend_class_entry *ce;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(ce);
+ array_init(return_value);
+ zend_hash_apply_with_argument(&ce->constants_table, (apply_func_arg_t)zval_update_constant_inline_change, ce TSRMLS_CC);
+ zend_hash_copy(Z_ARRVAL_P(return_value), &ce->constants_table, (copy_ctor_func_t) zval_add_ref, (void *) &tmp_copy, sizeof(zval *));
+}
+/* }}} */
+
+/* {{{ proto public mixed ReflectionClass::getConstant(string name)
+ Returns the class' constant specified by its name */
+ZEND_METHOD(reflection_class, getConstant)
+{
+ reflection_object *intern;
+ zend_class_entry *ce;
+ zval **value;
+ char *name;
+ int name_len;
+
+ METHOD_NOTSTATIC(reflection_class_ptr);
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
+ return;
+ }
+
+ GET_REFLECTION_OBJECT_PTR(ce);
+ zend_hash_apply_with_argument(&ce->constants_table, (apply_func_arg_t)zval_update_constant_inline_change, ce TSRMLS_CC);
+ if (zend_hash_find(&ce->constants_table, name, name_len + 1, (void **) &value) == FAILURE) {
+ RETURN_FALSE;
+ }
+ MAKE_COPY_ZVAL(value, return_value);
+}
+/* }}} */
+
+/* {{{ _class_check_flag */
+static void _class_check_flag(INTERNAL_FUNCTION_PARAMETERS, int mask)
+{
+ reflection_object *intern;
+ zend_class_entry *ce;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(ce);
+ RETVAL_BOOL(ce->ce_flags & mask);
+}
+/* }}} */
+
+/* {{{ proto public bool ReflectionClass::isInstantiable()
+ Returns whether this class is instantiable */
+ZEND_METHOD(reflection_class, isInstantiable)
+{
+ reflection_object *intern;
+ zend_class_entry *ce;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(ce);
+ if (ce->ce_flags & (ZEND_ACC_INTERFACE | ZEND_ACC_EXPLICIT_ABSTRACT_CLASS | ZEND_ACC_IMPLICIT_ABSTRACT_CLASS)) {
+ RETURN_FALSE;
+ }
+
+ /* Basically, the class is instantiable. Though, if there is a constructor
+ * and it is not publicly accessible, it isn't! */
+ if (!ce->constructor) {
+ RETURN_TRUE;
+ }
+
+ RETURN_BOOL(ce->constructor->common.fn_flags & ZEND_ACC_PUBLIC);
+}
+/* }}} */
+
+/* {{{ proto public bool ReflectionClass::isCloneable()
+ Returns whether this class is cloneable */
+ZEND_METHOD(reflection_class, isCloneable)
+{
+ reflection_object *intern;
+ zend_class_entry *ce;
+ zval obj;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(ce);
+ if (ce->ce_flags & (ZEND_ACC_INTERFACE | ZEND_ACC_TRAIT | ZEND_ACC_EXPLICIT_ABSTRACT_CLASS | ZEND_ACC_IMPLICIT_ABSTRACT_CLASS)) {
+ RETURN_FALSE;
+ }
+ if (intern->obj) {
+ if (ce->clone) {
+ RETURN_BOOL(ce->clone->common.fn_flags & ZEND_ACC_PUBLIC);
+ } else {
+ RETURN_BOOL(Z_OBJ_HANDLER_P(intern->obj, clone_obj) != NULL);
+ }
+ } else {
+ if (ce->clone) {
+ RETURN_BOOL(ce->clone->common.fn_flags & ZEND_ACC_PUBLIC);
+ } else {
+ object_init_ex(&obj, ce);
+ RETVAL_BOOL(Z_OBJ_HANDLER(obj, clone_obj) != NULL);
+ zval_dtor(&obj);
+ }
+ }
+}
+/* }}} */
+
+/* {{{ proto public bool ReflectionClass::isInterface()
+ Returns whether this is an interface or a class */
+ZEND_METHOD(reflection_class, isInterface)
+{
+ _class_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_INTERFACE);
+}
+/* }}} */
+
+/* {{{ proto public bool ReflectionClass::isTrait()
+ Returns whether this is a trait */
+ZEND_METHOD(reflection_class, isTrait)
+{
+ _class_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_TRAIT & ~ZEND_ACC_EXPLICIT_ABSTRACT_CLASS);
+}
+/* }}} */
+
+/* {{{ proto public bool ReflectionClass::isFinal()
+ Returns whether this class is final */
+ZEND_METHOD(reflection_class, isFinal)
+{
+ _class_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_FINAL_CLASS);
+}
+/* }}} */
+
+/* {{{ proto public bool ReflectionClass::isAbstract()
+ Returns whether this class is abstract */
+ZEND_METHOD(reflection_class, isAbstract)
+{
+ _class_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS);
+}
+/* }}} */
+
+/* {{{ proto public int ReflectionClass::getModifiers()
+ Returns a bitfield of the access modifiers for this class */
+ZEND_METHOD(reflection_class, getModifiers)
+{
+ reflection_object *intern;
+ zend_class_entry *ce;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(ce);
+
+ RETURN_LONG(ce->ce_flags);
+}
+/* }}} */
+
+/* {{{ proto public bool ReflectionClass::isInstance(stdclass object)
+ Returns whether the given object is an instance of this class */
+ZEND_METHOD(reflection_class, isInstance)
+{
+ reflection_object *intern;
+ zend_class_entry *ce;
+ zval *object;
+
+ METHOD_NOTSTATIC(reflection_class_ptr);
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &object) == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(ce);
+ RETURN_BOOL(HAS_CLASS_ENTRY(*object) && instanceof_function(Z_OBJCE_P(object), ce TSRMLS_CC));
+}
+/* }}} */
+
+/* {{{ proto public stdclass ReflectionClass::newInstance(mixed* args, ...)
+ Returns an instance of this class */
+ZEND_METHOD(reflection_class, newInstance)
+{
+ zval *retval_ptr = NULL;
+ reflection_object *intern;
+ zend_class_entry *ce;
+
+ METHOD_NOTSTATIC(reflection_class_ptr);
+ GET_REFLECTION_OBJECT_PTR(ce);
+
+ /* Run the constructor if there is one */
+ if (ce->constructor) {
+ zval ***params = NULL;
+ int num_args = 0;
+ zend_fcall_info fci;
+ zend_fcall_info_cache fcc;
+
+ if (!(ce->constructor->common.fn_flags & ZEND_ACC_PUBLIC)) {
+ zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Access to non-public constructor of class %s", ce->name);
+ return;
+ }
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "*", &params, &num_args) == FAILURE) {
+ if (params) {
+ efree(params);
+ }
+ RETURN_FALSE;
+ }
+
+ object_init_ex(return_value, ce);
+
+ fci.size = sizeof(fci);
+ fci.function_table = EG(function_table);
+ fci.function_name = NULL;
+ fci.symbol_table = NULL;
+ fci.object_ptr = return_value;
+ fci.retval_ptr_ptr = &retval_ptr;
+ fci.param_count = num_args;
+ fci.params = params;
+ fci.no_separation = 1;
+
+ fcc.initialized = 1;
+ fcc.function_handler = ce->constructor;
+ fcc.calling_scope = EG(scope);
+ fcc.called_scope = Z_OBJCE_P(return_value);
+ fcc.object_ptr = return_value;
+
+ if (zend_call_function(&fci, &fcc TSRMLS_CC) == FAILURE) {
+ if (params) {
+ efree(params);
+ }
+ if (retval_ptr) {
+ zval_ptr_dtor(&retval_ptr);
+ }
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invocation of %s's constructor failed", ce->name);
+ RETURN_NULL();
+ }
+ if (retval_ptr) {
+ zval_ptr_dtor(&retval_ptr);
+ }
+ if (params) {
+ efree(params);
+ }
+ } else if (!ZEND_NUM_ARGS()) {
+ object_init_ex(return_value, ce);
+ } else {
+ zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Class %s does not have a constructor, so you cannot pass any constructor arguments", ce->name);
+ }
+}
+/* }}} */
+
+/* {{{ proto public stdclass ReflectionClass::newInstanceWithoutConstructor()
+ Returns an instance of this class without invoking its constructor */
+ZEND_METHOD(reflection_class, newInstanceWithoutConstructor)
+{
+ reflection_object *intern;
+ zend_class_entry *ce;
+
+ METHOD_NOTSTATIC(reflection_class_ptr);
+ GET_REFLECTION_OBJECT_PTR(ce);
+
+ if (ce->create_object != NULL) {
+ zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Class %s is an internal class that cannot be instantiated without invoking its constructor", ce->name);
+ }
+
+ object_init_ex(return_value, ce);
+}
+/* }}} */
+
+/* {{{ proto public stdclass ReflectionClass::newInstanceArgs([array args])
+ Returns an instance of this class */
+ZEND_METHOD(reflection_class, newInstanceArgs)
+{
+ zval *retval_ptr = NULL;
+ reflection_object *intern;
+ zend_class_entry *ce;
+ int argc = 0;
+ HashTable *args;
+
+
+ METHOD_NOTSTATIC(reflection_class_ptr);
+ GET_REFLECTION_OBJECT_PTR(ce);
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|h", &args) == FAILURE) {
+ return;
+ }
+ if (ZEND_NUM_ARGS() > 0) {
+ argc = args->nNumOfElements;
+ }
+
+ /* Run the constructor if there is one */
+ if (ce->constructor) {
+ zval ***params = NULL;
+ zend_fcall_info fci;
+ zend_fcall_info_cache fcc;
+
+ if (!(ce->constructor->common.fn_flags & ZEND_ACC_PUBLIC)) {
+ zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Access to non-public constructor of class %s", ce->name);
+ return;
+ }
+
+ if (argc) {
+ params = safe_emalloc(sizeof(zval **), argc, 0);
+ zend_hash_apply_with_argument(args, (apply_func_arg_t)_zval_array_to_c_array, &params TSRMLS_CC);
+ params -= argc;
+ }
+
+ object_init_ex(return_value, ce);
+
+ fci.size = sizeof(fci);
+ fci.function_table = EG(function_table);
+ fci.function_name = NULL;
+ fci.symbol_table = NULL;
+ fci.object_ptr = return_value;
+ fci.retval_ptr_ptr = &retval_ptr;
+ fci.param_count = argc;
+ fci.params = params;
+ fci.no_separation = 1;
+
+ fcc.initialized = 1;
+ fcc.function_handler = ce->constructor;
+ fcc.calling_scope = EG(scope);
+ fcc.called_scope = Z_OBJCE_P(return_value);
+ fcc.object_ptr = return_value;
+
+ if (zend_call_function(&fci, &fcc TSRMLS_CC) == FAILURE) {
+ if (params) {
+ efree(params);
+ }
+ if (retval_ptr) {
+ zval_ptr_dtor(&retval_ptr);
+ }
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invocation of %s's constructor failed", ce->name);
+ RETURN_NULL();
+ }
+ if (retval_ptr) {
+ zval_ptr_dtor(&retval_ptr);
+ }
+ if (params) {
+ efree(params);
+ }
+ } else if (!ZEND_NUM_ARGS() || !argc) {
+ object_init_ex(return_value, ce);
+ } else {
+ zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Class %s does not have a constructor, so you cannot pass any constructor arguments", ce->name);
+ }
+}
+/* }}} */
+
+/* {{{ proto public ReflectionClass[] ReflectionClass::getInterfaces()
+ Returns an array of interfaces this class implements */
+ZEND_METHOD(reflection_class, getInterfaces)
+{
+ reflection_object *intern;
+ zend_class_entry *ce;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(ce);
+
+ /* Return an empty array if this class implements no interfaces */
+ array_init(return_value);
+
+ if (ce->num_interfaces) {
+ zend_uint i;
+
+ for (i=0; i < ce->num_interfaces; i++) {
+ zval *interface;
+ ALLOC_ZVAL(interface);
+ zend_reflection_class_factory(ce->interfaces[i], interface TSRMLS_CC);
+ add_assoc_zval_ex(return_value, ce->interfaces[i]->name, ce->interfaces[i]->name_length + 1, interface);
+ }
+ }
+}
+/* }}} */
+
+/* {{{ proto public String[] ReflectionClass::getInterfaceNames()
+ Returns an array of names of interfaces this class implements */
+ZEND_METHOD(reflection_class, getInterfaceNames)
+{
+ reflection_object *intern;
+ zend_class_entry *ce;
+ zend_uint i;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(ce);
+
+ /* Return an empty array if this class implements no interfaces */
+ array_init(return_value);
+
+ for (i=0; i < ce->num_interfaces; i++) {
+ add_next_index_stringl(return_value, ce->interfaces[i]->name, ce->interfaces[i]->name_length, 1);
+ }
+}
+/* }}} */
+
+/* {{{ proto public ReflectionClass[] ReflectionClass::getTraits()
+ Returns an array of traits used by this class */
+ZEND_METHOD(reflection_class, getTraits)
+{
+ reflection_object *intern;
+ zend_class_entry *ce;
+ zend_uint i;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(ce);
+
+ array_init(return_value);
+
+ for (i=0; i < ce->num_traits; i++) {
+ zval *trait;
+ ALLOC_ZVAL(trait);
+ zend_reflection_class_factory(ce->traits[i], trait TSRMLS_CC);
+ add_assoc_zval_ex(return_value, ce->traits[i]->name, ce->traits[i]->name_length + 1, trait);
+ }
+}
+/* }}} */
+
+/* {{{ proto public String[] ReflectionClass::getTraitNames()
+ Returns an array of names of traits used by this class */
+ZEND_METHOD(reflection_class, getTraitNames)
+{
+ reflection_object *intern;
+ zend_class_entry *ce;
+ zend_uint i;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(ce);
+
+ array_init(return_value);
+
+ for (i=0; i < ce->num_traits; i++) {
+ add_next_index_stringl(return_value, ce->traits[i]->name, ce->traits[i]->name_length, 1);
+ }
+}
+/* }}} */
+
+/* {{{ proto public arra ReflectionClass::getTraitaliases()
+ Returns an array of trait aliases */
+ZEND_METHOD(reflection_class, getTraitAliases)
+{
+ reflection_object *intern;
+ zend_class_entry *ce;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(ce);
+
+ array_init(return_value);
+
+ if (ce->trait_aliases) {
+ zend_uint i = 0;
+ while (ce->trait_aliases[i]) {
+ char *method_name;
+ int method_name_len;
+ zend_trait_method_reference *cur_ref = ce->trait_aliases[i]->trait_method;
+
+ if (ce->trait_aliases[i]->alias) {
+ method_name_len = spprintf(&method_name, 0, "%s::%s", cur_ref->ce->name, cur_ref->method_name);
+ add_assoc_stringl_ex(return_value, ce->trait_aliases[i]->alias, ce->trait_aliases[i]->alias_len + 1, method_name, method_name_len, 0);
+ }
+ i++;
+ }
+ }
+}
+/* }}} */
+
+/* {{{ proto public ReflectionClass ReflectionClass::getParentClass()
+ Returns the class' parent class, or, if none exists, FALSE */
+ZEND_METHOD(reflection_class, getParentClass)
+{
+ reflection_object *intern;
+ zend_class_entry *ce;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(ce);
+
+ if (ce->parent) {
+ zend_reflection_class_factory(ce->parent, return_value TSRMLS_CC);
+ } else {
+ RETURN_FALSE;
+ }
+}
+/* }}} */
+
+/* {{{ proto public bool ReflectionClass::isSubclassOf(string|ReflectionClass class)
+ Returns whether this class is a subclass of another class */
+ZEND_METHOD(reflection_class, isSubclassOf)
+{
+ reflection_object *intern, *argument;
+ zend_class_entry *ce, **pce, *class_ce;
+ zval *class_name;
+
+ METHOD_NOTSTATIC(reflection_class_ptr);
+ GET_REFLECTION_OBJECT_PTR(ce);
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &class_name) == FAILURE) {
+ return;
+ }
+
+ switch(class_name->type) {
+ case IS_STRING:
+ if (zend_lookup_class(Z_STRVAL_P(class_name), Z_STRLEN_P(class_name), &pce TSRMLS_CC) == FAILURE) {
+ zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
+ "Class %s does not exist", Z_STRVAL_P(class_name));
+ return;
+ }
+ class_ce = *pce;
+ break;
+ case IS_OBJECT:
+ if (instanceof_function(Z_OBJCE_P(class_name), reflection_class_ptr TSRMLS_CC)) {
+ argument = (reflection_object *) zend_object_store_get_object(class_name TSRMLS_CC);
+ if (argument == NULL || argument->ptr == NULL) {
+ php_error_docref(NULL TSRMLS_CC, E_ERROR, "Internal error: Failed to retrieve the argument's reflection object");
+ /* Bails out */
+ }
+ class_ce = argument->ptr;
+ break;
+ }
+ /* no break */
+ default:
+ zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
+ "Parameter one must either be a string or a ReflectionClass object");
+ return;
+ }
+
+ RETURN_BOOL((ce != class_ce && instanceof_function(ce, class_ce TSRMLS_CC)));
+}
+/* }}} */
+
+/* {{{ proto public bool ReflectionClass::implementsInterface(string|ReflectionClass interface_name)
+ Returns whether this class is a subclass of another class */
+ZEND_METHOD(reflection_class, implementsInterface)
+{
+ reflection_object *intern, *argument;
+ zend_class_entry *ce, *interface_ce, **pce;
+ zval *interface;
+
+ METHOD_NOTSTATIC(reflection_class_ptr);
+ GET_REFLECTION_OBJECT_PTR(ce);
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &interface) == FAILURE) {
+ return;
+ }
+
+ switch(interface->type) {
+ case IS_STRING:
+ if (zend_lookup_class(Z_STRVAL_P(interface), Z_STRLEN_P(interface), &pce TSRMLS_CC) == FAILURE) {
+ zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
+ "Interface %s does not exist", Z_STRVAL_P(interface));
+ return;
+ }
+ interface_ce = *pce;
+ break;
+ case IS_OBJECT:
+ if (instanceof_function(Z_OBJCE_P(interface), reflection_class_ptr TSRMLS_CC)) {
+ argument = (reflection_object *) zend_object_store_get_object(interface TSRMLS_CC);
+ if (argument == NULL || argument->ptr == NULL) {
+ php_error_docref(NULL TSRMLS_CC, E_ERROR, "Internal error: Failed to retrieve the argument's reflection object");
+ /* Bails out */
+ }
+ interface_ce = argument->ptr;
+ break;
+ }
+ /* no break */
+ default:
+ zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
+ "Parameter one must either be a string or a ReflectionClass object");
+ return;
+ }
+
+ if (!(interface_ce->ce_flags & ZEND_ACC_INTERFACE)) {
+ zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
+ "Interface %s is a Class", interface_ce->name);
+ return;
+ }
+ RETURN_BOOL(instanceof_function(ce, interface_ce TSRMLS_CC));
+}
+/* }}} */
+
+/* {{{ proto public bool ReflectionClass::isIterateable()
+ Returns whether this class is iterateable (can be used inside foreach) */
+ZEND_METHOD(reflection_class, isIterateable)
+{
+ reflection_object *intern;
+ zend_class_entry *ce;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+
+ METHOD_NOTSTATIC(reflection_class_ptr);
+ GET_REFLECTION_OBJECT_PTR(ce);
+
+ RETURN_BOOL(ce->get_iterator != NULL);
+}
+/* }}} */
+
+/* {{{ proto public ReflectionExtension|NULL ReflectionClass::getExtension()
+ Returns NULL or the extension the class belongs to */
+ZEND_METHOD(reflection_class, getExtension)
+{
+ reflection_object *intern;
+ zend_class_entry *ce;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+
+ METHOD_NOTSTATIC(reflection_class_ptr);
+ GET_REFLECTION_OBJECT_PTR(ce);
+
+ if ((ce->type == ZEND_INTERNAL_CLASS) && ce->info.internal.module) {
+ reflection_extension_factory(return_value, ce->info.internal.module->name TSRMLS_CC);
+ }
+}
+/* }}} */
+
+/* {{{ proto public string|false ReflectionClass::getExtensionName()
+ Returns false or the name of the extension the class belongs to */
+ZEND_METHOD(reflection_class, getExtensionName)
+{
+ reflection_object *intern;
+ zend_class_entry *ce;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+
+ METHOD_NOTSTATIC(reflection_class_ptr);
+ GET_REFLECTION_OBJECT_PTR(ce);
+
+ if ((ce->type == ZEND_INTERNAL_CLASS) && ce->info.internal.module) {
+ RETURN_STRING(ce->info.internal.module->name, 1);
+ } else {
+ RETURN_FALSE;
+ }
+}
+/* }}} */
+
+/* {{{ proto public bool ReflectionClass::inNamespace()
+ Returns whether this class is defined in namespace */
+ZEND_METHOD(reflection_class, inNamespace)
+{
+ zval **name;
+ const char *backslash;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ if (zend_hash_find(Z_OBJPROP_P(getThis()), "name", sizeof("name"), (void **) &name) == FAILURE) {
+ RETURN_FALSE;
+ }
+ if (Z_TYPE_PP(name) == IS_STRING
+ && (backslash = zend_memrchr(Z_STRVAL_PP(name), '\\', Z_STRLEN_PP(name)))
+ && backslash > Z_STRVAL_PP(name))
+ {
+ RETURN_TRUE;
+ }
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto public string ReflectionClass::getNamespaceName()
+ Returns the name of namespace where this class is defined */
+ZEND_METHOD(reflection_class, getNamespaceName)
+{
+ zval **name;
+ const char *backslash;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ if (zend_hash_find(Z_OBJPROP_P(getThis()), "name", sizeof("name"), (void **) &name) == FAILURE) {
+ RETURN_FALSE;
+ }
+ if (Z_TYPE_PP(name) == IS_STRING
+ && (backslash = zend_memrchr(Z_STRVAL_PP(name), '\\', Z_STRLEN_PP(name)))
+ && backslash > Z_STRVAL_PP(name))
+ {
+ RETURN_STRINGL(Z_STRVAL_PP(name), backslash - Z_STRVAL_PP(name), 1);
+ }
+ RETURN_EMPTY_STRING();
+}
+/* }}} */
+
+/* {{{ proto public string ReflectionClass::getShortName()
+ Returns the short name of the class (without namespace part) */
+ZEND_METHOD(reflection_class, getShortName)
+{
+ zval **name;
+ const char *backslash;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ if (zend_hash_find(Z_OBJPROP_P(getThis()), "name", sizeof("name"), (void **) &name) == FAILURE) {
+ RETURN_FALSE;
+ }
+ if (Z_TYPE_PP(name) == IS_STRING
+ && (backslash = zend_memrchr(Z_STRVAL_PP(name), '\\', Z_STRLEN_PP(name)))
+ && backslash > Z_STRVAL_PP(name))
+ {
+ RETURN_STRINGL(backslash + 1, Z_STRLEN_PP(name) - (backslash - Z_STRVAL_PP(name) + 1), 1);
+ }
+ RETURN_ZVAL(*name, 1, 0);
+}
+/* }}} */
+
+/* {{{ proto public static mixed ReflectionObject::export(mixed argument [, bool return]) throws ReflectionException
+ Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */
+ZEND_METHOD(reflection_object, export)
+{
+ _reflection_export(INTERNAL_FUNCTION_PARAM_PASSTHRU, reflection_object_ptr, 1);
+}
+/* }}} */
+
+/* {{{ proto public void ReflectionObject::__construct(mixed argument) throws ReflectionException
+ Constructor. Takes an instance as an argument */
+ZEND_METHOD(reflection_object, __construct)
+{
+ reflection_class_object_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
+}
+/* }}} */
+
+/* {{{ proto public static mixed ReflectionProperty::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_property, export)
+{
+ _reflection_export(INTERNAL_FUNCTION_PARAM_PASSTHRU, reflection_property_ptr, 2);
+}
+/* }}} */
+
+/* {{{ proto public void ReflectionProperty::__construct(mixed class, string name)
+ Constructor. Throws an Exception in case the given property does not exist */
+ZEND_METHOD(reflection_property, __construct)
+{
+ zval *propname, *classname;
+ char *name_str;
+ const char *class_name, *prop_name;
+ int name_len, dynam_prop = 0;
+ zval *object;
+ reflection_object *intern;
+ zend_class_entry **pce;
+ zend_class_entry *ce;
+ zend_property_info *property_info = NULL;
+ property_reference *reference;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zs", &classname, &name_str, &name_len) == FAILURE) {
+ return;
+ }
+
+ object = getThis();
+ intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
+ if (intern == NULL) {
+ return;
+ }
+
+ /* Find the class entry */
+ switch (Z_TYPE_P(classname)) {
+ case IS_STRING:
+ if (zend_lookup_class(Z_STRVAL_P(classname), Z_STRLEN_P(classname), &pce TSRMLS_CC) == FAILURE) {
+ zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
+ "Class %s does not exist", Z_STRVAL_P(classname));
+ return;
+ }
+ ce = *pce;
+ break;
+
+ case IS_OBJECT:
+ ce = Z_OBJCE_P(classname);
+ break;
+
+ default:
+ _DO_THROW("The parameter class is expected to be either a string or an object");
+ /* returns out of this function */
+ }
+
+ if (zend_hash_find(&ce->properties_info, name_str, name_len + 1, (void **) &property_info) == FAILURE || (property_info->flags & ZEND_ACC_SHADOW)) {
+ /* Check for dynamic properties */
+ if (property_info == NULL && Z_TYPE_P(classname) == IS_OBJECT && Z_OBJ_HT_P(classname)->get_properties) {
+ if (zend_hash_exists(Z_OBJ_HT_P(classname)->get_properties(classname TSRMLS_CC), name_str, name_len+1)) {
+ dynam_prop = 1;
+ }
+ }
+ if (dynam_prop == 0) {
+ zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Property %s::$%s does not exist", ce->name, name_str);
+ return;
+ }
+ }
+
+ if (dynam_prop == 0 && (property_info->flags & ZEND_ACC_PRIVATE) == 0) {
+ /* we have to search the class hierarchy for this (implicit) public or protected property */
+ zend_class_entry *tmp_ce = ce;
+ zend_property_info *tmp_info;
+
+ while (tmp_ce && zend_hash_find(&tmp_ce->properties_info, name_str, name_len + 1, (void **) &tmp_info) != SUCCESS) {
+ ce = tmp_ce;
+ property_info = tmp_info;
+ tmp_ce = tmp_ce->parent;
+ }
+ }
+
+ MAKE_STD_ZVAL(classname);
+ MAKE_STD_ZVAL(propname);
+
+ if (dynam_prop == 0) {
+ zend_unmangle_property_name(property_info->name, property_info->name_length, &class_name, &prop_name);
+ ZVAL_STRINGL(classname, property_info->ce->name, property_info->ce->name_length, 1);
+ ZVAL_STRING(propname, prop_name, 1);
+ } else {
+ ZVAL_STRINGL(classname, ce->name, ce->name_length, 1);
+ ZVAL_STRINGL(propname, name_str, name_len, 1);
+ }
+ reflection_update_property(object, "class", classname);
+ reflection_update_property(object, "name", propname);
+
+ reference = (property_reference*) emalloc(sizeof(property_reference));
+ if (dynam_prop) {
+ reference->prop.flags = ZEND_ACC_IMPLICIT_PUBLIC;
+ reference->prop.name = Z_STRVAL_P(propname);
+ reference->prop.name_length = Z_STRLEN_P(propname);
+ reference->prop.h = zend_get_hash_value(name_str, name_len+1);
+ reference->prop.doc_comment = NULL;
+ reference->prop.ce = ce;
+ } else {
+ reference->prop = *property_info;
+ }
+ reference->ce = ce;
+ intern->ptr = reference;
+ intern->ref_type = REF_TYPE_PROPERTY;
+ intern->ce = ce;
+ intern->ignore_visibility = 0;
+}
+/* }}} */
+
+/* {{{ proto public string ReflectionProperty::__toString()
+ Returns a string representation */
+ZEND_METHOD(reflection_property, __toString)
+{
+ reflection_object *intern;
+ property_reference *ref;
+ string str;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(ref);
+ string_init(&str);
+ _property_string(&str, &ref->prop, NULL, "" TSRMLS_CC);
+ RETURN_STRINGL(str.string, str.len - 1, 0);
+}
+/* }}} */
+
+/* {{{ proto public string ReflectionProperty::getName()
+ Returns the class' name */
+ZEND_METHOD(reflection_property, getName)
+{
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ _default_get_entry(getThis(), "name", sizeof("name"), return_value TSRMLS_CC);
+}
+/* }}} */
+
+static void _property_check_flag(INTERNAL_FUNCTION_PARAMETERS, int mask) /* {{{ */
+{
+ reflection_object *intern;
+ property_reference *ref;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(ref);
+ RETURN_BOOL(ref->prop.flags & mask);
+}
+/* }}} */
+
+/* {{{ proto public bool ReflectionProperty::isPublic()
+ Returns whether this property is public */
+ZEND_METHOD(reflection_property, isPublic)
+{
+ _property_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_PUBLIC | ZEND_ACC_IMPLICIT_PUBLIC);
+}
+/* }}} */
+
+/* {{{ proto public bool ReflectionProperty::isPrivate()
+ Returns whether this property is private */
+ZEND_METHOD(reflection_property, isPrivate)
+{
+ _property_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_PRIVATE);
+}
+/* }}} */
+
+/* {{{ proto public bool ReflectionProperty::isProtected()
+ Returns whether this property is protected */
+ZEND_METHOD(reflection_property, isProtected)
+{
+ _property_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_PROTECTED);
+}
+/* }}} */
+
+/* {{{ proto public bool ReflectionProperty::isStatic()
+ Returns whether this property is static */
+ZEND_METHOD(reflection_property, isStatic)
+{
+ _property_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_STATIC);
+}
+/* }}} */
+
+/* {{{ proto public bool ReflectionProperty::isDefault()
+ Returns whether this property is default (declared at compilation time). */
+ZEND_METHOD(reflection_property, isDefault)
+{
+ _property_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ~ZEND_ACC_IMPLICIT_PUBLIC);
+}
+/* }}} */
+
+/* {{{ proto public int ReflectionProperty::getModifiers()
+ Returns a bitfield of the access modifiers for this property */
+ZEND_METHOD(reflection_property, getModifiers)
+{
+ reflection_object *intern;
+ property_reference *ref;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(ref);
+
+ RETURN_LONG(ref->prop.flags);
+}
+/* }}} */
+
+/* {{{ proto public mixed ReflectionProperty::getValue([stdclass object])
+ Returns this property's value */
+ZEND_METHOD(reflection_property, getValue)
+{
+ reflection_object *intern;
+ property_reference *ref;
+ zval *object, name;
+ zval *member_p = NULL;
+
+ METHOD_NOTSTATIC(reflection_property_ptr);
+ GET_REFLECTION_OBJECT_PTR(ref);
+
+ if (!(ref->prop.flags & (ZEND_ACC_PUBLIC | ZEND_ACC_IMPLICIT_PUBLIC)) && intern->ignore_visibility == 0) {
+ _default_get_entry(getThis(), "name", sizeof("name"), &name TSRMLS_CC);
+ zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
+ "Cannot access non-public member %s::%s", intern->ce->name, Z_STRVAL(name));
+ zval_dtor(&name);
+ return;
+ }
+
+ if ((ref->prop.flags & ZEND_ACC_STATIC)) {
+ zend_update_class_constants(intern->ce TSRMLS_CC);
+ if (!CE_STATIC_MEMBERS(intern->ce)[ref->prop.offset]) {
+ php_error_docref(NULL TSRMLS_CC, E_ERROR, "Internal error: Could not find the property %s::%s", intern->ce->name, ref->prop.name);
+ /* Bails out */
+ }
+ *return_value= *CE_STATIC_MEMBERS(intern->ce)[ref->prop.offset];
+ zval_copy_ctor(return_value);
+ INIT_PZVAL(return_value);
+ } else {
+ const char *class_name, *prop_name;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &object) == FAILURE) {
+ return;
+ }
+ zend_unmangle_property_name(ref->prop.name, ref->prop.name_length, &class_name, &prop_name);
+ member_p = zend_read_property(ref->ce, object, prop_name, strlen(prop_name), 1 TSRMLS_CC);
+ MAKE_COPY_ZVAL(&member_p, return_value);
+ if (member_p != EG(uninitialized_zval_ptr)) {
+ zval_add_ref(&member_p);
+ zval_ptr_dtor(&member_p);
+ }
+ }
+}
+/* }}} */
+
+/* {{{ proto public void ReflectionProperty::setValue([stdclass object,] mixed value)
+ Sets this property's value */
+ZEND_METHOD(reflection_property, setValue)
+{
+ reflection_object *intern;
+ property_reference *ref;
+ zval **variable_ptr;
+ zval *object, name;
+ zval *value;
+ zval *tmp;
+
+ METHOD_NOTSTATIC(reflection_property_ptr);
+ GET_REFLECTION_OBJECT_PTR(ref);
+
+ if (!(ref->prop.flags & ZEND_ACC_PUBLIC) && intern->ignore_visibility == 0) {
+ _default_get_entry(getThis(), "name", sizeof("name"), &name TSRMLS_CC);
+ zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
+ "Cannot access non-public member %s::%s", intern->ce->name, Z_STRVAL(name));
+ zval_dtor(&name);
+ return;
+ }
+
+ 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;
+ }
+ }
+ zend_update_class_constants(intern->ce TSRMLS_CC);
+
+ if (!CE_STATIC_MEMBERS(intern->ce)[ref->prop.offset]) {
+ php_error_docref(NULL TSRMLS_CC, E_ERROR, "Internal error: Could not find the property %s::%s", intern->ce->name, ref->prop.name);
+ /* Bails out */
+ }
+ variable_ptr = &CE_STATIC_MEMBERS(intern->ce)[ref->prop.offset];
+ if (*variable_ptr != value) {
+ if (PZVAL_IS_REF(*variable_ptr)) {
+ zval garbage = **variable_ptr; /* old value should be destroyed */
+
+ /* To check: can't *variable_ptr be some system variable like error_zval here? */
+ Z_TYPE_PP(variable_ptr) = Z_TYPE_P(value);
+ (*variable_ptr)->value = value->value;
+ if (Z_REFCOUNT_P(value) > 0) {
+ zval_copy_ctor(*variable_ptr);
+ }
+ zval_dtor(&garbage);
+ } else {
+ zval *garbage = *variable_ptr;
+
+ /* if we assign referenced variable, we should separate it */
+ Z_ADDREF_P(value);
+ if (PZVAL_IS_REF(value)) {
+ SEPARATE_ZVAL(&value);
+ }
+ *variable_ptr = value;
+ zval_ptr_dtor(&garbage);
+ }
+ }
+ } else {
+ const char *class_name, *prop_name;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "oz", &object, &value) == FAILURE) {
+ return;
+ }
+ zend_unmangle_property_name(ref->prop.name, ref->prop.name_length, &class_name, &prop_name);
+ zend_update_property(ref->ce, object, prop_name, strlen(prop_name), value TSRMLS_CC);
+ }
+}
+/* }}} */
+
+/* {{{ proto public ReflectionClass ReflectionProperty::getDeclaringClass()
+ Get the declaring class */
+ZEND_METHOD(reflection_property, getDeclaringClass)
+{
+ reflection_object *intern;
+ property_reference *ref;
+ zend_class_entry *tmp_ce, *ce;
+ zend_property_info *tmp_info;
+ const char *prop_name, *class_name;
+ int prop_name_len;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(ref);
+
+ if (zend_unmangle_property_name(ref->prop.name, ref->prop.name_length, &class_name, &prop_name) != SUCCESS) {
+ RETURN_FALSE;
+ }
+
+ prop_name_len = strlen(prop_name);
+ ce = tmp_ce = ref->ce;
+ while (tmp_ce && zend_hash_find(&tmp_ce->properties_info, prop_name, prop_name_len + 1, (void **) &tmp_info) == SUCCESS) {
+ if (tmp_info->flags & ZEND_ACC_PRIVATE || tmp_info->flags & ZEND_ACC_SHADOW) {
+ /* it's a private property, so it can't be inherited */
+ break;
+ }
+ ce = tmp_ce;
+ if (tmp_ce == tmp_info->ce) {
+ /* declared in this class, done */
+ break;
+ }
+ tmp_ce = tmp_ce->parent;
+ }
+
+ zend_reflection_class_factory(ce, return_value TSRMLS_CC);
+}
+/* }}} */
+
+/* {{{ proto public string ReflectionProperty::getDocComment()
+ Returns the doc comment for this property */
+ZEND_METHOD(reflection_property, getDocComment)
+{
+ reflection_object *intern;
+ property_reference *ref;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(ref);
+ if (ref->prop.doc_comment) {
+ RETURN_STRINGL(ref->prop.doc_comment, ref->prop.doc_comment_len, 1);
+ }
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto public int ReflectionProperty::setAccessible(bool visible)
+ Sets whether non-public properties can be requested */
+ZEND_METHOD(reflection_property, setAccessible)
+{
+ reflection_object *intern;
+ zend_bool visible;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &visible) == FAILURE) {
+ return;
+ }
+
+ intern = (reflection_object *) zend_object_store_get_object(getThis() TSRMLS_CC);
+
+ if (intern == NULL) {
+ return;
+ }
+
+ intern->ignore_visibility = visible;
+}
+/* }}} */
+
+/* {{{ proto public static mixed ReflectionExtension::export(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_extension, export)
+{
+ _reflection_export(INTERNAL_FUNCTION_PARAM_PASSTHRU, reflection_extension_ptr, 1);
+}
+/* }}} */
+
+/* {{{ proto public void ReflectionExtension::__construct(string name)
+ Constructor. Throws an Exception in case the given extension does not exist */
+ZEND_METHOD(reflection_extension, __construct)
+{
+ zval *name;
+ zval *object;
+ char *lcname;
+ reflection_object *intern;
+ zend_module_entry *module;
+ char *name_str;
+ int name_len;
+ ALLOCA_FLAG(use_heap)
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name_str, &name_len) == FAILURE) {
+ return;
+ }
+
+ object = getThis();
+ intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
+ if (intern == NULL) {
+ return;
+ }
+ lcname = do_alloca(name_len + 1, use_heap);
+ zend_str_tolower_copy(lcname, name_str, name_len);
+ if (zend_hash_find(&module_registry, lcname, name_len + 1, (void **)&module) == FAILURE) {
+ free_alloca(lcname, use_heap);
+ zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
+ "Extension %s does not exist", name_str);
+ return;
+ }
+ free_alloca(lcname, use_heap);
+ MAKE_STD_ZVAL(name);
+ ZVAL_STRING(name, module->name, 1);
+ reflection_update_property( object, "name", name);
+ intern->ptr = module;
+ intern->ref_type = REF_TYPE_OTHER;
+ intern->ce = NULL;
+}
+/* }}} */
+
+/* {{{ proto public string ReflectionExtension::__toString()
+ Returns a string representation */
+ZEND_METHOD(reflection_extension, __toString)
+{
+ reflection_object *intern;
+ zend_module_entry *module;
+ string str;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(module);
+ string_init(&str);
+ _extension_string(&str, module, "" TSRMLS_CC);
+ RETURN_STRINGL(str.string, str.len - 1, 0);
+}
+/* }}} */
+
+/* {{{ proto public string ReflectionExtension::getName()
+ Returns this extension's name */
+ZEND_METHOD(reflection_extension, getName)
+{
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ _default_get_entry(getThis(), "name", sizeof("name"), return_value TSRMLS_CC);
+}
+/* }}} */
+
+/* {{{ proto public string ReflectionExtension::getVersion()
+ Returns this extension's version */
+ZEND_METHOD(reflection_extension, getVersion)
+{
+ reflection_object *intern;
+ zend_module_entry *module;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(module);
+
+ /* An extension does not necessarily have a version number */
+ if (module->version == NO_VERSION_YET) {
+ RETURN_NULL();
+ } else {
+ RETURN_STRING(module->version, 1);
+ }
+}
+/* }}} */
+
+/* {{{ proto public ReflectionFunction[] ReflectionExtension::getFunctions()
+ Returns an array of this extension's fuctions */
+ZEND_METHOD(reflection_extension, getFunctions)
+{
+ reflection_object *intern;
+ zend_module_entry *module;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(module);
+
+ array_init(return_value);
+ if (module->functions) {
+ zval *function;
+ zend_function *fptr;
+ const zend_function_entry *func = module->functions;
+
+ /* Is there a better way of doing this? */
+ while (func->fname) {
+ int fname_len = strlen(func->fname);
+ char *lc_name = zend_str_tolower_dup(func->fname, fname_len);
+
+ if (zend_hash_find(EG(function_table), lc_name, fname_len + 1, (void**) &fptr) == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Internal error: Cannot find extension function %s in global function table", func->fname);
+ func++;
+ efree(lc_name);
+ continue;
+ }
+
+ ALLOC_ZVAL(function);
+ reflection_function_factory(fptr, NULL, function TSRMLS_CC);
+ add_assoc_zval_ex(return_value, func->fname, fname_len+1, function);
+ func++;
+ efree(lc_name);
+ }
+ }
+}
+/* }}} */
+
+static int _addconstant(zend_constant *constant TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */
+{
+ zval *const_val;
+ zval *retval = va_arg(args, zval*);
+ int number = va_arg(args, int);
+
+ if (number == constant->module_number) {
+ ALLOC_ZVAL(const_val);
+ *const_val = constant->value;
+ zval_copy_ctor(const_val);
+ INIT_PZVAL(const_val);
+ add_assoc_zval_ex(retval, constant->name, constant->name_len, const_val);
+ }
+ return 0;
+}
+/* }}} */
+
+/* {{{ proto public array ReflectionExtension::getConstants()
+ Returns an associative array containing this extension's constants and their values */
+ZEND_METHOD(reflection_extension, getConstants)
+{
+ reflection_object *intern;
+ zend_module_entry *module;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(module);
+
+ array_init(return_value);
+ zend_hash_apply_with_arguments(EG(zend_constants) TSRMLS_CC, (apply_func_args_t) _addconstant, 2, return_value, module->module_number);
+}
+/* }}} */
+
+/* {{{ _addinientry */
+static int _addinientry(zend_ini_entry *ini_entry TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key)
+{
+ zval *retval = va_arg(args, zval*);
+ int number = va_arg(args, int);
+
+ if (number == ini_entry->module_number) {
+ if (ini_entry->value) {
+ add_assoc_stringl(retval, ini_entry->name, ini_entry->value, ini_entry->value_length, 1);
+ } else {
+ add_assoc_null(retval, ini_entry->name);
+ }
+ }
+ return ZEND_HASH_APPLY_KEEP;
+}
+/* }}} */
+
+/* {{{ proto public array ReflectionExtension::getINIEntries()
+ Returns an associative array containing this extension's INI entries and their values */
+ZEND_METHOD(reflection_extension, getINIEntries)
+{
+ reflection_object *intern;
+ zend_module_entry *module;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(module);
+
+ array_init(return_value);
+ zend_hash_apply_with_arguments(EG(ini_directives) TSRMLS_CC, (apply_func_args_t) _addinientry, 2, return_value, module->module_number);
+}
+/* }}} */
+
+/* {{{ add_extension_class */
+static int add_extension_class(zend_class_entry **pce TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key)
+{
+ zval *class_array = va_arg(args, zval*), *zclass;
+ struct _zend_module_entry *module = va_arg(args, struct _zend_module_entry*);
+ int add_reflection_class = va_arg(args, int);
+
+ if (((*pce)->type == ZEND_INTERNAL_CLASS) && (*pce)->info.internal.module && !strcasecmp((*pce)->info.internal.module->name, module->name)) {
+ if (add_reflection_class) {
+ ALLOC_ZVAL(zclass);
+ zend_reflection_class_factory(*pce, zclass TSRMLS_CC);
+ add_assoc_zval_ex(class_array, (*pce)->name, (*pce)->name_length + 1, zclass);
+ } else {
+ add_next_index_stringl(class_array, (*pce)->name, (*pce)->name_length, 1);
+ }
+ }
+ return ZEND_HASH_APPLY_KEEP;
+}
+/* }}} */
+
+/* {{{ proto public ReflectionClass[] ReflectionExtension::getClasses()
+ Returns an array containing ReflectionClass objects for all classes of this extension */
+ZEND_METHOD(reflection_extension, getClasses)
+{
+ reflection_object *intern;
+ zend_module_entry *module;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(module);
+
+ array_init(return_value);
+ zend_hash_apply_with_arguments(EG(class_table) TSRMLS_CC, (apply_func_args_t) add_extension_class, 3, return_value, module, 1);
+}
+/* }}} */
+
+/* {{{ proto public array ReflectionExtension::getClassNames()
+ Returns an array containing all names of all classes of this extension */
+ZEND_METHOD(reflection_extension, getClassNames)
+{
+ reflection_object *intern;
+ zend_module_entry *module;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(module);
+
+ array_init(return_value);
+ zend_hash_apply_with_arguments(EG(class_table) TSRMLS_CC, (apply_func_args_t) add_extension_class, 3, return_value, module, 0);
+}
+/* }}} */
+
+/* {{{ proto public array ReflectionExtension::getDependencies()
+ Returns an array containing all names of all extensions this extension depends on */
+ZEND_METHOD(reflection_extension, getDependencies)
+{
+ reflection_object *intern;
+ zend_module_entry *module;
+ const zend_module_dep *dep;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(module);
+
+ array_init(return_value);
+
+ dep = module->deps;
+
+ if (!dep)
+ {
+ return;
+ }
+
+ while(dep->name) {
+ char *relation;
+ char *rel_type;
+ int len;
+
+ switch(dep->type) {
+ case MODULE_DEP_REQUIRED:
+ rel_type = "Required";
+ break;
+ case MODULE_DEP_CONFLICTS:
+ rel_type = "Conflicts";
+ break;
+ case MODULE_DEP_OPTIONAL:
+ rel_type = "Optional";
+ break;
+ default:
+ rel_type = "Error"; /* shouldn't happen */
+ break;
+ }
+
+ len = spprintf(&relation, 0, "%s%s%s%s%s",
+ rel_type,
+ dep->rel ? " " : "",
+ dep->rel ? dep->rel : "",
+ dep->version ? " " : "",
+ dep->version ? dep->version : "");
+ add_assoc_stringl(return_value, dep->name, relation, len, 0);
+ dep++;
+ }
+}
+/* }}} */
+
+/* {{{ proto public void ReflectionExtension::info()
+ Prints phpinfo block for the extension */
+ZEND_METHOD(reflection_extension, info)
+{
+ reflection_object *intern;
+ zend_module_entry *module;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(module);
+
+ php_info_print_module(module TSRMLS_CC);
+}
+/* }}} */
+
+/* {{{ proto public bool ReflectionExtension::isPersistent()
+ Returns whether this extension is persistent */
+ZEND_METHOD(reflection_extension, isPersistent)
+{
+ reflection_object *intern;
+ zend_module_entry *module;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(module);
+
+ RETURN_BOOL(module->type == MODULE_PERSISTENT);
+}
+/* }}} */
+
+/* {{{ proto public bool ReflectionExtension::isTemporary()
+ Returns whether this extension is temporary */
+ZEND_METHOD(reflection_extension, isTemporary)
+{
+ reflection_object *intern;
+ zend_module_entry *module;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(module);
+
+ RETURN_BOOL(module->type == MODULE_TEMPORARY);
+}
+/* }}} */
+
+/* {{{ proto public static mixed ReflectionZendExtension::export(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_zend_extension, export)
+{
+ _reflection_export(INTERNAL_FUNCTION_PARAM_PASSTHRU, reflection_zend_extension_ptr, 1);
+}
+/* }}} */
+
+/* {{{ proto public void ReflectionZendExtension::__construct(string name)
+ Constructor. Throws an Exception in case the given Zend extension does not exist */
+ZEND_METHOD(reflection_zend_extension, __construct)
+{
+ zval *name;
+ zval *object;
+ reflection_object *intern;
+ zend_extension *extension;
+ char *name_str;
+ int name_len;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name_str, &name_len) == FAILURE) {
+ return;
+ }
+
+ object = getThis();
+ intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
+ if (intern == NULL) {
+ return;
+ }
+
+ extension = zend_get_extension(name_str);
+ if (!extension) {
+ zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
+ "Zend Extension %s does not exist", name_str);
+ return;
+ }
+ MAKE_STD_ZVAL(name);
+ ZVAL_STRING(name, extension->name, 1);
+ reflection_update_property(object, "name", name);
+ intern->ptr = extension;
+ intern->ref_type = REF_TYPE_OTHER;
+ intern->ce = NULL;
+}
+/* }}} */
+
+/* {{{ proto public string ReflectionZendExtension::__toString()
+ Returns a string representation */
+ZEND_METHOD(reflection_zend_extension, __toString)
+{
+ reflection_object *intern;
+ zend_extension *extension;
+ string str;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(extension);
+ string_init(&str);
+ _zend_extension_string(&str, extension, "" TSRMLS_CC);
+ RETURN_STRINGL(str.string, str.len - 1, 0);
+}
+/* }}} */
+
+/* {{{ proto public string ReflectionZendExtension::getName()
+ Returns the name of this Zend extension */
+ZEND_METHOD(reflection_zend_extension, getName)
+{
+ reflection_object *intern;
+ zend_extension *extension;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(extension);
+
+ RETURN_STRING(extension->name, 1);
+}
+/* }}} */
+
+/* {{{ proto public string ReflectionZendExtension::getVersion()
+ Returns the version information of this Zend extension */
+ZEND_METHOD(reflection_zend_extension, getVersion)
+{
+ reflection_object *intern;
+ zend_extension *extension;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(extension);
+
+ RETURN_STRING(extension->version ? extension->version : "", 1);
+}
+/* }}} */
+
+/* {{{ proto public void ReflectionZendExtension::getAuthor()
+ * Returns the name of this Zend extension's author */
+ZEND_METHOD(reflection_zend_extension, getAuthor)
+{
+ reflection_object *intern;
+ zend_extension *extension;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(extension);
+
+ RETURN_STRING(extension->author ? extension->author : "", 1);
+}
+/* }}} */
+
+/* {{{ proto public void ReflectionZendExtension::getURL()
+ Returns this Zend extension's URL*/
+ZEND_METHOD(reflection_zend_extension, getURL)
+{
+ reflection_object *intern;
+ zend_extension *extension;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(extension);
+
+ RETURN_STRING(extension->URL ? extension->URL : "", 1);
+}
+/* }}} */
+
+/* {{{ proto public void ReflectionZendExtension::getCopyright()
+ Returns this Zend extension's copyright information */
+ZEND_METHOD(reflection_zend_extension, getCopyright)
+{
+ reflection_object *intern;
+ zend_extension *extension;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ GET_REFLECTION_OBJECT_PTR(extension);
+
+ RETURN_STRING(extension->copyright ? extension->copyright : "", 1);
+}
+/* }}} */
+
+/* {{{ method tables */
+static const zend_function_entry reflection_exception_functions[] = {
+ PHP_FE_END
+};
+
+ZEND_BEGIN_ARG_INFO(arginfo_reflection__void, 0)
+ZEND_END_ARG_INFO()
+
+
+ZEND_BEGIN_ARG_INFO(arginfo_reflection_getModifierNames, 0)
+ ZEND_ARG_INFO(0, modifiers)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_export, 0, 0, 1)
+ ZEND_ARG_OBJ_INFO(0, reflector, Reflector, 0)
+ ZEND_ARG_INFO(0, return)
+ZEND_END_ARG_INFO()
+
+static const zend_function_entry reflection_functions[] = {
+ ZEND_ME(reflection, getModifierNames, arginfo_reflection_getModifierNames, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+ ZEND_ME(reflection, export, arginfo_reflection_export, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+ PHP_FE_END
+};
+
+static const zend_function_entry reflector_functions[] = {
+ ZEND_FENTRY(export, NULL, NULL, ZEND_ACC_STATIC|ZEND_ACC_ABSTRACT|ZEND_ACC_PUBLIC)
+ ZEND_ABSTRACT_ME(reflector, __toString, arginfo_reflection__void)
+ PHP_FE_END
+};
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_function_export, 0, 0, 1)
+ ZEND_ARG_INFO(0, name)
+ ZEND_ARG_INFO(0, return)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO(arginfo_reflection_function___construct, 0)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_function_invoke, 0, 0, 0)
+ ZEND_ARG_INFO(0, args)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO(arginfo_reflection_function_invokeArgs, 0)
+ ZEND_ARG_ARRAY_INFO(0, args, 0)
+ZEND_END_ARG_INFO()
+
+static const zend_function_entry reflection_function_abstract_functions[] = {
+ ZEND_ME(reflection, __clone, arginfo_reflection__void, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL)
+ PHP_ABSTRACT_ME(reflection_function, __toString, arginfo_reflection__void)
+ ZEND_ME(reflection_function, inNamespace, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_function, isClosure, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_function, isDeprecated, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_function, isInternal, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_function, isUserDefined, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_function, getClosureThis, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_function, getClosureScopeClass, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_function, getDocComment, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_function, getEndLine, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_function, getExtension, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_function, getExtensionName, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_function, getFileName, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_function, getName, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_function, getNamespaceName, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_function, getNumberOfParameters, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_function, getNumberOfRequiredParameters, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_function, getParameters, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_function, getShortName, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_function, getStartLine, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_function, getStaticVariables, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_function, returnsReference, arginfo_reflection__void, 0)
+ PHP_FE_END
+};
+
+static const zend_function_entry reflection_function_functions[] = {
+ ZEND_ME(reflection_function, __construct, arginfo_reflection_function___construct, 0)
+ ZEND_ME(reflection_function, __toString, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_function, export, arginfo_reflection_function_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC)
+ ZEND_ME(reflection_function, isDisabled, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_function, invoke, arginfo_reflection_function_invoke, 0)
+ ZEND_ME(reflection_function, invokeArgs, arginfo_reflection_function_invokeArgs, 0)
+ ZEND_ME(reflection_function, getClosure, arginfo_reflection__void, 0)
+ PHP_FE_END
+};
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_method_export, 0, 0, 2)
+ ZEND_ARG_INFO(0, class)
+ ZEND_ARG_INFO(0, name)
+ ZEND_ARG_INFO(0, return)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_method___construct, 0, 0, 1)
+ ZEND_ARG_INFO(0, class_or_method)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO(arginfo_reflection_method_invoke, 0)
+ ZEND_ARG_INFO(0, object)
+ ZEND_ARG_INFO(0, args)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO(arginfo_reflection_method_invokeArgs, 0)
+ ZEND_ARG_INFO(0, object)
+ ZEND_ARG_ARRAY_INFO(0, args, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO(arginfo_reflection_method_setAccessible, 0)
+ ZEND_ARG_INFO(0, value)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO(arginfo_reflection_method_getClosure, 0)
+ ZEND_ARG_INFO(0, object)
+ZEND_END_ARG_INFO()
+
+static const zend_function_entry reflection_method_functions[] = {
+ ZEND_ME(reflection_method, export, arginfo_reflection_method_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC)
+ ZEND_ME(reflection_method, __construct, arginfo_reflection_method___construct, 0)
+ ZEND_ME(reflection_method, __toString, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_method, isPublic, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_method, isPrivate, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_method, isProtected, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_method, isAbstract, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_method, isFinal, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_method, isStatic, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_method, isConstructor, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_method, isDestructor, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_method, getClosure, arginfo_reflection_method_getClosure, 0)
+ ZEND_ME(reflection_method, getModifiers, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_method, invoke, arginfo_reflection_method_invoke, 0)
+ ZEND_ME(reflection_method, invokeArgs, arginfo_reflection_method_invokeArgs, 0)
+ ZEND_ME(reflection_method, getDeclaringClass, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_method, getPrototype, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_property, setAccessible, arginfo_reflection_method_setAccessible, 0)
+ PHP_FE_END
+};
+
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_class_export, 0, 0, 1)
+ ZEND_ARG_INFO(0, argument)
+ ZEND_ARG_INFO(0, return)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO(arginfo_reflection_class___construct, 0)
+ ZEND_ARG_INFO(0, argument)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_class_getStaticPropertyValue, 0, 0, 1)
+ ZEND_ARG_INFO(0, name)
+ ZEND_ARG_INFO(0, default)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_setStaticPropertyValue, 0)
+ ZEND_ARG_INFO(0, name)
+ ZEND_ARG_INFO(0, value)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_hasMethod, 0)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_getMethod, 0)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_class_getMethods, 0, 0, 0)
+ ZEND_ARG_INFO(0, filter)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_hasProperty, 0)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_getProperty, 0)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_class_getProperties, 0, 0, 0)
+ ZEND_ARG_INFO(0, filter)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_hasConstant, 0)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_getConstant, 0)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_isInstance, 0)
+ ZEND_ARG_INFO(0, object)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_newInstance, 0)
+ ZEND_ARG_INFO(0, args)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_newInstanceWithoutConstructor, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_class_newInstanceArgs, 0, 0, 0)
+ ZEND_ARG_ARRAY_INFO(0, args, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_isSubclassOf, 0)
+ ZEND_ARG_INFO(0, class)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_implementsInterface, 0)
+ ZEND_ARG_INFO(0, interface)
+ZEND_END_ARG_INFO()
+
+static const zend_function_entry reflection_class_functions[] = {
+ ZEND_ME(reflection, __clone, arginfo_reflection__void, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL)
+ ZEND_ME(reflection_class, export, arginfo_reflection_class_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC)
+ ZEND_ME(reflection_class, __construct, arginfo_reflection_class___construct, 0)
+ ZEND_ME(reflection_class, __toString, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_class, getName, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_class, isInternal, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_class, isUserDefined, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_class, isInstantiable, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_class, isCloneable, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_class, getFileName, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_class, getStartLine, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_class, getEndLine, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_class, getDocComment, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_class, getConstructor, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_class, hasMethod, arginfo_reflection_class_hasMethod, 0)
+ ZEND_ME(reflection_class, getMethod, arginfo_reflection_class_getMethod, 0)
+ ZEND_ME(reflection_class, getMethods, arginfo_reflection_class_getMethods, 0)
+ ZEND_ME(reflection_class, hasProperty, arginfo_reflection_class_hasProperty, 0)
+ ZEND_ME(reflection_class, getProperty, arginfo_reflection_class_getProperty, 0)
+ ZEND_ME(reflection_class, getProperties, arginfo_reflection_class_getProperties, 0)
+ ZEND_ME(reflection_class, hasConstant, arginfo_reflection_class_hasConstant, 0)
+ ZEND_ME(reflection_class, getConstants, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_class, getConstant, arginfo_reflection_class_getConstant, 0)
+ ZEND_ME(reflection_class, getInterfaces, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_class, getInterfaceNames, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_class, isInterface, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_class, getTraits, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_class, getTraitNames, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_class, getTraitAliases, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_class, isTrait, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_class, isAbstract, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_class, isFinal, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_class, getModifiers, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_class, isInstance, arginfo_reflection_class_isInstance, 0)
+ ZEND_ME(reflection_class, newInstance, arginfo_reflection_class_newInstance, 0)
+ ZEND_ME(reflection_class, newInstanceWithoutConstructor, arginfo_reflection_class_newInstanceWithoutConstructor, 0)
+ ZEND_ME(reflection_class, newInstanceArgs, arginfo_reflection_class_newInstanceArgs, 0)
+ ZEND_ME(reflection_class, getParentClass, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_class, isSubclassOf, arginfo_reflection_class_isSubclassOf, 0)
+ ZEND_ME(reflection_class, getStaticProperties, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_class, getStaticPropertyValue, arginfo_reflection_class_getStaticPropertyValue, 0)
+ ZEND_ME(reflection_class, setStaticPropertyValue, arginfo_reflection_class_setStaticPropertyValue, 0)
+ ZEND_ME(reflection_class, getDefaultProperties, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_class, isIterateable, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_class, implementsInterface, arginfo_reflection_class_implementsInterface, 0)
+ ZEND_ME(reflection_class, getExtension, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_class, getExtensionName, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_class, inNamespace, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_class, getNamespaceName, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_class, getShortName, arginfo_reflection__void, 0)
+ PHP_FE_END
+};
+
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_object_export, 0, 0, 1)
+ ZEND_ARG_INFO(0, argument)
+ ZEND_ARG_INFO(0, return)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO(arginfo_reflection_object___construct, 0)
+ ZEND_ARG_INFO(0, argument)
+ZEND_END_ARG_INFO()
+
+static const zend_function_entry reflection_object_functions[] = {
+ ZEND_ME(reflection_object, export, arginfo_reflection_object_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC)
+ ZEND_ME(reflection_object, __construct, arginfo_reflection_object___construct, 0)
+ PHP_FE_END
+};
+
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_property_export, 0, 0, 2)
+ ZEND_ARG_INFO(0, class)
+ ZEND_ARG_INFO(0, name)
+ ZEND_ARG_INFO(0, return)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_property___construct, 0, 0, 2)
+ ZEND_ARG_INFO(0, class)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_property_getValue, 0, 0, 0)
+ ZEND_ARG_INFO(0, object)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_property_setValue, 0, 0, 1)
+ ZEND_ARG_INFO(0, object)
+ ZEND_ARG_INFO(0, value)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO(arginfo_reflection_property_setAccessible, 0)
+ ZEND_ARG_INFO(0, visible)
+ZEND_END_ARG_INFO()
+
+static const zend_function_entry reflection_property_functions[] = {
+ ZEND_ME(reflection, __clone, arginfo_reflection__void, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL)
+ ZEND_ME(reflection_property, export, arginfo_reflection_property_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC)
+ ZEND_ME(reflection_property, __construct, arginfo_reflection_property___construct, 0)
+ ZEND_ME(reflection_property, __toString, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_property, getName, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_property, getValue, arginfo_reflection_property_getValue, 0)
+ ZEND_ME(reflection_property, setValue, arginfo_reflection_property_setValue, 0)
+ ZEND_ME(reflection_property, isPublic, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_property, isPrivate, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_property, isProtected, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_property, isStatic, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_property, isDefault, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_property, getModifiers, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_property, getDeclaringClass, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_property, getDocComment, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_property, setAccessible, arginfo_reflection_property_setAccessible, 0)
+ PHP_FE_END
+};
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_parameter_export, 0, 0, 2)
+ ZEND_ARG_INFO(0, function)
+ ZEND_ARG_INFO(0, parameter)
+ ZEND_ARG_INFO(0, return)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO(arginfo_reflection_parameter___construct, 0)
+ ZEND_ARG_INFO(0, function)
+ ZEND_ARG_INFO(0, parameter)
+ZEND_END_ARG_INFO()
+
+static const zend_function_entry reflection_parameter_functions[] = {
+ ZEND_ME(reflection, __clone, arginfo_reflection__void, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL)
+ ZEND_ME(reflection_parameter, export, arginfo_reflection_parameter_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC)
+ ZEND_ME(reflection_parameter, __construct, arginfo_reflection_parameter___construct, 0)
+ ZEND_ME(reflection_parameter, __toString, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_parameter, getName, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_parameter, isPassedByReference, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_parameter, canBePassedByValue, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_parameter, getDeclaringFunction, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_parameter, getDeclaringClass, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_parameter, getClass, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_parameter, isArray, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_parameter, isCallable, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_parameter, allowsNull, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_parameter, getPosition, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_parameter, isOptional, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_parameter, isDefaultValueAvailable, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_parameter, getDefaultValue, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_parameter, isDefaultValueConstant, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_parameter, getDefaultValueConstantName, arginfo_reflection__void, 0)
+ PHP_FE_END
+};
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_extension_export, 0, 0, 1)
+ ZEND_ARG_INFO(0, name)
+ ZEND_ARG_INFO(0, return)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO(arginfo_reflection_extension___construct, 0)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO()
+
+static const zend_function_entry reflection_extension_functions[] = {
+ ZEND_ME(reflection, __clone, arginfo_reflection__void, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL)
+ ZEND_ME(reflection_extension, export, arginfo_reflection_extension_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC)
+ ZEND_ME(reflection_extension, __construct, arginfo_reflection_extension___construct, 0)
+ ZEND_ME(reflection_extension, __toString, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_extension, getName, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_extension, getVersion, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_extension, getFunctions, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_extension, getConstants, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_extension, getINIEntries, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_extension, getClasses, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_extension, getClassNames, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_extension, getDependencies, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_extension, info, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_extension, isPersistent, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_extension, isTemporary, arginfo_reflection__void, 0)
+ PHP_FE_END
+};
+
+ZEND_BEGIN_ARG_INFO(arginfo_reflection_zend_extension___construct, 0)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO()
+
+static const zend_function_entry reflection_zend_extension_functions[] = {
+ ZEND_ME(reflection, __clone, arginfo_reflection__void, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL)
+ ZEND_ME(reflection_zend_extension, export, arginfo_reflection_extension_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC)
+ ZEND_ME(reflection_zend_extension, __construct, arginfo_reflection_extension___construct, 0)
+ ZEND_ME(reflection_zend_extension, __toString, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_zend_extension, getName, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_zend_extension, getVersion, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_zend_extension, getAuthor, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_zend_extension, getURL, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_zend_extension, getCopyright, arginfo_reflection__void, 0)
+ PHP_FE_END
+};
+/* }}} */
+
+const zend_function_entry reflection_ext_functions[] = { /* {{{ */
+ PHP_FE_END
+}; /* }}} */
+
+static zend_object_handlers *zend_std_obj_handlers;
+
+/* {{{ _reflection_write_property */
+static void _reflection_write_property(zval *object, zval *member, zval *value, const zend_literal *key TSRMLS_DC)
+{
+ if ((Z_TYPE_P(member) == IS_STRING)
+ && zend_hash_exists(&Z_OBJCE_P(object)->properties_info, Z_STRVAL_P(member), Z_STRLEN_P(member)+1)
+ && ((Z_STRLEN_P(member) == sizeof("name") - 1 && !memcmp(Z_STRVAL_P(member), "name", sizeof("name")))
+ || (Z_STRLEN_P(member) == sizeof("class") - 1 && !memcmp(Z_STRVAL_P(member), "class", sizeof("class")))))
+ {
+ zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
+ "Cannot set read-only property %s::$%s", Z_OBJCE_P(object)->name, Z_STRVAL_P(member));
+ }
+ else
+ {
+ zend_std_obj_handlers->write_property(object, member, value, key TSRMLS_CC);
+ }
+}
+/* }}} */
+
+PHP_MINIT_FUNCTION(reflection) /* {{{ */
+{
+ zend_class_entry _reflection_entry;
+
+ zend_std_obj_handlers = zend_get_std_object_handlers();
+ memcpy(&reflection_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
+ reflection_object_handlers.clone_obj = NULL;
+ reflection_object_handlers.write_property = _reflection_write_property;
+
+ INIT_CLASS_ENTRY(_reflection_entry, "ReflectionException", reflection_exception_functions);
+ reflection_exception_ptr = zend_register_internal_class_ex(&_reflection_entry, zend_exception_get_default(TSRMLS_C), NULL TSRMLS_CC);
+
+ INIT_CLASS_ENTRY(_reflection_entry, "Reflection", reflection_functions);
+ reflection_ptr = zend_register_internal_class(&_reflection_entry TSRMLS_CC);
+
+ INIT_CLASS_ENTRY(_reflection_entry, "Reflector", reflector_functions);
+ reflector_ptr = zend_register_internal_interface(&_reflection_entry TSRMLS_CC);
+
+ INIT_CLASS_ENTRY(_reflection_entry, "ReflectionFunctionAbstract", reflection_function_abstract_functions);
+ _reflection_entry.create_object = reflection_objects_new;
+ reflection_function_abstract_ptr = zend_register_internal_class(&_reflection_entry TSRMLS_CC);
+ reflection_register_implement(reflection_function_abstract_ptr, reflector_ptr TSRMLS_CC);
+ zend_declare_property_string(reflection_function_abstract_ptr, "name", sizeof("name")-1, "", ZEND_ACC_ABSTRACT TSRMLS_CC);
+
+ INIT_CLASS_ENTRY(_reflection_entry, "ReflectionFunction", reflection_function_functions);
+ _reflection_entry.create_object = reflection_objects_new;
+ reflection_function_ptr = zend_register_internal_class_ex(&_reflection_entry, reflection_function_abstract_ptr, NULL TSRMLS_CC);
+ zend_declare_property_string(reflection_function_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC TSRMLS_CC);
+
+ REGISTER_REFLECTION_CLASS_CONST_LONG(function, "IS_DEPRECATED", ZEND_ACC_DEPRECATED);
+
+ INIT_CLASS_ENTRY(_reflection_entry, "ReflectionParameter", reflection_parameter_functions);
+ _reflection_entry.create_object = reflection_objects_new;
+ reflection_parameter_ptr = zend_register_internal_class(&_reflection_entry TSRMLS_CC);
+ reflection_register_implement(reflection_parameter_ptr, reflector_ptr TSRMLS_CC);
+ zend_declare_property_string(reflection_parameter_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC TSRMLS_CC);
+
+ INIT_CLASS_ENTRY(_reflection_entry, "ReflectionMethod", reflection_method_functions);
+ _reflection_entry.create_object = reflection_objects_new;
+ reflection_method_ptr = zend_register_internal_class_ex(&_reflection_entry, reflection_function_abstract_ptr, NULL TSRMLS_CC);
+ zend_declare_property_string(reflection_method_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC TSRMLS_CC);
+ zend_declare_property_string(reflection_method_ptr, "class", sizeof("class")-1, "", ZEND_ACC_PUBLIC TSRMLS_CC);
+
+ REGISTER_REFLECTION_CLASS_CONST_LONG(method, "IS_STATIC", ZEND_ACC_STATIC);
+ REGISTER_REFLECTION_CLASS_CONST_LONG(method, "IS_PUBLIC", ZEND_ACC_PUBLIC);
+ REGISTER_REFLECTION_CLASS_CONST_LONG(method, "IS_PROTECTED", ZEND_ACC_PROTECTED);
+ REGISTER_REFLECTION_CLASS_CONST_LONG(method, "IS_PRIVATE", ZEND_ACC_PRIVATE);
+ REGISTER_REFLECTION_CLASS_CONST_LONG(method, "IS_ABSTRACT", ZEND_ACC_ABSTRACT);
+ REGISTER_REFLECTION_CLASS_CONST_LONG(method, "IS_FINAL", ZEND_ACC_FINAL);
+
+ INIT_CLASS_ENTRY(_reflection_entry, "ReflectionClass", reflection_class_functions);
+ _reflection_entry.create_object = reflection_objects_new;
+ reflection_class_ptr = zend_register_internal_class(&_reflection_entry TSRMLS_CC);
+ reflection_register_implement(reflection_class_ptr, reflector_ptr TSRMLS_CC);
+ zend_declare_property_string(reflection_class_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC TSRMLS_CC);
+
+ REGISTER_REFLECTION_CLASS_CONST_LONG(class, "IS_IMPLICIT_ABSTRACT", ZEND_ACC_IMPLICIT_ABSTRACT_CLASS);
+ REGISTER_REFLECTION_CLASS_CONST_LONG(class, "IS_EXPLICIT_ABSTRACT", ZEND_ACC_EXPLICIT_ABSTRACT_CLASS);
+ REGISTER_REFLECTION_CLASS_CONST_LONG(class, "IS_FINAL", ZEND_ACC_FINAL_CLASS);
+
+ INIT_CLASS_ENTRY(_reflection_entry, "ReflectionObject", reflection_object_functions);
+ _reflection_entry.create_object = reflection_objects_new;
+ reflection_object_ptr = zend_register_internal_class_ex(&_reflection_entry, reflection_class_ptr, NULL TSRMLS_CC);
+
+ INIT_CLASS_ENTRY(_reflection_entry, "ReflectionProperty", reflection_property_functions);
+ _reflection_entry.create_object = reflection_objects_new;
+ reflection_property_ptr = zend_register_internal_class(&_reflection_entry TSRMLS_CC);
+ reflection_register_implement(reflection_property_ptr, reflector_ptr TSRMLS_CC);
+ zend_declare_property_string(reflection_property_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC TSRMLS_CC);
+ zend_declare_property_string(reflection_property_ptr, "class", sizeof("class")-1, "", ZEND_ACC_PUBLIC TSRMLS_CC);
+
+ REGISTER_REFLECTION_CLASS_CONST_LONG(property, "IS_STATIC", ZEND_ACC_STATIC);
+ REGISTER_REFLECTION_CLASS_CONST_LONG(property, "IS_PUBLIC", ZEND_ACC_PUBLIC);
+ REGISTER_REFLECTION_CLASS_CONST_LONG(property, "IS_PROTECTED", ZEND_ACC_PROTECTED);
+ REGISTER_REFLECTION_CLASS_CONST_LONG(property, "IS_PRIVATE", ZEND_ACC_PRIVATE);
+
+ INIT_CLASS_ENTRY(_reflection_entry, "ReflectionExtension", reflection_extension_functions);
+ _reflection_entry.create_object = reflection_objects_new;
+ reflection_extension_ptr = zend_register_internal_class(&_reflection_entry TSRMLS_CC);
+ reflection_register_implement(reflection_extension_ptr, reflector_ptr TSRMLS_CC);
+ zend_declare_property_string(reflection_extension_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC TSRMLS_CC);
+
+ INIT_CLASS_ENTRY(_reflection_entry, "ReflectionZendExtension", reflection_zend_extension_functions);
+ _reflection_entry.create_object = reflection_objects_new;
+ reflection_zend_extension_ptr = zend_register_internal_class(&_reflection_entry TSRMLS_CC);
+ reflection_register_implement(reflection_zend_extension_ptr, reflector_ptr TSRMLS_CC);
+ zend_declare_property_string(reflection_zend_extension_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC TSRMLS_CC);
+
+ return SUCCESS;
+} /* }}} */
+
+PHP_MINFO_FUNCTION(reflection) /* {{{ */
+{
+ php_info_print_table_start();
+ php_info_print_table_header(2, "Reflection", "enabled");
+
+ php_info_print_table_row(2, "Version", "$Id: 25ecbad68e5a4573ffee43ea24a0591ea179492a $");
+
+ php_info_print_table_end();
+} /* }}} */
+
+zend_module_entry reflection_module_entry = { /* {{{ */
+ STANDARD_MODULE_HEADER,
+ "Reflection",
+ reflection_ext_functions,
+ PHP_MINIT(reflection),
+ NULL,
+ NULL,
+ NULL,
+ PHP_MINFO(reflection),
+ "$Id: 25ecbad68e5a4573ffee43ea24a0591ea179492a $",
+ STANDARD_MODULE_PROPERTIES
+}; /* }}} */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * indent-tabs-mode: t
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ */
diff --git a/ext/reflection/php_reflection.h b/ext/reflection/php_reflection.h
new file mode 100644
index 0000000..48470f4
--- /dev/null
+++ b/ext/reflection/php_reflection.h
@@ -0,0 +1,57 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2013 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: George Schlossnagle <george@omniti.com> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifndef PHP_REFLECTION_H
+#define PHP_REFLECTION_H
+
+#include "php.h"
+
+extern zend_module_entry reflection_module_entry;
+#define phpext_reflection_ptr &reflection_module_entry
+
+BEGIN_EXTERN_C()
+
+/* Class entry pointers */
+extern PHPAPI zend_class_entry *reflector_ptr;
+extern PHPAPI zend_class_entry *reflection_exception_ptr;
+extern PHPAPI zend_class_entry *reflection_ptr;
+extern PHPAPI zend_class_entry *reflection_function_abstract_ptr;
+extern PHPAPI zend_class_entry *reflection_function_ptr;
+extern PHPAPI zend_class_entry *reflection_parameter_ptr;
+extern PHPAPI zend_class_entry *reflection_class_ptr;
+extern PHPAPI zend_class_entry *reflection_object_ptr;
+extern PHPAPI zend_class_entry *reflection_method_ptr;
+extern PHPAPI zend_class_entry *reflection_property_ptr;
+extern PHPAPI zend_class_entry *reflection_extension_ptr;
+extern PHPAPI zend_class_entry *reflection_zend_extension_ptr;
+
+PHPAPI void zend_reflection_class_factory(zend_class_entry *ce, zval *object TSRMLS_DC);
+
+END_EXTERN_C()
+
+#endif /* PHP_REFLECTION_H */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * indent-tabs-mode: t
+ * End:
+ */
diff --git a/ext/reflection/tests/001.phpt b/ext/reflection/tests/001.phpt
new file mode 100644
index 0000000..f68afc9
--- /dev/null
+++ b/ext/reflection/tests/001.phpt
@@ -0,0 +1,89 @@
+--TEST--
+Reflection inheritance
+--FILE--
+<?php
+
+class ReflectionClassEx extends ReflectionClass
+{
+ public $bla;
+
+ function getMethodNames()
+ {
+ $res = array();
+ foreach($this->getMethods() as $m)
+ {
+ $res[] = $m->class . '::' . $m->name;
+ }
+ return $res;
+ }
+}
+
+$r = new ReflectionClassEx('ReflectionClassEx');
+
+$exp = array (
+ 'UMLClass::__clone',
+ 'UMLClass::export',
+ 'UMLClass::__construct',
+ 'UMLClass::__toString',
+ 'UMLClass::getName',
+ 'UMLClass::isInternal',
+ 'UMLClass::isUserDefined',
+ 'UMLClass::isInstantiable',
+ 'UMLClass::getFileName',
+ 'UMLClass::getStartLine',
+ 'UMLClass::getEndLine',
+ 'UMLClass::getDocComment',
+ 'UMLClass::getConstructor',
+ 'UMLClass::getMethod',
+ 'UMLClass::getMethods',
+ 'UMLClass::getProperty',
+ 'UMLClass::getProperties',
+ 'UMLClass::getConstants',
+ 'UMLClass::getConstant',
+ 'UMLClass::getInterfaces',
+ 'UMLClass::isInterface',
+ 'UMLClass::isAbstract',
+ 'UMLClass::isFinal',
+ 'UMLClass::getModifiers',
+ 'UMLClass::isInstance',
+ 'UMLClass::newInstance',
+ 'UMLClass::getParentClass',
+ 'UMLClass::isSubclassOf',
+ 'UMLClass::getStaticProperties',
+ 'UMLClass::getDefaultProperties',
+ 'UMLClass::isIterateable',
+ 'UMLClass::implementsInterface',
+ 'UMLClass::getExtension',
+ 'UMLClass::getExtensionName');
+
+$miss = array();
+
+$res = $r->getMethodNames();
+
+foreach($exp as $m)
+{
+ if (!in_array($m, $exp))
+ {
+ $miss[] = $m;
+ }
+}
+
+var_dump($miss);
+
+$props = array_keys(get_class_vars('ReflectionClassEx'));
+sort($props);
+var_dump($props);
+var_dump($r->name);
+?>
+===DONE===
+--EXPECT--
+array(0) {
+}
+array(2) {
+ [0]=>
+ string(3) "bla"
+ [1]=>
+ string(4) "name"
+}
+string(17) "ReflectionClassEx"
+===DONE===
diff --git a/ext/reflection/tests/002.phpt b/ext/reflection/tests/002.phpt
new file mode 100644
index 0000000..833fed4
--- /dev/null
+++ b/ext/reflection/tests/002.phpt
@@ -0,0 +1,63 @@
+--TEST--
+Reflection properties are read only
+--FILE--
+<?php
+
+class ReflectionMethodEx extends ReflectionMethod
+{
+ public $foo = "xyz";
+
+ function __construct($c,$m)
+ {
+ echo __METHOD__ . "\n";
+ parent::__construct($c,$m);
+ }
+}
+
+$r = new ReflectionMethodEx('ReflectionMethodEx','getName');
+
+var_dump($r->class);
+var_dump($r->name);
+var_dump($r->foo);
+@var_dump($r->bar);
+
+try
+{
+ $r->class = 'bullshit';
+}
+catch(ReflectionException $e)
+{
+ echo $e->getMessage() . "\n";
+}
+try
+{
+$r->name = 'bullshit';
+}
+catch(ReflectionException $e)
+{
+ echo $e->getMessage() . "\n";
+}
+
+$r->foo = 'bar';
+$r->bar = 'baz';
+
+var_dump($r->class);
+var_dump($r->name);
+var_dump($r->foo);
+var_dump($r->bar);
+
+?>
+===DONE===
+--EXPECTF--
+ReflectionMethodEx::__construct
+%unicode|string%(26) "ReflectionFunctionAbstract"
+%unicode|string%(7) "getName"
+%unicode|string%(3) "xyz"
+NULL
+Cannot set read-only property ReflectionMethodEx::$class
+Cannot set read-only property ReflectionMethodEx::$name
+%unicode|string%(26) "ReflectionFunctionAbstract"
+%unicode|string%(7) "getName"
+%unicode|string%(3) "bar"
+%unicode|string%(3) "baz"
+===DONE===
diff --git a/ext/reflection/tests/003.phpt b/ext/reflection/tests/003.phpt
new file mode 100644
index 0000000..80bf0a6
--- /dev/null
+++ b/ext/reflection/tests/003.phpt
@@ -0,0 +1,31 @@
+--TEST--
+ReflectionMethod::invoke() with base class method
+--FILE--
+<?php
+
+class Foo
+{
+ function Test()
+ {
+ echo __METHOD__ . "\n";
+ }
+}
+
+class Bar extends Foo
+{
+ function Test()
+ {
+ echo __METHOD__ . "\n";
+ }
+}
+
+$o = new Bar;
+$r = new ReflectionMethod('Foo','Test');
+
+$r->invoke($o);
+
+?>
+===DONE===
+--EXPECT--
+Foo::Test
+===DONE===
diff --git a/ext/reflection/tests/004.phpt b/ext/reflection/tests/004.phpt
new file mode 100644
index 0000000..2c81c50
--- /dev/null
+++ b/ext/reflection/tests/004.phpt
@@ -0,0 +1,42 @@
+--TEST--
+ReflectionMethod::invoke() with non object or null value
+--FILE--
+<?php
+
+class a {
+ function a(){
+ }
+}
+class b {
+}
+
+$b = new b();
+
+$a=new ReflectionClass("a");
+$m=$a->getMethod("a");
+
+try {
+ $m->invoke(null);
+} catch (ReflectionException $E) {
+ echo $E->getMessage()."\n";
+}
+
+
+try {
+ $m->invoke($b);
+} catch (ReflectionException $E) {
+ echo $E->getMessage()."\n";
+}
+
+$b = new a();
+try {
+ $m->invoke($b);
+} catch (ReflectionException $E) {
+ echo $E->getMessage()."\n";
+}
+
+echo "===DONE===\n";?>
+--EXPECT--
+Non-object passed to Invoke()
+Given object is not an instance of the class this method was declared in
+===DONE===
diff --git a/ext/reflection/tests/005.phpt b/ext/reflection/tests/005.phpt
new file mode 100644
index 0000000..f337e44
--- /dev/null
+++ b/ext/reflection/tests/005.phpt
@@ -0,0 +1,54 @@
+--TEST--
+ReflectionMethod::getDocComment() uses wrong comment block
+--FILE--
+<?php
+
+function strip_doc_comment($c)
+{
+ if (!strlen($c) || $c === false) return $c;
+ return trim(substr($c, 3, -2));
+}
+
+/** Comment for class A */
+class A
+{
+ /** Method A::bla()
+ */
+ function bla()
+ {
+ }
+
+ function foo() {
+ /**
+ * This is a valid comment inside a method
+ */
+ }
+
+ function bar() {
+ // I don't have a doc comment....
+ }
+
+ /**
+ * Comment for A::baz()
+ */
+ function baz() {
+ }
+}
+
+$r = new ReflectionClass('A');
+var_dump(strip_doc_comment($r->getDocComment()));
+
+foreach($r->getMethods() as $m)
+{
+ var_dump(strip_doc_comment($m->getDocComment()));
+}
+
+?>
+===DONE===
+--EXPECT--
+string(19) "Comment for class A"
+string(15) "Method A::bla()"
+bool(false)
+bool(false)
+string(22) "* Comment for A::baz()"
+===DONE===
diff --git a/ext/reflection/tests/006.phpt b/ext/reflection/tests/006.phpt
new file mode 100644
index 0000000..89c4387
--- /dev/null
+++ b/ext/reflection/tests/006.phpt
@@ -0,0 +1,103 @@
+--TEST--
+ReflectionClass::[gs]etStaticPropertyValue
+--FILE--
+<?php
+
+/* ReflectionClass cannot touch protected or private static properties */
+
+/* ReflectionClass cannot create or delete static properties */
+
+Class Test
+{
+ static public $pub = 'pub';
+ static protected $pro = 'pro';
+ static private $pri = 'pri';
+
+ static function testing()
+ {
+ $ref = new ReflectionClass('Test');
+
+ foreach(array('pub', 'pro', 'pri') as $name)
+ {
+ try
+ {
+ var_dump($ref->getStaticPropertyValue($name));
+ var_dump($ref->getStaticPropertyValue($name));
+ $ref->setStaticPropertyValue($name, 'updated');
+ var_dump($ref->getStaticPropertyValue($name));
+ }
+ catch(Exception $e)
+ {
+ echo "EXCEPTION\n";
+ }
+ }
+ }
+}
+
+Class TestDerived extends Test
+{
+// static public $pub = 'pub';
+// static protected $pro = 'pro';
+ static private $pri = 'pri';
+
+ static function testing()
+ {
+ $ref = new ReflectionClass('Test');
+
+ foreach(array('pub', 'pro', 'pri') as $name)
+ {
+ try
+ {
+ var_dump($ref->getStaticPropertyValue($name));
+ var_dump($ref->getStaticPropertyValue($name));
+ $ref->setStaticPropertyValue($name, 'updated');
+ var_dump($ref->getStaticPropertyValue($name));
+ }
+ catch(Exception $e)
+ {
+ echo "EXCEPTION\n";
+ }
+ }
+ }
+}
+
+$ref = new ReflectionClass('Test');
+
+foreach(array('pub', 'pro', 'pri') as $name)
+{
+ try
+ {
+ var_dump($ref->getStaticPropertyValue($name));
+ var_dump($ref->getStaticPropertyValue($name));
+ $ref->setStaticPropertyValue($name, 'updated');
+ var_dump($ref->getStaticPropertyValue($name));
+ }
+ catch(Exception $e)
+ {
+ echo "EXCEPTION\n";
+ }
+}
+
+Test::testing();
+TestDerived::testing();
+
+?>
+===DONE===
+<?php exit(0); ?>
+--EXPECT--
+string(3) "pub"
+string(3) "pub"
+string(7) "updated"
+EXCEPTION
+EXCEPTION
+string(7) "updated"
+string(7) "updated"
+string(7) "updated"
+EXCEPTION
+EXCEPTION
+string(7) "updated"
+string(7) "updated"
+string(7) "updated"
+EXCEPTION
+EXCEPTION
+===DONE===
diff --git a/ext/reflection/tests/007.phpt b/ext/reflection/tests/007.phpt
new file mode 100644
index 0000000..004158c
--- /dev/null
+++ b/ext/reflection/tests/007.phpt
@@ -0,0 +1,160 @@
+--TEST--
+ReflectionClass::newInstance[Args]
+--FILE--
+<?php
+
+function test($class)
+{
+ echo "====>$class\n";
+ try
+ {
+ $ref = new ReflectionClass($class);
+ }
+ catch (ReflectionException $e)
+ {
+ var_dump($e->getMessage());
+ return; // only here
+ }
+
+ echo "====>newInstance()\n";
+ try
+ {
+ var_dump($ref->newInstance());
+ }
+ catch (ReflectionException $e)
+ {
+ var_dump($e->getMessage());
+ }
+
+ echo "====>newInstance(25)\n";
+ try
+ {
+ var_dump($ref->newInstance(25));
+ }
+ catch (ReflectionException $e)
+ {
+ var_dump($e->getMessage());
+ }
+
+ echo "====>newInstance(25, 42)\n";
+ try
+ {
+ var_dump($ref->newInstance(25, 42));
+ }
+ catch (ReflectionException $e)
+ {
+ var_dump($e->getMessage());
+ }
+
+ echo "\n";
+}
+
+function __autoload($class)
+{
+ echo __FUNCTION__ . "($class)\n";
+}
+
+test('Class_does_not_exist');
+
+Class NoCtor
+{
+}
+
+test('NoCtor');
+
+Class WithCtor
+{
+ function __construct()
+ {
+ echo __METHOD__ . "()\n";
+ var_dump(func_get_args());
+ }
+}
+
+test('WithCtor');
+
+Class WithCtorWithArgs
+{
+ function __construct($arg)
+ {
+ echo __METHOD__ . "($arg)\n";
+ var_dump(func_get_args());
+ }
+}
+
+test('WithCtorWithArgs');
+
+?>
+===DONE===
+<?php exit(0); ?>
+--EXPECTF--
+
+====>Class_does_not_exist
+__autoload(Class_does_not_exist)
+string(41) "Class Class_does_not_exist does not exist"
+====>NoCtor
+====>newInstance()
+object(NoCtor)#%d (0) {
+}
+====>newInstance(25)
+string(86) "Class NoCtor does not have a constructor, so you cannot pass any constructor arguments"
+====>newInstance(25, 42)
+string(86) "Class NoCtor does not have a constructor, so you cannot pass any constructor arguments"
+
+====>WithCtor
+====>newInstance()
+WithCtor::__construct()
+array(0) {
+}
+object(WithCtor)#%d (0) {
+}
+====>newInstance(25)
+WithCtor::__construct()
+array(1) {
+ [0]=>
+ int(25)
+}
+object(WithCtor)#%d (0) {
+}
+====>newInstance(25, 42)
+WithCtor::__construct()
+array(2) {
+ [0]=>
+ int(25)
+ [1]=>
+ int(42)
+}
+object(WithCtor)#%d (0) {
+}
+
+====>WithCtorWithArgs
+====>newInstance()
+
+Warning: Missing argument 1 for WithCtorWithArgs::__construct() in %s007.php on line %d
+
+Notice: Undefined variable: arg in %s007.php on line %d
+WithCtorWithArgs::__construct()
+array(0) {
+}
+object(WithCtorWithArgs)#%d (0) {
+}
+====>newInstance(25)
+WithCtorWithArgs::__construct(25)
+array(1) {
+ [0]=>
+ int(25)
+}
+object(WithCtorWithArgs)#%d (0) {
+}
+====>newInstance(25, 42)
+WithCtorWithArgs::__construct(25)
+array(2) {
+ [0]=>
+ int(25)
+ [1]=>
+ int(42)
+}
+object(WithCtorWithArgs)#%d (0) {
+}
+
+===DONE===
diff --git a/ext/reflection/tests/008.phpt b/ext/reflection/tests/008.phpt
new file mode 100644
index 0000000..2abdcdb
--- /dev/null
+++ b/ext/reflection/tests/008.phpt
@@ -0,0 +1,39 @@
+--TEST--
+ReflectionMethod::__construct() tests
+--FILE--
+<?php
+
+$a = array("", 1, "::", "a::", "::b", "a::b");
+
+foreach ($a as $val) {
+ try {
+ new ReflectionMethod($val);
+ } catch (Exception $e) {
+ var_dump($e->getMessage());
+ }
+}
+
+$a = array("", 1, "");
+$b = array("", "", 1);
+
+foreach ($a as $key=>$val) {
+ try {
+ new ReflectionMethod($val, $b[$key]);
+ } catch (Exception $e) {
+ var_dump($e->getMessage());
+ }
+}
+
+echo "Done\n";
+?>
+--EXPECTF--
+string(20) "Invalid method name "
+string(21) "Invalid method name 1"
+string(21) "Class does not exist"
+string(22) "Class a does not exist"
+string(21) "Class does not exist"
+string(22) "Class a does not exist"
+string(21) "Class does not exist"
+string(66) "The parameter class is expected to be either a string or an object"
+string(21) "Class does not exist"
+Done
diff --git a/ext/reflection/tests/009.phpt b/ext/reflection/tests/009.phpt
new file mode 100644
index 0000000..e96b21e
--- /dev/null
+++ b/ext/reflection/tests/009.phpt
@@ -0,0 +1,112 @@
+--TEST--
+ReflectionFunction basic tests
+--FILE--
+<?php
+
+/**
+hoho
+*/
+function test ($a, $b = 1, $c = "") {
+ static $var = 1;
+}
+
+$func = new ReflectionFunction("test");
+
+var_dump($func->export("test"));
+echo "--getName--\n";
+var_dump($func->getName());
+echo "--isInternal--\n";
+var_dump($func->isInternal());
+echo "--isUserDefined--\n";
+var_dump($func->isUserDefined());
+echo "--getFilename--\n";
+var_dump($func->getFilename());
+echo "--getStartline--\n";
+var_dump($func->getStartline());
+echo "--getEndline--\n";
+var_dump($func->getEndline());
+echo "--getDocComment--\n";
+var_dump($func->getDocComment());
+echo "--getStaticVariables--\n";
+var_dump($func->getStaticVariables());
+echo "--invoke--\n";
+var_dump($func->invoke(array(1,2,3)));
+echo "--invokeArgs--\n";
+var_dump($func->invokeArgs(array(1,2,3)));
+echo "--returnsReference--\n";
+var_dump($func->returnsReference());
+echo "--getParameters--\n";
+var_dump($func->getParameters());
+echo "--getNumberOfParameters--\n";
+var_dump($func->getNumberOfParameters());
+echo "--getNumberOfRequiredParameters--\n";
+var_dump($func->getNumberOfRequiredParameters());
+
+echo "Done\n";
+
+?>
+--EXPECTF--
+/**
+hoho
+*/
+Function [ <user> function test ] {
+ @@ %s009.php 6 - 8
+
+ - Parameters [3] {
+ Parameter #0 [ <required> $a ]
+ Parameter #1 [ <optional> $b = 1 ]
+ Parameter #2 [ <optional> $c = '' ]
+ }
+}
+
+NULL
+--getName--
+string(4) "test"
+--isInternal--
+bool(false)
+--isUserDefined--
+bool(true)
+--getFilename--
+string(%d) "%s009.php"
+--getStartline--
+int(6)
+--getEndline--
+int(8)
+--getDocComment--
+string(11) "/**
+hoho
+*/"
+--getStaticVariables--
+array(1) {
+ ["var"]=>
+ int(1)
+}
+--invoke--
+NULL
+--invokeArgs--
+NULL
+--returnsReference--
+bool(false)
+--getParameters--
+array(3) {
+ [0]=>
+ &object(ReflectionParameter)#2 (1) {
+ ["name"]=>
+ string(1) "a"
+ }
+ [1]=>
+ &object(ReflectionParameter)#3 (1) {
+ ["name"]=>
+ string(1) "b"
+ }
+ [2]=>
+ &object(ReflectionParameter)#4 (1) {
+ ["name"]=>
+ string(1) "c"
+ }
+}
+--getNumberOfParameters--
+int(3)
+--getNumberOfRequiredParameters--
+int(1)
+Done
diff --git a/ext/reflection/tests/010.phpt b/ext/reflection/tests/010.phpt
new file mode 100644
index 0000000..8f92fee
--- /dev/null
+++ b/ext/reflection/tests/010.phpt
@@ -0,0 +1,21 @@
+--TEST--
+ReflectionMethod::__toString() tests (overriden method)
+--SKIPIF--
+<?php extension_loaded('reflection') or die('skip'); ?>
+--FILE--
+<?php
+class Foo {
+ function func() {
+ }
+}
+class Bar extends Foo {
+ function func() {
+ }
+}
+$m = new ReflectionMethod("Bar::func");
+echo $m;
+?>
+--EXPECTF--
+Method [ <user, overwrites Foo, prototype Foo> public method func ] {
+ @@ %s010.php 7 - 8
+}
diff --git a/ext/reflection/tests/011.phpt b/ext/reflection/tests/011.phpt
new file mode 100644
index 0000000..b39be37
--- /dev/null
+++ b/ext/reflection/tests/011.phpt
@@ -0,0 +1,12 @@
+--TEST--
+ReflectionExtension::getClasses()
+--SKIPIF--
+<?php extension_loaded('reflection') or die('skip'); ?>
+--FILE--
+<?php
+$ext = new ReflectionExtension("reflection");
+$classes = $ext->getClasses();
+echo $classes["ReflectionException"]->getName();
+?>
+--EXPECT--
+ReflectionException
diff --git a/ext/reflection/tests/012.phpt b/ext/reflection/tests/012.phpt
new file mode 100644
index 0000000..b8a2694
--- /dev/null
+++ b/ext/reflection/tests/012.phpt
@@ -0,0 +1,16 @@
+--TEST--
+ReflectionClass::getDefaultProperties()
+--SKIPIF--
+<?php extension_loaded('reflection') or die('skip'); ?>
+--FILE--
+<?php
+class Foo {
+ public $test = "ok";
+}
+$class = new ReflectionClass("Foo");
+$props = $class->getDefaultProperties();
+echo $props["test"];
+?>
+--EXPECT--
+ok
+
diff --git a/ext/reflection/tests/013.phpt b/ext/reflection/tests/013.phpt
new file mode 100644
index 0000000..9ecfa8b
--- /dev/null
+++ b/ext/reflection/tests/013.phpt
@@ -0,0 +1,13 @@
+--TEST--
+ReflectionExtension::getFunctions()
+--SKIPIF--
+<?php extension_loaded('reflection') or die('skip'); ?>
+--FILE--
+<?php
+$ext = new ReflectionExtension("standard");
+$funcs = $ext->getFunctions();
+echo $funcs["sleep"]->getName();
+?>
+--EXPECT--
+sleep
+
diff --git a/ext/reflection/tests/014.phpt b/ext/reflection/tests/014.phpt
new file mode 100644
index 0000000..8b5955f
--- /dev/null
+++ b/ext/reflection/tests/014.phpt
@@ -0,0 +1,13 @@
+--TEST--
+ReflectionExtension::getConstants()
+--SKIPIF--
+<?php extension_loaded('reflection') or die('skip'); ?>
+--FILE--
+<?php
+$ext = new ReflectionExtension("standard");
+$consts = $ext->getConstants();
+var_dump($consts["CONNECTION_NORMAL"]);
+?>
+--EXPECT--
+int(0)
+
diff --git a/ext/reflection/tests/015.phpt b/ext/reflection/tests/015.phpt
new file mode 100644
index 0000000..b172362
--- /dev/null
+++ b/ext/reflection/tests/015.phpt
@@ -0,0 +1,15 @@
+--TEST--
+ReflectionExtension::getINIEntries()
+--SKIPIF--
+<?php extension_loaded('reflection') or die('skip'); ?>
+--INI--
+user_agent=php
+--FILE--
+<?php
+$ext = new ReflectionExtension("standard");
+$inis = $ext->getINIEntries();
+var_dump($inis["user_agent"]);
+?>
+--EXPECT--
+string(3) "php"
+
diff --git a/ext/reflection/tests/016.phpt b/ext/reflection/tests/016.phpt
new file mode 100644
index 0000000..d289165
--- /dev/null
+++ b/ext/reflection/tests/016.phpt
@@ -0,0 +1,20 @@
+--TEST--
+ReflectionExtension::getDependencies()
+--SKIPIF--
+<?php
+extension_loaded('reflection') or die('skip');
+if (!extension_loaded("xml")) {
+ die('skip xml extension not available');
+}
+?>
+--FILE--
+<?php
+$ext = new ReflectionExtension("xml");
+$deps = $ext->getDependencies();
+var_dump($deps);
+?>
+--EXPECT--
+array(1) {
+ ["libxml"]=>
+ string(8) "Required"
+}
diff --git a/ext/reflection/tests/017.phpt b/ext/reflection/tests/017.phpt
new file mode 100644
index 0000000..d40c4d8
--- /dev/null
+++ b/ext/reflection/tests/017.phpt
@@ -0,0 +1,33 @@
+--TEST--
+ReflectionClass::__toString() (constants)
+--SKIPIF--
+<?php extension_loaded('reflection') or die('skip'); ?>
+--FILE--
+<?php
+class Foo {
+ const test = "ok";
+}
+$class = new ReflectionClass("Foo");
+echo $class;
+?>
+--EXPECTF--
+Class [ <user> class Foo ] {
+ @@ %s017.php 2-4
+
+ - Constants [1] {
+ Constant [ string test ] { ok }
+ }
+
+ - Static properties [0] {
+ }
+
+ - Static methods [0] {
+ }
+
+ - Properties [0] {
+ }
+
+ - Methods [0] {
+ }
+}
+
diff --git a/ext/reflection/tests/018.phpt b/ext/reflection/tests/018.phpt
new file mode 100644
index 0000000..fbda5d6
--- /dev/null
+++ b/ext/reflection/tests/018.phpt
@@ -0,0 +1,15 @@
+--TEST--
+Reflection::getModifierNames
+--SKIPIF--
+<?php extension_loaded('reflection') or die('skip'); ?>
+--FILE--
+<?php
+var_dump(Reflection::getModifierNames(ReflectionMethod::IS_FINAL | ReflectionMethod::IS_PROTECTED));
+?>
+--EXPECT--
+array(2) {
+ [0]=>
+ string(5) "final"
+ [1]=>
+ string(9) "protected"
+}
diff --git a/ext/reflection/tests/019.phpt b/ext/reflection/tests/019.phpt
new file mode 100644
index 0000000..b6ac20c
--- /dev/null
+++ b/ext/reflection/tests/019.phpt
@@ -0,0 +1,11 @@
+--TEST--
+ReflectionFunction::getExtensionName
+--SKIPIF--
+<?php extension_loaded('reflection') or die('skip'); ?>
+--FILE--
+<?php
+$f = new ReflectionFunction("sleep");
+var_dump($f->getExtensionName());
+?>
+--EXPECT--
+string(8) "standard"
diff --git a/ext/reflection/tests/020.phpt b/ext/reflection/tests/020.phpt
new file mode 100644
index 0000000..c5b0ae5
--- /dev/null
+++ b/ext/reflection/tests/020.phpt
@@ -0,0 +1,27 @@
+--TEST--
+ReflectionObject::hasProperty
+--SKIPIF--
+<?php extension_loaded('reflection') or die('skip'); ?>
+--FILE--
+<?php
+class Foo {
+ public $p1;
+ protected $p2;
+ private $p3;
+
+ function __isset($name) {
+ var_dump($name);
+ return false;
+ }
+}
+$obj = new ReflectionObject(new Foo());
+var_dump($obj->hasProperty("p1"));
+var_dump($obj->hasProperty("p2"));
+var_dump($obj->hasProperty("p3"));
+var_dump($obj->hasProperty("p4"));
+?>
+--EXPECT--
+bool(true)
+bool(true)
+bool(true)
+bool(false)
diff --git a/ext/reflection/tests/021.phpt b/ext/reflection/tests/021.phpt
new file mode 100644
index 0000000..30dbb5a
--- /dev/null
+++ b/ext/reflection/tests/021.phpt
@@ -0,0 +1,16 @@
+--TEST--
+ReflectionClass::hasConstant
+--SKIPIF--
+<?php extension_loaded('reflection') or die('skip'); ?>
+--FILE--
+<?php
+class Foo {
+ const c1 = 1;
+}
+$class = new ReflectionClass("Foo");
+var_dump($class->hasConstant("c1"));
+var_dump($class->hasConstant("c2"));
+?>
+--EXPECT--
+bool(true)
+bool(false)
diff --git a/ext/reflection/tests/022.phpt b/ext/reflection/tests/022.phpt
new file mode 100644
index 0000000..50dbd6e
--- /dev/null
+++ b/ext/reflection/tests/022.phpt
@@ -0,0 +1,16 @@
+--TEST--
+ReflectionClass::getConstant
+--SKIPIF--
+<?php extension_loaded('reflection') or die('skip'); ?>
+--FILE--
+<?php
+class Foo {
+ const c1 = 1;
+}
+$class = new ReflectionClass("Foo");
+var_dump($class->getConstant("c1"));
+var_dump($class->getConstant("c2"));
+?>
+--EXPECT--
+int(1)
+bool(false)
diff --git a/ext/reflection/tests/023.phpt b/ext/reflection/tests/023.phpt
new file mode 100644
index 0000000..ab11365
--- /dev/null
+++ b/ext/reflection/tests/023.phpt
@@ -0,0 +1,32 @@
+--TEST--
+ReflectionClass::getDefaultProperties (filtering parent privates)
+--SKIPIF--
+<?php extension_loaded('reflection') or die('skip'); ?>
+--FILE--
+<?php
+class C1 {
+ private $p1 = 1;
+ protected $p2 = 2;
+ public $p3 = 3;
+}
+class C2 extends C1 {
+ private $p4 = 4;
+ protected $p5 = 5;
+ public $p6 = 6;
+}
+$class = new ReflectionClass("C2");
+var_dump($class->getDefaultProperties());
+?>
+--EXPECT--
+array(5) {
+ ["p4"]=>
+ int(4)
+ ["p5"]=>
+ int(5)
+ ["p6"]=>
+ int(6)
+ ["p2"]=>
+ int(2)
+ ["p3"]=>
+ int(3)
+}
diff --git a/ext/reflection/tests/024.phpt b/ext/reflection/tests/024.phpt
new file mode 100644
index 0000000..a1c2c81
--- /dev/null
+++ b/ext/reflection/tests/024.phpt
@@ -0,0 +1,45 @@
+--TEST--
+ReflectionObject::__toString (filtering privates/protected dynamic properties)
+--SKIPIF--
+<?php extension_loaded('reflection') or die('skip'); ?>
+--FILE--
+<?php
+class C1 {
+ private $p1 = 1;
+ protected $p2 = 2;
+ public $p3 = 3;
+}
+
+$x = new C1();
+$x->z = 4;
+$x->p3 = 5;
+
+$obj = new ReflectionObject($x);
+echo $obj;
+?>
+--EXPECTF--
+Object of class [ <user> class C1 ] {
+ @@ %s024.php 2-6
+
+ - Constants [0] {
+ }
+
+ - Static properties [0] {
+ }
+
+ - Static methods [0] {
+ }
+
+ - Properties [3] {
+ Property [ <default> private $p1 ]
+ Property [ <default> protected $p2 ]
+ Property [ <default> public $p3 ]
+ }
+
+ - Dynamic properties [1] {
+ Property [ <dynamic> public $z ]
+ }
+
+ - Methods [0] {
+ }
+}
diff --git a/ext/reflection/tests/025.phpt b/ext/reflection/tests/025.phpt
new file mode 100644
index 0000000..a5f604f
--- /dev/null
+++ b/ext/reflection/tests/025.phpt
@@ -0,0 +1,114 @@
+--TEST--
+ReflectionFunction basic tests
+--SKIPIF--
+<?php extension_loaded('reflection') or die('skip'); ?>
+--FILE--
+<?php
+
+/**
+hoho
+*/
+function test ($a, $b = 1, $c = "") {
+ static $var = 1;
+}
+
+$func = new ReflectionFunction("test");
+
+var_dump($func->export("test"));
+echo "--getName--\n";
+var_dump($func->getName());
+echo "--isInternal--\n";
+var_dump($func->isInternal());
+echo "--isUserDefined--\n";
+var_dump($func->isUserDefined());
+echo "--getFilename--\n";
+var_dump($func->getFilename());
+echo "--getStartline--\n";
+var_dump($func->getStartline());
+echo "--getEndline--\n";
+var_dump($func->getEndline());
+echo "--getDocComment--\n";
+var_dump($func->getDocComment());
+echo "--getStaticVariables--\n";
+var_dump($func->getStaticVariables());
+echo "--invoke--\n";
+var_dump($func->invoke(array(1,2,3)));
+echo "--invokeArgs--\n";
+var_dump($func->invokeArgs(array(1,2,3)));
+echo "--returnsReference--\n";
+var_dump($func->returnsReference());
+echo "--getParameters--\n";
+var_dump($func->getParameters());
+echo "--getNumberOfParameters--\n";
+var_dump($func->getNumberOfParameters());
+echo "--getNumberOfRequiredParameters--\n";
+var_dump($func->getNumberOfRequiredParameters());
+
+echo "Done\n";
+
+?>
+--EXPECTF--
+/**
+hoho
+*/
+Function [ <user> function test ] {
+ @@ %s 6 - 8
+
+ - Parameters [3] {
+ Parameter #0 [ <required> $a ]
+ Parameter #1 [ <optional> $b = 1 ]
+ Parameter #2 [ <optional> $c = '' ]
+ }
+}
+
+NULL
+--getName--
+string(4) "test"
+--isInternal--
+bool(false)
+--isUserDefined--
+bool(true)
+--getFilename--
+string(%d) "%s025.php"
+--getStartline--
+int(6)
+--getEndline--
+int(8)
+--getDocComment--
+string(11) "/**
+hoho
+*/"
+--getStaticVariables--
+array(1) {
+ ["var"]=>
+ int(1)
+}
+--invoke--
+NULL
+--invokeArgs--
+NULL
+--returnsReference--
+bool(false)
+--getParameters--
+array(3) {
+ [0]=>
+ &object(ReflectionParameter)#2 (1) {
+ ["name"]=>
+ string(1) "a"
+ }
+ [1]=>
+ &object(ReflectionParameter)#3 (1) {
+ ["name"]=>
+ string(1) "b"
+ }
+ [2]=>
+ &object(ReflectionParameter)#4 (1) {
+ ["name"]=>
+ string(1) "c"
+ }
+}
+--getNumberOfParameters--
+int(3)
+--getNumberOfRequiredParameters--
+int(1)
+Done
diff --git a/ext/reflection/tests/026.phpt b/ext/reflection/tests/026.phpt
new file mode 100644
index 0000000..dc4c4a3
--- /dev/null
+++ b/ext/reflection/tests/026.phpt
@@ -0,0 +1,34 @@
+--TEST--
+ReflectionExtension::info()
+--FILE--
+<?php
+$r = new ReflectionExtension("reflection");
+$r->info();
+
+date_default_timezone_set('Europe/Berlin');
+$r = new ReflectionExtension("date");
+$r->info();
+
+echo "\nDone!\n";
+?>
+--EXPECTF--
+Reflection
+
+Reflection => enabled
+Version => %s
+
+date
+
+date/time support => enabled
+"Olson" Timezone Database Version => %s
+Timezone Database => %s
+Default timezone => %s
+
+Directive => %s => %s
+date.timezone => %s => %s
+date.default_latitude => %s => %s
+date.default_longitude => %s => %s
+date.sunset_zenith => %s => %s
+date.sunrise_zenith => %s => %s
+
+Done!
diff --git a/ext/reflection/tests/ReflectionClass_CannotClone_basic.phpt b/ext/reflection/tests/ReflectionClass_CannotClone_basic.phpt
new file mode 100644
index 0000000..6b440cf
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_CannotClone_basic.phpt
@@ -0,0 +1,15 @@
+--TEST--
+Reflection class can not be cloned
+--CREDITS--
+Stefan Koopmanschap <stefan@phpgg.nl>
+TestFest PHP|Tek
+--SKIPIF--
+<?php
+if (!extension_loaded('reflection)) print 'skip';
+?>
+--FILE--
+<?php
+$rc = new ReflectionClass("stdClass");
+$rc2 = clone($rc);
+--EXPECTF--
+Fatal error: Trying to clone an uncloneable object of class ReflectionClass in %s on line %d
diff --git a/ext/reflection/tests/ReflectionClass_FileInfo_basic.phpt b/ext/reflection/tests/ReflectionClass_FileInfo_basic.phpt
new file mode 100644
index 0000000..da276e6
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_FileInfo_basic.phpt
@@ -0,0 +1,33 @@
+--TEST--
+ReflectionClass::getFileName(), ReflectionClass::getStartLine(), ReflectionClass::getEndLine()
+--FILE--
+<?php
+//New instance of class C - defined below
+$rc = new ReflectionClass("C");
+
+//Get the file name of the PHP script in which C is defined
+var_dump($rc->getFileName());
+
+//Get the line number at the start of the definition of class C
+var_dump($rc->getStartLine());
+
+//Get the line number at the end of the definition of class C
+var_dump($rc->getEndLine());
+
+//Same tests as above but stdclass is internal - so all results should be false.
+$rc = new ReflectionClass("stdClass");
+var_dump($rc->getFileName());
+var_dump($rc->getStartLine());
+var_dump($rc->getEndLine());
+
+Class C {
+
+}
+?>
+--EXPECTF--
+string(%d) "%sReflectionClass_FileInfo_basic.php"
+int(20)
+int(22)
+bool(false)
+bool(false)
+bool(false)
diff --git a/ext/reflection/tests/ReflectionClass_FileInfo_error.phpt b/ext/reflection/tests/ReflectionClass_FileInfo_error.phpt
new file mode 100644
index 0000000..b42be13
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_FileInfo_error.phpt
@@ -0,0 +1,37 @@
+--TEST--
+ReflectionClass::getFileName(), ReflectionClass::getStartLine(), ReflectionClass::getEndLine() - bad params
+--FILE--
+<?php
+Class C { }
+
+$rc = new ReflectionClass("C");
+$methods = array("getFileName", "getStartLine", "getEndLine");
+
+foreach ($methods as $method) {
+ var_dump($rc->$method());
+ var_dump($rc->$method(null));
+ var_dump($rc->$method('X', 0));
+}
+?>
+--EXPECTF--
+string(%d) "%s"
+
+Warning: ReflectionClass::getFileName() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionClass::getFileName() expects exactly 0 parameters, 2 given in %s on line %d
+NULL
+int(2)
+
+Warning: ReflectionClass::getStartLine() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionClass::getStartLine() expects exactly 0 parameters, 2 given in %s on line %d
+NULL
+int(2)
+
+Warning: ReflectionClass::getEndLine() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionClass::getEndLine() expects exactly 0 parameters, 2 given in %s on line %d
+NULL
diff --git a/ext/reflection/tests/ReflectionClass_constructor_001.phpt b/ext/reflection/tests/ReflectionClass_constructor_001.phpt
new file mode 100644
index 0000000..1a70fe1
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_constructor_001.phpt
@@ -0,0 +1,33 @@
+--TEST--
+ReflectionClass::__constructor()
+--FILE--
+<?php
+$r1 = new ReflectionClass("stdClass");
+
+$myInstance = new stdClass;
+$r2 = new ReflectionClass($myInstance);
+
+class TrickClass {
+ function __toString() {
+ //Return the name of another class
+ return "Exception";
+ }
+}
+$myTrickClass = new TrickClass;
+$r3 = new ReflectionClass($myTrickClass);
+
+var_dump($r1, $r2, $r3);
+?>
+--EXPECTF--
+object(ReflectionClass)#%d (1) {
+ ["name"]=>
+ string(8) "stdClass"
+}
+object(ReflectionClass)#%d (1) {
+ ["name"]=>
+ string(8) "stdClass"
+}
+object(ReflectionClass)#%d (1) {
+ ["name"]=>
+ string(10) "TrickClass"
+}
diff --git a/ext/reflection/tests/ReflectionClass_constructor_002.phpt b/ext/reflection/tests/ReflectionClass_constructor_002.phpt
new file mode 100644
index 0000000..3685c63
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_constructor_002.phpt
@@ -0,0 +1,67 @@
+--TEST--
+ReflectionClass::__constructor() - bad arguments
+--FILE--
+<?php
+try {
+ var_dump(new ReflectionClass());
+} catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+
+try {
+ var_dump(new ReflectionClass(null));
+} catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+
+try {
+ var_dump(new ReflectionClass(true));
+} catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+
+try {
+ var_dump(new ReflectionClass(1));
+} catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+
+try {
+ var_dump(new ReflectionClass(array(1,2,3)));
+} catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+
+try {
+ var_dump(new ReflectionClass("stdClass", 1));
+} catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+
+try {
+ var_dump(new ReflectionClass("X"));
+} catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+
+?>
+--EXPECTF--
+
+Warning: ReflectionClass::__construct() expects exactly 1 parameter, 0 given in %s on line 3
+object(ReflectionClass)#%d (1) {
+ ["name"]=>
+ string(0) ""
+}
+Class does not exist
+Class 1 does not exist
+Class 1 does not exist
+
+Notice: Array to string conversion in %s on line 27
+Class Array does not exist
+
+Warning: ReflectionClass::__construct() expects exactly 1 parameter, 2 given in %s on line 33
+object(ReflectionClass)#%d (1) {
+ ["name"]=>
+ string(0) ""
+}
+Class X does not exist \ No newline at end of file
diff --git a/ext/reflection/tests/ReflectionClass_export_basic1.phpt b/ext/reflection/tests/ReflectionClass_export_basic1.phpt
new file mode 100644
index 0000000..8729731
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_export_basic1.phpt
@@ -0,0 +1,62 @@
+--TEST--
+ReflectionClass::export() - various parameters
+--FILE--
+<?php
+Class A {
+ public function privf(Exception $a) {}
+ public function pubf(A $a,
+ $b,
+ C $c = null,
+ $d = K,
+ $e = "15 chars long -",
+ $f = null,
+ $g = false,
+ array $h = null) {}
+}
+
+Class C extends A { }
+
+define('K', "16 chars long --");
+ReflectionClass::export("C");
+?>
+--EXPECTF--
+Class [ <user> class C extends A ] {
+ @@ %s 14-14
+
+ - Constants [0] {
+ }
+
+ - Static properties [0] {
+ }
+
+ - Static methods [0] {
+ }
+
+ - Properties [0] {
+ }
+
+ - Methods [2] {
+ Method [ <user, inherits A> public method privf ] {
+ @@ %s 3 - 3
+
+ - Parameters [1] {
+ Parameter #0 [ <required> Exception $a ]
+ }
+ }
+
+ Method [ <user, inherits A> public method pubf ] {
+ @@ %s 4 - 11
+
+ - Parameters [8] {
+ Parameter #0 [ <required> A $a ]
+ Parameter #1 [ <required> $b ]
+ Parameter #2 [ <optional> C or NULL $c = NULL ]
+ Parameter #3 [ <optional> $d = '16 chars long -...' ]
+ Parameter #4 [ <optional> $e = '15 chars long -' ]
+ Parameter #5 [ <optional> $f = NULL ]
+ Parameter #6 [ <optional> $g = false ]
+ Parameter #7 [ <optional> array or NULL $h = NULL ]
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/ext/reflection/tests/ReflectionClass_export_basic2.phpt b/ext/reflection/tests/ReflectionClass_export_basic2.phpt
new file mode 100644
index 0000000..b664488
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_export_basic2.phpt
@@ -0,0 +1,54 @@
+--TEST--
+ReflectionClass::export() - ensure inherited private props are hidden.
+--FILE--
+<?php
+Class c {
+ private $a;
+ static private $b;
+}
+
+class d extends c {}
+
+ReflectionClass::export("c");
+ReflectionClass::export("d");
+?>
+--EXPECTF--
+Class [ <user> class c ] {
+ @@ %s 2-5
+
+ - Constants [0] {
+ }
+
+ - Static properties [1] {
+ Property [ private static $b ]
+ }
+
+ - Static methods [0] {
+ }
+
+ - Properties [1] {
+ Property [ <default> private $a ]
+ }
+
+ - Methods [0] {
+ }
+}
+
+Class [ <user> class d extends c ] {
+ @@ %s 7-7
+
+ - Constants [0] {
+ }
+
+ - Static properties [0] {
+ }
+
+ - Static methods [0] {
+ }
+
+ - Properties [0] {
+ }
+
+ - Methods [0] {
+ }
+} \ No newline at end of file
diff --git a/ext/reflection/tests/ReflectionClass_getConstant_basic.phpt b/ext/reflection/tests/ReflectionClass_getConstant_basic.phpt
new file mode 100644
index 0000000..6e05111
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_getConstant_basic.phpt
@@ -0,0 +1,41 @@
+--TEST--
+ReflectionClass::getConstants()
+--FILE--
+<?php
+class C {
+ const a = 'hello from C';
+}
+class D extends C {
+}
+class E extends D {
+}
+class F extends E {
+ const a = 'hello from F';
+}
+class X {
+}
+
+$classes = array("C", "D", "E", "F", "X");
+foreach($classes as $class) {
+ echo "Reflecting on class $class: \n";
+ $rc = new ReflectionClass($class);
+ var_dump($rc->getConstant('a'));
+ var_dump($rc->getConstant('doesntexist'));
+}
+?>
+--EXPECTF--
+Reflecting on class C:
+string(12) "hello from C"
+bool(false)
+Reflecting on class D:
+string(12) "hello from C"
+bool(false)
+Reflecting on class E:
+string(12) "hello from C"
+bool(false)
+Reflecting on class F:
+string(12) "hello from F"
+bool(false)
+Reflecting on class X:
+bool(false)
+bool(false)
diff --git a/ext/reflection/tests/ReflectionClass_getConstant_error.phpt b/ext/reflection/tests/ReflectionClass_getConstant_error.phpt
new file mode 100644
index 0000000..907d6d8
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_getConstant_error.phpt
@@ -0,0 +1,37 @@
+--TEST--
+ReflectionClass::getConstant() - bad params
+--FILE--
+<?php
+class C {
+ const myConst = 1;
+}
+
+$rc = new ReflectionClass("C");
+echo "Check invalid params:\n";
+var_dump($rc->getConstant());
+var_dump($rc->getConstant("myConst", "myConst"));
+var_dump($rc->getConstant(null));
+var_dump($rc->getConstant(1));
+var_dump($rc->getConstant(1.5));
+var_dump($rc->getConstant(true));
+var_dump($rc->getConstant(array(1,2,3)));
+var_dump($rc->getConstant(new C));
+?>
+--EXPECTF--
+Check invalid params:
+
+Warning: ReflectionClass::getConstant() expects exactly 1 parameter, 0 given in %s on line 8
+NULL
+
+Warning: ReflectionClass::getConstant() expects exactly 1 parameter, 2 given in %s on line 9
+NULL
+bool(false)
+bool(false)
+bool(false)
+bool(false)
+
+Warning: ReflectionClass::getConstant() expects parameter 1 to be string, array given in %s on line 14
+NULL
+
+Warning: ReflectionClass::getConstant() expects parameter 1 to be string, object given in %s on line 15
+NULL \ No newline at end of file
diff --git a/ext/reflection/tests/ReflectionClass_getConstants_basic.phpt b/ext/reflection/tests/ReflectionClass_getConstants_basic.phpt
new file mode 100644
index 0000000..9abdcc8
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_getConstants_basic.phpt
@@ -0,0 +1,48 @@
+--TEST--
+ReflectionClass::getConstants()
+--FILE--
+<?php
+class C {
+ const a = 'hello from C';
+}
+class D extends C {
+}
+class E extends D {
+}
+class F extends E {
+ const a = 'hello from F';
+}
+class X {
+}
+
+$classes = array('C', 'D', 'E', 'F', 'X');
+foreach($classes as $class) {
+ echo "Constants from class $class: \n";
+ $rc = new ReflectionClass($class);
+ var_dump($rc->getConstants());
+}
+?>
+--EXPECTF--
+Constants from class C:
+array(1) {
+ ["a"]=>
+ string(12) "hello from C"
+}
+Constants from class D:
+array(1) {
+ ["a"]=>
+ string(12) "hello from C"
+}
+Constants from class E:
+array(1) {
+ ["a"]=>
+ string(12) "hello from C"
+}
+Constants from class F:
+array(1) {
+ ["a"]=>
+ string(12) "hello from F"
+}
+Constants from class X:
+array(0) {
+}
diff --git a/ext/reflection/tests/ReflectionClass_getConstants_error.phpt b/ext/reflection/tests/ReflectionClass_getConstants_error.phpt
new file mode 100644
index 0000000..1784d71
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_getConstants_error.phpt
@@ -0,0 +1,24 @@
+--TEST--
+ReflectionClass::getConstants()
+--FILE--
+<?php
+class X {
+}
+
+$rc = new reflectionClass('X');
+
+//Test invalid arguments
+$rc->getConstants('X');
+$rc->getConstants(true);
+$rc->getConstants(null);
+$rc->getConstants('A', 'B');
+
+?>
+--EXPECTF--
+Warning: ReflectionClass::getConstants() expects exactly 0 parameters, 1 given in %s on line %d
+
+Warning: ReflectionClass::getConstants() expects exactly 0 parameters, 1 given in %s on line %d
+
+Warning: ReflectionClass::getConstants() expects exactly 0 parameters, 1 given in %s on line %d
+
+Warning: ReflectionClass::getConstants() expects exactly 0 parameters, 2 given in %s on line %d
diff --git a/ext/reflection/tests/ReflectionClass_getConstructor_basic.phpt b/ext/reflection/tests/ReflectionClass_getConstructor_basic.phpt
new file mode 100644
index 0000000..1f5ba43
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_getConstructor_basic.phpt
@@ -0,0 +1,79 @@
+--TEST--
+ReflectionClass::getConstructor()
+--FILE--
+<?php
+class NewCtor {
+ function __construct() {}
+}
+
+class ExtendsNewCtor extends NewCtor {
+}
+
+class OldCtor {
+ function OldCtor() {}
+}
+
+class ExtendsOldCtor extends OldCtor {
+}
+
+
+class X {
+ function Y() {}
+}
+
+class Y extends X {
+}
+
+class OldAndNewCtor {
+ function OldAndNewCtor() {}
+ function __construct() {}
+}
+
+class NewAndOldCtor {
+ function __construct() {}
+ function NewAndOldCtor() {}
+}
+class B {
+ function B() {}
+}
+
+class C extends B {
+ function C() {}
+}
+
+class D1 extends C {
+ function __construct() {}
+}
+
+class D2 extends C {
+}
+
+$classes = array('NewCtor', 'ExtendsNewCtor', 'OldCtor', 'ExtendsOldCtor',
+ 'OldAndNewCtor', 'NewAndOldCtor', 'B', 'C', 'D1', 'D2', 'X', 'Y');
+
+foreach ($classes as $class) {
+ $rc = new ReflectionClass($class);
+ $rm = $rc->getConstructor();
+ if ($rm != null) {
+ echo "Constructor of $class: " . $rm->getName() . "\n";
+ } else {
+ echo "No constructor for $class\n";
+ }
+
+}
+
+?>
+--EXPECTF--
+Strict Standards: Redefining already defined constructor for class OldAndNewCtor in %s on line %d
+Constructor of NewCtor: __construct
+Constructor of ExtendsNewCtor: __construct
+Constructor of OldCtor: OldCtor
+Constructor of ExtendsOldCtor: OldCtor
+Constructor of OldAndNewCtor: __construct
+Constructor of NewAndOldCtor: __construct
+Constructor of B: B
+Constructor of C: C
+Constructor of D1: __construct
+Constructor of D2: C
+No constructor for X
+No constructor for Y
diff --git a/ext/reflection/tests/ReflectionClass_getConstructor_error.phpt b/ext/reflection/tests/ReflectionClass_getConstructor_error.phpt
new file mode 100644
index 0000000..7e8932a
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_getConstructor_error.phpt
@@ -0,0 +1,23 @@
+--TEST--
+ReflectionClass::getConstructor() - bad params
+--FILE--
+<?php
+class C {}
+$rc = new ReflectionClass('C');
+var_dump($rc->getConstructor(null));
+var_dump($rc->getConstructor('X'));
+var_dump($rc->getConstructor(true));
+var_dump($rc->getConstructor(array(1,2,3)));
+?>
+--EXPECTF--
+Warning: ReflectionClass::getConstructor() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionClass::getConstructor() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionClass::getConstructor() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionClass::getConstructor() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
diff --git a/ext/reflection/tests/ReflectionClass_getDefaultProperties_001.phpt b/ext/reflection/tests/ReflectionClass_getDefaultProperties_001.phpt
new file mode 100644
index 0000000..e19db81
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_getDefaultProperties_001.phpt
@@ -0,0 +1,194 @@
+--TEST--
+ReflectionClass::getDefaultProperties(), ReflectionClass::getStaticProperties()
+--CREDITS--
+Robin Fernandes <robinf@php.net>
+Steve Seear <stevseea@php.net>
+--FILE--
+<?php
+
+
+class A {
+ static public $statPubC = "stat pubC in A";
+ static protected $statProtC = "stat protC in A";
+ static private $statPrivC = "stat privC in A";
+
+ static public $statPubA = "stat pubA in A";
+ static protected $statProtA = "stat protA in A";
+ static private $statPrivA = "stat privA in A";
+
+ public $pubC = "pubC in A";
+ protected $protC = "protC in A";
+ private $privC = "privC in A";
+
+ public $pubA = "pubA in A";
+ protected $protA = "protA in A";
+ private $privA = "privA in A";
+}
+
+class B extends A {
+ static public $statPubC = "stat pubC in B";
+ static protected $statProtC = "stat protC in B";
+ static private $statPrivC = "stat privC in B";
+
+ static public $statPubB = "stat pubB in B";
+ static protected $statProtB = "stat protB in B";
+ static private $statPrivB = "stat privB in B";
+
+ public $pubC = "pubC in B";
+ protected $protC = "protC in B";
+ private $privC = "privC in B";
+
+ public $pubB = "pubB in B";
+ protected $protB = "protB in B";
+ private $privB = "privB in B";
+}
+
+class C extends B {
+ static public $statPubC = "stat pubC in C";
+ static protected $statProtC = "stat protC in C";
+ static private $statPrivC = "stat privC in C";
+
+ public $pubC = "pubC in C";
+ protected $protC = "protC in C";
+ private $privC = "privC in C";
+}
+
+class X {
+ static public $statPubC = "stat pubC in X";
+ static protected $statProtC = "stat protC in X";
+ static private $statPrivC = "stat privC in X";
+
+ public $pubC = "pubC in X";
+ protected $protC = "protC in X";
+ private $privC = "privC in X";
+}
+
+$classes = array('A', 'B', 'C', 'X');
+foreach ($classes as $class) {
+ $rc = new ReflectionClass($class);
+ echo "\n\n---- Static properties in $class ----\n";
+ print_r($rc->getStaticProperties());
+ echo "\n\n---- Default properties in $class ----\n";
+ print_r($rc->getDefaultProperties());
+}
+
+?>
+--EXPECTF--
+---- Static properties in A ----
+Array
+(
+ [statPubC] => stat pubC in A
+ [statProtC] => stat protC in A
+ [statPrivC] => stat privC in A
+ [statPubA] => stat pubA in A
+ [statProtA] => stat protA in A
+ [statPrivA] => stat privA in A
+)
+
+
+---- Default properties in A ----
+Array
+(
+ [statPubC] => stat pubC in A
+ [statProtC] => stat protC in A
+ [statPrivC] => stat privC in A
+ [statPubA] => stat pubA in A
+ [statProtA] => stat protA in A
+ [statPrivA] => stat privA in A
+ [pubC] => pubC in A
+ [protC] => protC in A
+ [privC] => privC in A
+ [pubA] => pubA in A
+ [protA] => protA in A
+ [privA] => privA in A
+)
+
+
+---- Static properties in B ----
+Array
+(
+ [statPubC] => stat pubC in B
+ [statProtC] => stat protC in B
+ [statPrivC] => stat privC in B
+ [statPubB] => stat pubB in B
+ [statProtB] => stat protB in B
+ [statPrivB] => stat privB in B
+ [statPubA] => stat pubA in A
+ [statProtA] => stat protA in A
+)
+
+
+---- Default properties in B ----
+Array
+(
+ [statPubC] => stat pubC in B
+ [statProtC] => stat protC in B
+ [statPrivC] => stat privC in B
+ [statPubB] => stat pubB in B
+ [statProtB] => stat protB in B
+ [statPrivB] => stat privB in B
+ [statPubA] => stat pubA in A
+ [statProtA] => stat protA in A
+ [pubC] => pubC in B
+ [protC] => protC in B
+ [privC] => privC in B
+ [pubB] => pubB in B
+ [protB] => protB in B
+ [privB] => privB in B
+ [pubA] => pubA in A
+ [protA] => protA in A
+)
+
+
+---- Static properties in C ----
+Array
+(
+ [statPubC] => stat pubC in C
+ [statProtC] => stat protC in C
+ [statPrivC] => stat privC in C
+ [statPubB] => stat pubB in B
+ [statProtB] => stat protB in B
+ [statPubA] => stat pubA in A
+ [statProtA] => stat protA in A
+)
+
+
+---- Default properties in C ----
+Array
+(
+ [statPubC] => stat pubC in C
+ [statProtC] => stat protC in C
+ [statPrivC] => stat privC in C
+ [statPubB] => stat pubB in B
+ [statProtB] => stat protB in B
+ [statPubA] => stat pubA in A
+ [statProtA] => stat protA in A
+ [pubC] => pubC in C
+ [protC] => protC in C
+ [privC] => privC in C
+ [pubB] => pubB in B
+ [protB] => protB in B
+ [pubA] => pubA in A
+ [protA] => protA in A
+)
+
+
+---- Static properties in X ----
+Array
+(
+ [statPubC] => stat pubC in X
+ [statProtC] => stat protC in X
+ [statPrivC] => stat privC in X
+)
+
+
+---- Default properties in X ----
+Array
+(
+ [statPubC] => stat pubC in X
+ [statProtC] => stat protC in X
+ [statPrivC] => stat privC in X
+ [pubC] => pubC in X
+ [protC] => protC in X
+ [privC] => privC in X
+)
diff --git a/ext/reflection/tests/ReflectionClass_getDefaultProperties_002.phpt b/ext/reflection/tests/ReflectionClass_getDefaultProperties_002.phpt
new file mode 100644
index 0000000..7c178ac
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_getDefaultProperties_002.phpt
@@ -0,0 +1,44 @@
+--TEST--
+ReflectionClass::getDefaultProperties(), ReflectionClass::getStaticProperties() - wrong param count
+--CREDITS--
+Robin Fernandes <robinf@php.net>
+Steve Seear <stevseea@php.net>
+--FILE--
+<?php
+interface I {}
+class C implements I {}
+$rc = new ReflectionClass('C');
+var_dump($rc->getDefaultProperties(null));
+var_dump($rc->getDefaultProperties('X'));
+var_dump($rc->getDefaultProperties(true));
+var_dump($rc->getDefaultProperties(array(1,2,3)));
+var_dump($rc->getStaticProperties(null));
+var_dump($rc->getStaticProperties('X'));
+var_dump($rc->getStaticProperties(true));
+var_dump($rc->getStaticProperties(array(1,2,3)));
+
+?>
+--EXPECTF--
+Warning: ReflectionClass::getDefaultProperties() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionClass::getDefaultProperties() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionClass::getDefaultProperties() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionClass::getDefaultProperties() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionClass::getStaticProperties() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionClass::getStaticProperties() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionClass::getStaticProperties() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionClass::getStaticProperties() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
diff --git a/ext/reflection/tests/ReflectionClass_getDocComment_001.phpt b/ext/reflection/tests/ReflectionClass_getDocComment_001.phpt
new file mode 100644
index 0000000..5feb560
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_getDocComment_001.phpt
@@ -0,0 +1,98 @@
+--TEST--
+ReflectionClass::getDocComment()
+--CREDITS--
+Robin Fernandes <robinf@php.net>
+Steve Seear <stevseea@php.net>
+--FILE--
+<?php
+/**
+
+
+ My
+Doc
+ * Comment
+for A
+
+* */
+class A {}
+
+/** My DocComment for B */
+class B extends A { }
+
+class C extends B {}
+
+/**
+ * Interface doc comment
+ */
+
+
+
+
+interface I {}
+
+/*.*
+ * Not a doc comment
+ */
+class D implements I {}
+
+/**** Not a doc comment */
+class E extends C implements I {} {}
+
+/**?** Not a doc comment */
+class F extends C implements I {} {}
+
+/** ** Doc comment for G */
+final class G extends C implements I {} {}
+
+$classes = array('A', 'B', 'C', 'D', 'E', 'F', 'G', 'I');
+foreach ($classes as $class) {
+ echo "\n\n---> Doc comment for class $class:\n";
+ $rc = new ReflectionClass($class);
+ var_dump($rc->getDocComment());
+}
+
+
+?>
+--EXPECTF--
+
+
+---> Doc comment for class A:
+string(%d) "/**
+
+
+ My
+Doc
+ * Comment
+for A
+
+* */"
+
+
+---> Doc comment for class B:
+string(26) "/** My DocComment for B */"
+
+
+---> Doc comment for class C:
+bool(false)
+
+
+---> Doc comment for class D:
+bool(false)
+
+
+---> Doc comment for class E:
+bool(false)
+
+
+---> Doc comment for class F:
+bool(false)
+
+
+---> Doc comment for class G:
+string(27) "/** ** Doc comment for G */"
+
+
+---> Doc comment for class I:
+string(%d) "/**
+ * Interface doc comment
+ */" \ No newline at end of file
diff --git a/ext/reflection/tests/ReflectionClass_getDocComment_002.phpt b/ext/reflection/tests/ReflectionClass_getDocComment_002.phpt
new file mode 100644
index 0000000..5bbd596
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_getDocComment_002.phpt
@@ -0,0 +1,26 @@
+--TEST--
+ReflectionClass::getDocComment() - bad params
+--CREDITS--
+Robin Fernandes <robinf@php.net>
+Steve Seear <stevseea@php.net>
+--FILE--
+<?php
+class C {}
+$rc = new ReflectionClass('C');
+var_dump($rc->getDocComment(null));
+var_dump($rc->getDocComment('X'));
+var_dump($rc->getDocComment(true));
+var_dump($rc->getDocComment(array(1,2,3)));
+?>
+--EXPECTF--
+Warning: ReflectionClass::getDocComment() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionClass::getDocComment() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionClass::getDocComment() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionClass::getDocComment() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
diff --git a/ext/reflection/tests/ReflectionClass_getExtensionName_basic.phpt b/ext/reflection/tests/ReflectionClass_getExtensionName_basic.phpt
new file mode 100644
index 0000000..310b22e
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_getExtensionName_basic.phpt
@@ -0,0 +1,14 @@
+--TEST--
+ReflectionClass::getExtensionName() method - basic test for getExtensionName() method
+--SKIPIF--
+<?php extension_loaded('dom') or die('skip - dom extension not loaded'); ?>
+--CREDITS--
+Rein Velt <rein@velt.org>
+#testFest Roosendaal 2008-05-10
+--FILE--
+<?php
+ $rc=new reflectionClass('domDocument');
+ var_dump( $rc->getExtensionName()) ;
+?>
+--EXPECT--
+string(3) "dom"
diff --git a/ext/reflection/tests/ReflectionClass_getExtensionName_variation.phpt b/ext/reflection/tests/ReflectionClass_getExtensionName_variation.phpt
new file mode 100644
index 0000000..998355c
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_getExtensionName_variation.phpt
@@ -0,0 +1,18 @@
+--TEST--
+ReflectionClass::getExtensionName() method - variation test for getExtensionName()
+--CREDITS--
+Rein Velt <rein@velt.org>
+#testFest Roosendaal 2008-05-10
+--FILE--
+<?php
+
+ class myClass
+ {
+ public $varX;
+ public $varY;
+ }
+ $rc=new reflectionClass('myClass');
+ var_dump( $rc->getExtensionName()) ;
+?>
+--EXPECT--
+bool(false)
diff --git a/ext/reflection/tests/ReflectionClass_getExtension_basic.phpt b/ext/reflection/tests/ReflectionClass_getExtension_basic.phpt
new file mode 100644
index 0000000..dbe157a
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_getExtension_basic.phpt
@@ -0,0 +1,17 @@
+--TEST--
+ReflectionClass::getExtension() method - basic test for getExtension() method
+--SKIPIF--
+<?php extension_loaded('dom') or die('skip - dom extension not loaded'); ?>
+--CREDITS--
+Rein Velt <rein@velt.org>
+#testFest Roosendaal 2008-05-10
+--FILE--
+<?php
+ $rc=new reflectionClass('domDocument');
+ var_dump($rc->getExtension()) ;
+?>
+--EXPECTF--
+object(ReflectionExtension)#%d (1) {
+ ["name"]=>
+ string(3) "dom"
+}
diff --git a/ext/reflection/tests/ReflectionClass_getExtension_variation.phpt b/ext/reflection/tests/ReflectionClass_getExtension_variation.phpt
new file mode 100644
index 0000000..5409504
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_getExtension_variation.phpt
@@ -0,0 +1,18 @@
+--TEST--
+ReflectionClass::getExtension() method - variation test for getExtension()
+--CREDITS--
+Rein Velt <rein@velt.org>
+#testFest Roosendaal 2008-05-10
+--FILE--
+<?php
+
+ class myClass
+ {
+ public $varX;
+ public $varY;
+ }
+ $rc=new reflectionClass('myClass');
+ var_dump( $rc->getExtension()) ;
+?>
+--EXPECT--
+NULL
diff --git a/ext/reflection/tests/ReflectionClass_getInterfaceNames_basic.phpt b/ext/reflection/tests/ReflectionClass_getInterfaceNames_basic.phpt
new file mode 100644
index 0000000..6681c9f
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_getInterfaceNames_basic.phpt
@@ -0,0 +1,23 @@
+--TEST--
+ReflectionClass::getInterfaceNames()
+--CREDITS--
+Michelangelo van Dam <dragonbe@gmail.com>
+#testfest roosendaal on 2008-05-10
+--FILE--
+<?php
+interface Foo { }
+
+interface Bar { }
+
+class Baz implements Foo, Bar { }
+
+$rc1 = new ReflectionClass("Baz");
+var_dump($rc1->getInterfaceNames());
+?>
+--EXPECT--
+array(2) {
+ [0]=>
+ string(3) "Foo"
+ [1]=>
+ string(3) "Bar"
+}
diff --git a/ext/reflection/tests/ReflectionClass_getInterfaces_001.phpt b/ext/reflection/tests/ReflectionClass_getInterfaces_001.phpt
new file mode 100644
index 0000000..4213600
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_getInterfaces_001.phpt
@@ -0,0 +1,311 @@
+--TEST--
+ReflectionClass::getInterfaces()
+--CREDITS--
+Robin Fernandes <robinf@php.net>
+Steve Seear <stevseea@php.net>
+--FILE--
+<?php
+class A0 {}
+class B0 extends A0 {}
+abstract class A1 {}
+class B1 extends A1 {}
+
+interface I0 {}
+interface I1 {}
+interface I2 {}
+interface I3 {}
+interface I4 extends I3 {}
+interface I5 extends I4 {}
+interface I6 extends I5, I1, I2 {}
+interface I7 extends I6 {}
+
+class C0 implements I0 {}
+class C1 implements I1, I3 {}
+class C2 extends C1 {}
+class C3 extends C2 implements I1 {}
+class C4 extends C3 implements I2 {}
+class C5 extends C4 implements I7 {}
+class C6 implements I1, I2, I3, I4, I5, I6, I7 {}
+
+
+$classes = array( 'A0', 'A1', 'B0', 'B1',
+ 'I0', 'I1', 'I2', 'I3', 'I4', 'I5', 'I6', 'I7',
+ 'C0', 'C1', 'C2', 'C3', 'C4', 'C5', 'C6' );
+
+foreach ($classes as $class) {
+ echo "---( Interfaces implemented by $class )---\n ";
+ $rc = new ReflectionClass($class);
+ $interfaces = $rc->getInterfaces();
+ // Sort interfaces so that tests do not fail because of wrong order.
+ ksort($interfaces);
+ print_r($interfaces);
+}
+
+?>
+--EXPECTF--
+---( Interfaces implemented by A0 )---
+ Array
+(
+)
+---( Interfaces implemented by A1 )---
+ Array
+(
+)
+---( Interfaces implemented by B0 )---
+ Array
+(
+)
+---( Interfaces implemented by B1 )---
+ Array
+(
+)
+---( Interfaces implemented by I0 )---
+ Array
+(
+)
+---( Interfaces implemented by I1 )---
+ Array
+(
+)
+---( Interfaces implemented by I2 )---
+ Array
+(
+)
+---( Interfaces implemented by I3 )---
+ Array
+(
+)
+---( Interfaces implemented by I4 )---
+ Array
+(
+ [I3] => ReflectionClass Object
+ (
+ [name] => I3
+ )
+
+)
+---( Interfaces implemented by I5 )---
+ Array
+(
+ [I3] => ReflectionClass Object
+ (
+ [name] => I3
+ )
+
+ [I4] => ReflectionClass Object
+ (
+ [name] => I4
+ )
+
+)
+---( Interfaces implemented by I6 )---
+ Array
+(
+ [I1] => ReflectionClass Object
+ (
+ [name] => I1
+ )
+
+ [I2] => ReflectionClass Object
+ (
+ [name] => I2
+ )
+
+ [I3] => ReflectionClass Object
+ (
+ [name] => I3
+ )
+
+ [I4] => ReflectionClass Object
+ (
+ [name] => I4
+ )
+
+ [I5] => ReflectionClass Object
+ (
+ [name] => I5
+ )
+
+)
+---( Interfaces implemented by I7 )---
+ Array
+(
+ [I1] => ReflectionClass Object
+ (
+ [name] => I1
+ )
+
+ [I2] => ReflectionClass Object
+ (
+ [name] => I2
+ )
+
+ [I3] => ReflectionClass Object
+ (
+ [name] => I3
+ )
+
+ [I4] => ReflectionClass Object
+ (
+ [name] => I4
+ )
+
+ [I5] => ReflectionClass Object
+ (
+ [name] => I5
+ )
+
+ [I6] => ReflectionClass Object
+ (
+ [name] => I6
+ )
+
+)
+---( Interfaces implemented by C0 )---
+ Array
+(
+ [I0] => ReflectionClass Object
+ (
+ [name] => I0
+ )
+
+)
+---( Interfaces implemented by C1 )---
+ Array
+(
+ [I1] => ReflectionClass Object
+ (
+ [name] => I1
+ )
+
+ [I3] => ReflectionClass Object
+ (
+ [name] => I3
+ )
+
+)
+---( Interfaces implemented by C2 )---
+ Array
+(
+ [I1] => ReflectionClass Object
+ (
+ [name] => I1
+ )
+
+ [I3] => ReflectionClass Object
+ (
+ [name] => I3
+ )
+
+)
+---( Interfaces implemented by C3 )---
+ Array
+(
+ [I1] => ReflectionClass Object
+ (
+ [name] => I1
+ )
+
+ [I3] => ReflectionClass Object
+ (
+ [name] => I3
+ )
+
+)
+---( Interfaces implemented by C4 )---
+ Array
+(
+ [I1] => ReflectionClass Object
+ (
+ [name] => I1
+ )
+
+ [I2] => ReflectionClass Object
+ (
+ [name] => I2
+ )
+
+ [I3] => ReflectionClass Object
+ (
+ [name] => I3
+ )
+
+)
+---( Interfaces implemented by C5 )---
+ Array
+(
+ [I1] => ReflectionClass Object
+ (
+ [name] => I1
+ )
+
+ [I2] => ReflectionClass Object
+ (
+ [name] => I2
+ )
+
+ [I3] => ReflectionClass Object
+ (
+ [name] => I3
+ )
+
+ [I4] => ReflectionClass Object
+ (
+ [name] => I4
+ )
+
+ [I5] => ReflectionClass Object
+ (
+ [name] => I5
+ )
+
+ [I6] => ReflectionClass Object
+ (
+ [name] => I6
+ )
+
+ [I7] => ReflectionClass Object
+ (
+ [name] => I7
+ )
+
+)
+---( Interfaces implemented by C6 )---
+ Array
+(
+ [I1] => ReflectionClass Object
+ (
+ [name] => I1
+ )
+
+ [I2] => ReflectionClass Object
+ (
+ [name] => I2
+ )
+
+ [I3] => ReflectionClass Object
+ (
+ [name] => I3
+ )
+
+ [I4] => ReflectionClass Object
+ (
+ [name] => I4
+ )
+
+ [I5] => ReflectionClass Object
+ (
+ [name] => I5
+ )
+
+ [I6] => ReflectionClass Object
+ (
+ [name] => I6
+ )
+
+ [I7] => ReflectionClass Object
+ (
+ [name] => I7
+ )
+
+)
diff --git a/ext/reflection/tests/ReflectionClass_getInterfaces_002.phpt b/ext/reflection/tests/ReflectionClass_getInterfaces_002.phpt
new file mode 100644
index 0000000..328a7c3
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_getInterfaces_002.phpt
@@ -0,0 +1,53 @@
+--TEST--
+ReflectionClass::getInterfaces() - interface ordering.
+--CREDITS--
+Robin Fernandes <robinf@php.net>
+Steve Seear <stevseea@php.net>
+--FILE--
+<?php
+interface I1 {}
+interface I2 {}
+interface I3 {}
+interface I4 extends I3 {}
+interface I5 extends I4 {}
+interface I6 extends I5, I1, I2 {}
+interface I7 extends I6 {}
+
+$rc = new ReflectionClass('I7');
+$interfaces = $rc->getInterfaces();
+print_r($interfaces);
+?>
+--EXPECTF--
+Array
+(
+ [I6] => ReflectionClass Object
+ (
+ [name] => I6
+ )
+
+ [I2] => ReflectionClass Object
+ (
+ [name] => I2
+ )
+
+ [I1] => ReflectionClass Object
+ (
+ [name] => I1
+ )
+
+ [I4] => ReflectionClass Object
+ (
+ [name] => I4
+ )
+
+ [I3] => ReflectionClass Object
+ (
+ [name] => I3
+ )
+
+ [I5] => ReflectionClass Object
+ (
+ [name] => I5
+ )
+
+) \ No newline at end of file
diff --git a/ext/reflection/tests/ReflectionClass_getInterfaces_003.phpt b/ext/reflection/tests/ReflectionClass_getInterfaces_003.phpt
new file mode 100644
index 0000000..74044f7
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_getInterfaces_003.phpt
@@ -0,0 +1,69 @@
+--TEST--
+ReflectionClass::getInterfaces() - odd ampersand behaviour.
+--CREDITS--
+Robin Fernandes <robinf@php.net>
+Steve Seear <stevseea@php.net>
+--FILE--
+<?php
+
+echo "An object is in an array and is referenced. As expected, var_dumping the array shows '&':\n";
+$a = array(new stdclass);
+$b =& $a[0];
+var_dump($a);
+
+echo "Naturally, this remains true if we modify the object:\n";
+$a[0]->x = 1;
+var_dump($a);
+
+
+echo "\n\nObtain the array of interfaces implemented by C.\n";
+interface I {}
+class C implements I {}
+$rc = new ReflectionClass('C');
+$a = $rc->getInterfaces();
+echo "The result is an array in which each element is an object (an instance of ReflectionClass)\n";
+echo "Var_dumping this array shows that the elements are referenced. By what?\n";
+var_dump($a);
+
+echo "Modify the object, and it is apparently no longer referenced.\n";
+$a['I']->x = 1;
+var_dump($a);
+
+?>
+--EXPECTF--
+An object is in an array and is referenced. As expected, var_dumping the array shows '&':
+array(1) {
+ [0]=>
+ &object(stdClass)#%d (0) {
+ }
+}
+Naturally, this remains true if we modify the object:
+array(1) {
+ [0]=>
+ &object(stdClass)#%d (1) {
+ ["x"]=>
+ int(1)
+ }
+}
+
+
+Obtain the array of interfaces implemented by C.
+The result is an array in which each element is an object (an instance of ReflectionClass)
+Var_dumping this array shows that the elements are referenced. By what?
+array(1) {
+ ["I"]=>
+ &object(ReflectionClass)#%d (1) {
+ ["name"]=>
+ string(1) "I"
+ }
+}
+Modify the object, and it is apparently no longer referenced.
+array(1) {
+ ["I"]=>
+ object(ReflectionClass)#%d (2) {
+ ["name"]=>
+ string(1) "I"
+ ["x"]=>
+ int(1)
+ }
+} \ No newline at end of file
diff --git a/ext/reflection/tests/ReflectionClass_getInterfaces_004.phpt b/ext/reflection/tests/ReflectionClass_getInterfaces_004.phpt
new file mode 100644
index 0000000..f62d58c
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_getInterfaces_004.phpt
@@ -0,0 +1,27 @@
+--TEST--
+ReflectionClass::getInterfaces() - wrong param count
+--CREDITS--
+Robin Fernandes <robinf@php.net>
+Steve Seear <stevseea@php.net>
+--FILE--
+<?php
+interface I {}
+class C implements I {}
+$rc = new ReflectionClass('C');
+var_dump($rc->getInterfaces(null));
+var_dump($rc->getInterfaces('X'));
+var_dump($rc->getInterfaces(true));
+var_dump($rc->getInterfaces(array(1,2,3)));
+?>
+--EXPECTF--
+Warning: ReflectionClass::getInterfaces() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionClass::getInterfaces() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionClass::getInterfaces() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionClass::getInterfaces() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
diff --git a/ext/reflection/tests/ReflectionClass_getMethod_001.phpt b/ext/reflection/tests/ReflectionClass_getMethod_001.phpt
new file mode 100644
index 0000000..2f2d790
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_getMethod_001.phpt
@@ -0,0 +1,168 @@
+--TEST--
+ReflectionClass::getMethod()
+--CREDITS--
+Robin Fernandes <robinf@php.net>
+Steve Seear <stevseea@php.net>
+--FILE--
+<?php
+class pubf {
+ public function f() {}
+ static public function s() {}
+}
+class subpubf extends pubf {
+}
+
+class protf {
+ protected function f() {}
+ static protected function s() {}
+}
+class subprotf extends protf {
+}
+
+class privf {
+ private function f() {}
+ static private function s() {}
+}
+class subprivf extends privf {
+}
+
+$classes = array("pubf", "subpubf", "protf", "subprotf",
+ "privf", "subprivf");
+foreach($classes as $class) {
+ echo "Reflecting on class $class: \n";
+ $rc = new ReflectionClass($class);
+ echo " --> Check for f(): ";
+ var_dump($rc->getMethod("f"));
+ echo " --> Check for s(): ";
+ var_dump($rc->getMethod("s"));
+ echo " --> Check for F(): ";
+ var_dump($rc->getMethod("F"));
+ echo " --> Check for doesntExist(): ";
+ try {
+ var_dump($rc->getMethod("doesntExist"));
+ } catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+ }
+}
+?>
+--EXPECTF--
+Reflecting on class pubf:
+ --> Check for f(): object(ReflectionMethod)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(1) "f"
+ [%u|b%"class"]=>
+ %unicode|string%(4) "pubf"
+}
+ --> Check for s(): object(ReflectionMethod)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(1) "s"
+ [%u|b%"class"]=>
+ %unicode|string%(4) "pubf"
+}
+ --> Check for F(): object(ReflectionMethod)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(1) "f"
+ [%u|b%"class"]=>
+ %unicode|string%(4) "pubf"
+}
+ --> Check for doesntExist(): Method doesntExist does not exist
+Reflecting on class subpubf:
+ --> Check for f(): object(ReflectionMethod)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(1) "f"
+ [%u|b%"class"]=>
+ %unicode|string%(4) "pubf"
+}
+ --> Check for s(): object(ReflectionMethod)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(1) "s"
+ [%u|b%"class"]=>
+ %unicode|string%(4) "pubf"
+}
+ --> Check for F(): object(ReflectionMethod)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(1) "f"
+ [%u|b%"class"]=>
+ %unicode|string%(4) "pubf"
+}
+ --> Check for doesntExist(): Method doesntExist does not exist
+Reflecting on class protf:
+ --> Check for f(): object(ReflectionMethod)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(1) "f"
+ [%u|b%"class"]=>
+ %unicode|string%(5) "protf"
+}
+ --> Check for s(): object(ReflectionMethod)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(1) "s"
+ [%u|b%"class"]=>
+ %unicode|string%(5) "protf"
+}
+ --> Check for F(): object(ReflectionMethod)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(1) "f"
+ [%u|b%"class"]=>
+ %unicode|string%(5) "protf"
+}
+ --> Check for doesntExist(): Method doesntExist does not exist
+Reflecting on class subprotf:
+ --> Check for f(): object(ReflectionMethod)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(1) "f"
+ [%u|b%"class"]=>
+ %unicode|string%(5) "protf"
+}
+ --> Check for s(): object(ReflectionMethod)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(1) "s"
+ [%u|b%"class"]=>
+ %unicode|string%(5) "protf"
+}
+ --> Check for F(): object(ReflectionMethod)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(1) "f"
+ [%u|b%"class"]=>
+ %unicode|string%(5) "protf"
+}
+ --> Check for doesntExist(): Method doesntExist does not exist
+Reflecting on class privf:
+ --> Check for f(): object(ReflectionMethod)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(1) "f"
+ [%u|b%"class"]=>
+ %unicode|string%(5) "privf"
+}
+ --> Check for s(): object(ReflectionMethod)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(1) "s"
+ [%u|b%"class"]=>
+ %unicode|string%(5) "privf"
+}
+ --> Check for F(): object(ReflectionMethod)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(1) "f"
+ [%u|b%"class"]=>
+ %unicode|string%(5) "privf"
+}
+ --> Check for doesntExist(): Method doesntExist does not exist
+Reflecting on class subprivf:
+ --> Check for f(): object(ReflectionMethod)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(1) "f"
+ [%u|b%"class"]=>
+ %unicode|string%(5) "privf"
+}
+ --> Check for s(): object(ReflectionMethod)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(1) "s"
+ [%u|b%"class"]=>
+ %unicode|string%(5) "privf"
+}
+ --> Check for F(): object(ReflectionMethod)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(1) "f"
+ [%u|b%"class"]=>
+ %unicode|string%(5) "privf"
+}
+ --> Check for doesntExist(): Method doesntExist does not exist
diff --git a/ext/reflection/tests/ReflectionClass_getMethod_002.phpt b/ext/reflection/tests/ReflectionClass_getMethod_002.phpt
new file mode 100644
index 0000000..2baabde
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_getMethod_002.phpt
@@ -0,0 +1,74 @@
+--TEST--
+ReflectionClass::getMethod() - error cases
+--CREDITS--
+Robin Fernandes <robinf@php.net>
+Steve Seear <stevseea@php.net>
+--FILE--
+<?php
+class C {
+ function f() {}
+}
+
+$rc = new ReflectionClass("C");
+echo "Check invalid params:\n";
+try {
+ var_dump($rc->getMethod());
+} catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+try {
+ var_dump($rc->getMethod("f", "f"));
+} catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+try {
+ var_dump($rc->getMethod(null));
+} catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+try {
+ var_dump($rc->getMethod(1));
+} catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+try {
+ var_dump($rc->getMethod(1.5));
+} catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+try {
+ var_dump($rc->getMethod(true));
+} catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+try {
+ var_dump($rc->getMethod(array(1,2,3)));
+} catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+try {
+ var_dump($rc->getMethod(new C));
+} catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+
+
+?>
+--EXPECTF--
+Check invalid params:
+
+Warning: ReflectionClass::getMethod() expects exactly 1 parameter, 0 given in %s on line 9
+NULL
+
+Warning: ReflectionClass::getMethod() expects exactly 1 parameter, 2 given in %s on line 14
+NULL
+Method does not exist
+Method 1 does not exist
+Method 1.5 does not exist
+Method 1 does not exist
+
+Warning: ReflectionClass::getMethod() expects parameter 1 to be string, array given in %s on line 39
+NULL
+
+Warning: ReflectionClass::getMethod() expects parameter 1 to be string, object given in %s on line 44
+NULL \ No newline at end of file
diff --git a/ext/reflection/tests/ReflectionClass_getMethods_001.phpt b/ext/reflection/tests/ReflectionClass_getMethods_001.phpt
new file mode 100644
index 0000000..ce5c980
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_getMethods_001.phpt
@@ -0,0 +1,140 @@
+--TEST--
+ReflectionClass::getMethods()
+--CREDITS--
+Robin Fernandes <robinf@php.net>
+Steve Seear <stevseea@php.net>
+--FILE--
+<?php
+class pubf {
+ public function f() {}
+ static public function s() {}
+}
+class subpubf extends pubf {
+}
+
+class protf {
+ protected function f() {}
+ static protected function s() {}
+}
+class subprotf extends protf {
+}
+
+class privf {
+ private function f() {}
+ static private function s() {}
+}
+class subprivf extends privf {
+}
+
+$classes = array("pubf", "subpubf", "protf", "subprotf",
+ "privf", "subprivf");
+foreach($classes as $class) {
+ echo "Reflecting on class $class: \n";
+ $rc = new ReflectionClass($class);
+ var_dump($rc->getMethods());
+}
+
+?>
+--EXPECTF--
+Reflecting on class pubf:
+array(2) {
+ [0]=>
+ &object(ReflectionMethod)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(1) "f"
+ [%u|b%"class"]=>
+ %unicode|string%(4) "pubf"
+ }
+ [1]=>
+ &object(ReflectionMethod)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(1) "s"
+ [%u|b%"class"]=>
+ %unicode|string%(4) "pubf"
+ }
+}
+Reflecting on class subpubf:
+array(2) {
+ [0]=>
+ &object(ReflectionMethod)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(1) "f"
+ [%u|b%"class"]=>
+ %unicode|string%(4) "pubf"
+ }
+ [1]=>
+ &object(ReflectionMethod)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(1) "s"
+ [%u|b%"class"]=>
+ %unicode|string%(4) "pubf"
+ }
+}
+Reflecting on class protf:
+array(2) {
+ [0]=>
+ &object(ReflectionMethod)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(1) "f"
+ [%u|b%"class"]=>
+ %unicode|string%(5) "protf"
+ }
+ [1]=>
+ &object(ReflectionMethod)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(1) "s"
+ [%u|b%"class"]=>
+ %unicode|string%(5) "protf"
+ }
+}
+Reflecting on class subprotf:
+array(2) {
+ [0]=>
+ &object(ReflectionMethod)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(1) "f"
+ [%u|b%"class"]=>
+ %unicode|string%(5) "protf"
+ }
+ [1]=>
+ &object(ReflectionMethod)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(1) "s"
+ [%u|b%"class"]=>
+ %unicode|string%(5) "protf"
+ }
+}
+Reflecting on class privf:
+array(2) {
+ [0]=>
+ &object(ReflectionMethod)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(1) "f"
+ [%u|b%"class"]=>
+ %unicode|string%(5) "privf"
+ }
+ [1]=>
+ &object(ReflectionMethod)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(1) "s"
+ [%u|b%"class"]=>
+ %unicode|string%(5) "privf"
+ }
+}
+Reflecting on class subprivf:
+array(2) {
+ [0]=>
+ &object(ReflectionMethod)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(1) "f"
+ [%u|b%"class"]=>
+ %unicode|string%(5) "privf"
+ }
+ [1]=>
+ &object(ReflectionMethod)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(1) "s"
+ [%u|b%"class"]=>
+ %unicode|string%(5) "privf"
+ }
+}
diff --git a/ext/reflection/tests/ReflectionClass_getMethods_002.phpt b/ext/reflection/tests/ReflectionClass_getMethods_002.phpt
new file mode 100644
index 0000000..b252225
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_getMethods_002.phpt
@@ -0,0 +1,18 @@
+--TEST--
+ReflectionClass::getMethods() - invalid arguments
+--CREDITS--
+Robin Fernandes <robinf@php.net>
+Steve Seear <stevseea@php.net>
+--FILE--
+<?php
+$rc = new ReflectionClass("ReflectionClass");
+echo "\nTest invalid arguments:";
+$rc->getMethods('X');
+$rc->getMethods('X', true);
+
+?>
+--EXPECTF--
+Test invalid arguments:
+Warning: ReflectionClass::getMethods() expects parameter 1 to be long, string given in %s on line 4
+
+Warning: ReflectionClass::getMethods() expects at most 1 parameter, 2 given in %s on line 5
diff --git a/ext/reflection/tests/ReflectionClass_getMethods_003.phpt b/ext/reflection/tests/ReflectionClass_getMethods_003.phpt
new file mode 100644
index 0000000..435f5d2
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_getMethods_003.phpt
@@ -0,0 +1,191 @@
+--TEST--
+ReflectionClass::getMethods()
+--CREDITS--
+Robin Fernandes <robinf@php.net>
+Steve Seear <stevseea@php.net>
+--FILE--
+<?php
+class C {
+ public function pubf1() {}
+ public function pubf2() {}
+ private function privf1() {}
+ private function privf2() {}
+ static public function pubsf1() {}
+ static public function pubsf2() {}
+ static private function privsf1() {}
+ static private function privsf2() {}
+}
+
+$rc = new ReflectionClass("C");
+$StaticFlag = 0x01;
+$pubFlag = 0x100;
+$privFlag = 0x400;
+
+echo "No methods:";
+var_dump($rc->getMethods(0));
+
+echo "Public methods:";
+var_dump($rc->getMethods($pubFlag));
+
+echo "Private methods:";
+var_dump($rc->getMethods($privFlag));
+
+echo "Public or static methods:";
+var_dump($rc->getMethods($StaticFlag | $pubFlag));
+
+echo "Private or static methods:";
+var_dump($rc->getMethods($StaticFlag | $privFlag));
+
+
+?>
+--EXPECTF--
+No methods:array(0) {
+}
+Public methods:array(4) {
+ [0]=>
+ &object(ReflectionMethod)#%d (2) {
+ ["name"]=>
+ string(5) "pubf1"
+ ["class"]=>
+ string(1) "C"
+ }
+ [1]=>
+ &object(ReflectionMethod)#%d (2) {
+ ["name"]=>
+ string(5) "pubf2"
+ ["class"]=>
+ string(1) "C"
+ }
+ [2]=>
+ &object(ReflectionMethod)#%d (2) {
+ ["name"]=>
+ string(6) "pubsf1"
+ ["class"]=>
+ string(1) "C"
+ }
+ [3]=>
+ &object(ReflectionMethod)#%d (2) {
+ ["name"]=>
+ string(6) "pubsf2"
+ ["class"]=>
+ string(1) "C"
+ }
+}
+Private methods:array(4) {
+ [0]=>
+ &object(ReflectionMethod)#%d (2) {
+ ["name"]=>
+ string(6) "privf1"
+ ["class"]=>
+ string(1) "C"
+ }
+ [1]=>
+ &object(ReflectionMethod)#%d (2) {
+ ["name"]=>
+ string(6) "privf2"
+ ["class"]=>
+ string(1) "C"
+ }
+ [2]=>
+ &object(ReflectionMethod)#%d (2) {
+ ["name"]=>
+ string(7) "privsf1"
+ ["class"]=>
+ string(1) "C"
+ }
+ [3]=>
+ &object(ReflectionMethod)#%d (2) {
+ ["name"]=>
+ string(7) "privsf2"
+ ["class"]=>
+ string(1) "C"
+ }
+}
+Public or static methods:array(6) {
+ [0]=>
+ &object(ReflectionMethod)#%d (2) {
+ ["name"]=>
+ string(5) "pubf1"
+ ["class"]=>
+ string(1) "C"
+ }
+ [1]=>
+ &object(ReflectionMethod)#%d (2) {
+ ["name"]=>
+ string(5) "pubf2"
+ ["class"]=>
+ string(1) "C"
+ }
+ [2]=>
+ &object(ReflectionMethod)#%d (2) {
+ ["name"]=>
+ string(6) "pubsf1"
+ ["class"]=>
+ string(1) "C"
+ }
+ [3]=>
+ &object(ReflectionMethod)#%d (2) {
+ ["name"]=>
+ string(6) "pubsf2"
+ ["class"]=>
+ string(1) "C"
+ }
+ [4]=>
+ &object(ReflectionMethod)#%d (2) {
+ ["name"]=>
+ string(7) "privsf1"
+ ["class"]=>
+ string(1) "C"
+ }
+ [5]=>
+ &object(ReflectionMethod)#%d (2) {
+ ["name"]=>
+ string(7) "privsf2"
+ ["class"]=>
+ string(1) "C"
+ }
+}
+Private or static methods:array(6) {
+ [0]=>
+ &object(ReflectionMethod)#%d (2) {
+ ["name"]=>
+ string(6) "privf1"
+ ["class"]=>
+ string(1) "C"
+ }
+ [1]=>
+ &object(ReflectionMethod)#%d (2) {
+ ["name"]=>
+ string(6) "privf2"
+ ["class"]=>
+ string(1) "C"
+ }
+ [2]=>
+ &object(ReflectionMethod)#%d (2) {
+ ["name"]=>
+ string(6) "pubsf1"
+ ["class"]=>
+ string(1) "C"
+ }
+ [3]=>
+ &object(ReflectionMethod)#%d (2) {
+ ["name"]=>
+ string(6) "pubsf2"
+ ["class"]=>
+ string(1) "C"
+ }
+ [4]=>
+ &object(ReflectionMethod)#%d (2) {
+ ["name"]=>
+ string(7) "privsf1"
+ ["class"]=>
+ string(1) "C"
+ }
+ [5]=>
+ &object(ReflectionMethod)#%d (2) {
+ ["name"]=>
+ string(7) "privsf2"
+ ["class"]=>
+ string(1) "C"
+ }
+}
diff --git a/ext/reflection/tests/ReflectionClass_getModifierNames_basic.phpt b/ext/reflection/tests/ReflectionClass_getModifierNames_basic.phpt
new file mode 100644
index 0000000..91a0a18
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_getModifierNames_basic.phpt
@@ -0,0 +1,139 @@
+--TEST--
+ReflectionClass::getModifierNames() basic tests
+--CREDITS--
+Felix De Vliegher <felix.devliegher@gmail.com>
+--FILE--
+<?php
+
+class a {}
+abstract class b {}
+final class c {}
+
+class x
+{
+ function __construct() {}
+ function __destruct() {}
+ private function a() {}
+ private static function b() {}
+ protected function c() {}
+ protected static function d() {}
+ public function e() {}
+ public static function f() {}
+ final function g() {}
+ function h() {}
+}
+
+abstract class y
+{
+ abstract function a();
+ abstract protected function b();
+}
+
+function dump_modifierNames($class) {
+ $obj = new ReflectionClass($class);
+ var_dump($obj->getName(), Reflection::getModifierNames($obj->getModifiers()));
+}
+
+function dump_methodModifierNames($class) {
+ $obj = new ReflectionClass($class);
+ foreach($obj->getMethods() as $method) {
+ var_dump($obj->getName() . "::" . $method->getName(), Reflection::getModifierNames($method->getModifiers()));
+ }
+}
+
+dump_modifierNames('a');
+dump_modifierNames('b');
+dump_modifierNames('c');
+
+dump_methodModifierNames('x');
+dump_methodModifierNames('y');
+
+?>
+==DONE==
+--EXPECT--
+string(1) "a"
+array(0) {
+}
+string(1) "b"
+array(1) {
+ [0]=>
+ string(8) "abstract"
+}
+string(1) "c"
+array(1) {
+ [0]=>
+ string(5) "final"
+}
+string(14) "x::__construct"
+array(1) {
+ [0]=>
+ string(6) "public"
+}
+string(13) "x::__destruct"
+array(1) {
+ [0]=>
+ string(6) "public"
+}
+string(4) "x::a"
+array(1) {
+ [0]=>
+ string(7) "private"
+}
+string(4) "x::b"
+array(2) {
+ [0]=>
+ string(7) "private"
+ [1]=>
+ string(6) "static"
+}
+string(4) "x::c"
+array(1) {
+ [0]=>
+ string(9) "protected"
+}
+string(4) "x::d"
+array(2) {
+ [0]=>
+ string(9) "protected"
+ [1]=>
+ string(6) "static"
+}
+string(4) "x::e"
+array(1) {
+ [0]=>
+ string(6) "public"
+}
+string(4) "x::f"
+array(2) {
+ [0]=>
+ string(6) "public"
+ [1]=>
+ string(6) "static"
+}
+string(4) "x::g"
+array(2) {
+ [0]=>
+ string(5) "final"
+ [1]=>
+ string(6) "public"
+}
+string(4) "x::h"
+array(1) {
+ [0]=>
+ string(6) "public"
+}
+string(4) "y::a"
+array(2) {
+ [0]=>
+ string(8) "abstract"
+ [1]=>
+ string(6) "public"
+}
+string(4) "y::b"
+array(2) {
+ [0]=>
+ string(8) "abstract"
+ [1]=>
+ string(9) "protected"
+}
+==DONE==
diff --git a/ext/reflection/tests/ReflectionClass_getModifiers_basic.phpt b/ext/reflection/tests/ReflectionClass_getModifiers_basic.phpt
new file mode 100644
index 0000000..65f23c9
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_getModifiers_basic.phpt
@@ -0,0 +1,37 @@
+--TEST--
+ReflectionClass::getModifiers()
+--CREDITS--
+Felix De Vliegher <felix.devliegher@gmail.com>
+--FILE--
+<?php
+
+class a {}
+abstract class b {}
+final class c {}
+interface d {}
+class e implements d {}
+interface f extends d {}
+class g extends b {}
+
+function dump_modifiers($class) {
+ $obj = new ReflectionClass($class);
+ var_dump($obj->getModifiers());
+}
+
+dump_modifiers('a');
+dump_modifiers('b');
+dump_modifiers('c');
+dump_modifiers('d');
+dump_modifiers('e');
+dump_modifiers('f');
+dump_modifiers('g');
+
+?>
+--EXPECT--
+int(0)
+int(32)
+int(64)
+int(128)
+int(524288)
+int(524416)
+int(0)
diff --git a/ext/reflection/tests/ReflectionClass_getName_basic.phpt b/ext/reflection/tests/ReflectionClass_getName_basic.phpt
new file mode 100644
index 0000000..158413f
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_getName_basic.phpt
@@ -0,0 +1,25 @@
+--TEST--
+ReflectionClass::getName()
+--FILE--
+<?php
+class TrickClass {
+ function __toString() {
+ //Return the name of another class
+ return "Exception";
+ }
+}
+
+$r1 = new ReflectionClass("stdClass");
+
+$myInstance = new stdClass;
+$r2 = new ReflectionClass($myInstance);
+
+$r3 = new ReflectionClass("TrickClass");
+
+var_dump($r1->getName(), $r2->getName(), $r3->getName());
+
+?>
+--EXPECTF--
+string(8) "stdClass"
+string(8) "stdClass"
+string(10) "TrickClass"
diff --git a/ext/reflection/tests/ReflectionClass_getName_error.phpt b/ext/reflection/tests/ReflectionClass_getName_error.phpt
new file mode 100644
index 0000000..06cc415
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_getName_error.phpt
@@ -0,0 +1,16 @@
+--TEST--
+ReflectionClass::getName() - invalid params
+--FILE--
+<?php
+
+$r1 = new ReflectionClass("stdClass");
+
+var_dump($r1->getName('X'));
+var_dump($r1->getName('X', true));
+?>
+--EXPECTF--
+Warning: ReflectionClass::getName() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionClass::getName() expects exactly 0 parameters, 2 given in %s on line %d
+NULL
diff --git a/ext/reflection/tests/ReflectionClass_getName_error1.phpt b/ext/reflection/tests/ReflectionClass_getName_error1.phpt
new file mode 100644
index 0000000..5590137
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_getName_error1.phpt
@@ -0,0 +1,8 @@
+--TEST--
+ReflectionClass::getName - forbid static invocation
+--FILE--
+<?php
+ReflectionClass::getName();
+?>
+--EXPECTF--
+Fatal error: Non-static method ReflectionClass::getName() cannot be called statically in %s on line 2
diff --git a/ext/reflection/tests/ReflectionClass_getNamespaceName.phpt b/ext/reflection/tests/ReflectionClass_getNamespaceName.phpt
new file mode 100644
index 0000000..1c46e06
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_getNamespaceName.phpt
@@ -0,0 +1,30 @@
+--TEST--
+ReflectionClass::getNamespaceName()
+--FILE--
+<?php
+namespace A\B;
+class Foo {
+}
+
+$function = new \ReflectionClass('stdClass');
+var_dump($function->inNamespace());
+var_dump($function->getName());
+var_dump($function->getNamespaceName());
+var_dump($function->getShortName());
+
+$function = new \ReflectionClass('A\\B\\Foo');
+var_dump($function->inNamespace());
+var_dump($function->getName());
+var_dump($function->getNamespaceName());
+var_dump($function->getShortName());
+?>
+--EXPECT--
+bool(false)
+string(8) "stdClass"
+string(0) ""
+string(8) "stdClass"
+bool(true)
+string(7) "A\B\Foo"
+string(3) "A\B"
+string(3) "Foo"
+
diff --git a/ext/reflection/tests/ReflectionClass_getParentClass.phpt b/ext/reflection/tests/ReflectionClass_getParentClass.phpt
new file mode 100644
index 0000000..46884ca
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_getParentClass.phpt
@@ -0,0 +1,21 @@
+--TEST--
+ReflectionClass::getParentClass()
+--CREDITS--
+Michelangelo van Dam <dragonbe@gmail.com>
+#testfest roosendaal on 2008-05-10
+--FILE--
+<?php
+
+class Foo {}
+
+class Bar extends Foo {}
+
+$rc1 = new ReflectionClass("Bar");
+var_dump($rc1->getParentClass());
+?>
+
+--EXPECTF--
+object(ReflectionClass)#%d (1) {
+ ["name"]=>
+ string(3) "Foo"
+}
diff --git a/ext/reflection/tests/ReflectionClass_getParentClass_001.phpt b/ext/reflection/tests/ReflectionClass_getParentClass_001.phpt
new file mode 100644
index 0000000..be50dbb
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_getParentClass_001.phpt
@@ -0,0 +1,38 @@
+--TEST--
+ReflectionClass::getParentClass()
+--CREDITS--
+Robin Fernandes <robinf@php.net>
+Steve Seear <stevseea@php.net>
+--FILE--
+<?php
+class A {}
+class B extends A {}
+
+$rc = new ReflectionClass('B');
+$parent = $rc->getParentClass();
+$grandParent = $parent->getParentClass();
+var_dump($parent, $grandParent);
+
+echo "\nTest bad params:\n";
+var_dump($rc->getParentClass(null));
+var_dump($rc->getParentClass('x'));
+var_dump($rc->getParentClass('x', 123));
+
+?>
+--EXPECTF--
+object(ReflectionClass)#%d (1) {
+ ["name"]=>
+ string(1) "A"
+}
+bool(false)
+
+Test bad params:
+
+Warning: ReflectionClass::getParentClass() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionClass::getParentClass() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionClass::getParentClass() expects exactly 0 parameters, 2 given in %s on line %d
+NULL
diff --git a/ext/reflection/tests/ReflectionClass_getProperties_001.phpt b/ext/reflection/tests/ReflectionClass_getProperties_001.phpt
new file mode 100644
index 0000000..b4f99ca
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_getProperties_001.phpt
@@ -0,0 +1,126 @@
+--TEST--
+ReflectionClass::getProperties()
+--CREDITS--
+Robin Fernandes <robinf@php.net>
+Steve Seear <stevseea@php.net>
+--FILE--
+<?php
+class pubf {
+ public $a;
+ static public $s;
+}
+class subpubf extends pubf {
+}
+
+class protf {
+ protected $a;
+ static protected $s;
+}
+class subprotf extends protf {
+}
+
+class privf {
+ private $a;
+ static private $s;
+}
+class subprivf extends privf {
+}
+
+$classes = array("pubf", "subpubf", "protf", "subprotf",
+ "privf", "subprivf");
+foreach($classes as $class) {
+ echo "Reflecting on class $class: \n";
+ $rc = new ReflectionClass($class);
+ var_dump($rc->getProperties());
+}
+
+?>
+--EXPECTF--
+Reflecting on class pubf:
+array(2) {
+ [0]=>
+ &object(ReflectionProperty)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(1) "a"
+ [%u|b%"class"]=>
+ %unicode|string%(4) "pubf"
+ }
+ [1]=>
+ &object(ReflectionProperty)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(1) "s"
+ [%u|b%"class"]=>
+ %unicode|string%(4) "pubf"
+ }
+}
+Reflecting on class subpubf:
+array(2) {
+ [0]=>
+ &object(ReflectionProperty)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(1) "a"
+ [%u|b%"class"]=>
+ %unicode|string%(4) "pubf"
+ }
+ [1]=>
+ &object(ReflectionProperty)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(1) "s"
+ [%u|b%"class"]=>
+ %unicode|string%(4) "pubf"
+ }
+}
+Reflecting on class protf:
+array(2) {
+ [0]=>
+ &object(ReflectionProperty)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(1) "a"
+ [%u|b%"class"]=>
+ %unicode|string%(5) "protf"
+ }
+ [1]=>
+ &object(ReflectionProperty)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(1) "s"
+ [%u|b%"class"]=>
+ %unicode|string%(5) "protf"
+ }
+}
+Reflecting on class subprotf:
+array(2) {
+ [0]=>
+ &object(ReflectionProperty)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(1) "a"
+ [%u|b%"class"]=>
+ %unicode|string%(5) "protf"
+ }
+ [1]=>
+ &object(ReflectionProperty)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(1) "s"
+ [%u|b%"class"]=>
+ %unicode|string%(5) "protf"
+ }
+}
+Reflecting on class privf:
+array(2) {
+ [0]=>
+ &object(ReflectionProperty)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(1) "a"
+ [%u|b%"class"]=>
+ %unicode|string%(5) "privf"
+ }
+ [1]=>
+ &object(ReflectionProperty)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(1) "s"
+ [%u|b%"class"]=>
+ %unicode|string%(5) "privf"
+ }
+}
+Reflecting on class subprivf:
+array(0) {
+}
diff --git a/ext/reflection/tests/ReflectionClass_getProperties_002.phpt b/ext/reflection/tests/ReflectionClass_getProperties_002.phpt
new file mode 100644
index 0000000..c21cff2
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_getProperties_002.phpt
@@ -0,0 +1,17 @@
+--TEST--
+ReflectionClass::getProperties() - invalid arguments
+--CREDITS--
+Robin Fernandes <robinf@php.net>
+Steve Seear <stevseea@php.net>
+--FILE--
+<?php
+$rc = new ReflectionClass("ReflectionClass");
+echo "\nTest invalid arguments:";
+$rc->getProperties('X');
+$rc->getProperties('X', true);
+?>
+--EXPECTF--
+Test invalid arguments:
+Warning: ReflectionClass::getProperties() expects parameter 1 to be long, string given in %s on line 4
+
+Warning: ReflectionClass::getProperties() expects at most 1 parameter, 2 given in %s on line 5
diff --git a/ext/reflection/tests/ReflectionClass_getProperties_003.phpt b/ext/reflection/tests/ReflectionClass_getProperties_003.phpt
new file mode 100644
index 0000000..b4f9a77
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_getProperties_003.phpt
@@ -0,0 +1,189 @@
+--TEST--
+ReflectionClass::getProperties()
+--CREDITS--
+Robin Fernandes <robinf@php.net>
+Steve Seear <stevseea@php.net>
+--FILE--
+<?php
+class C {
+ public $pub1;
+ public $pub2;
+ private $priv1;
+ private $priv2;
+ static public $pubs;
+ static public $pubs2;
+ static private $privs1;
+ static private $privs2;
+}
+
+$rc = new ReflectionClass("C");
+$StaticFlag = 0x01;
+$pubFlag = 0x100;
+$privFlag = 0x400;
+
+echo "No properties:";
+var_dump($rc->getProperties(0));
+
+echo "Public properties:";
+var_dump($rc->getProperties($pubFlag));
+
+echo "Private properties:";
+var_dump($rc->getProperties($privFlag));
+
+echo "Public or static properties:";
+var_dump($rc->getProperties($StaticFlag | $pubFlag));
+
+echo "Private or static properties:";
+var_dump($rc->getProperties($StaticFlag | $privFlag));
+?>
+--EXPECTF--
+No properties:array(0) {
+}
+Public properties:array(4) {
+ [0]=>
+ &object(ReflectionProperty)#%d (2) {
+ ["name"]=>
+ string(4) "pub1"
+ ["class"]=>
+ string(1) "C"
+ }
+ [1]=>
+ &object(ReflectionProperty)#%d (2) {
+ ["name"]=>
+ string(4) "pub2"
+ ["class"]=>
+ string(1) "C"
+ }
+ [2]=>
+ &object(ReflectionProperty)#%d (2) {
+ ["name"]=>
+ string(4) "pubs"
+ ["class"]=>
+ string(1) "C"
+ }
+ [3]=>
+ &object(ReflectionProperty)#%d (2) {
+ ["name"]=>
+ string(5) "pubs2"
+ ["class"]=>
+ string(1) "C"
+ }
+}
+Private properties:array(4) {
+ [0]=>
+ &object(ReflectionProperty)#%d (2) {
+ ["name"]=>
+ string(5) "priv1"
+ ["class"]=>
+ string(1) "C"
+ }
+ [1]=>
+ &object(ReflectionProperty)#%d (2) {
+ ["name"]=>
+ string(5) "priv2"
+ ["class"]=>
+ string(1) "C"
+ }
+ [2]=>
+ &object(ReflectionProperty)#%d (2) {
+ ["name"]=>
+ string(6) "privs1"
+ ["class"]=>
+ string(1) "C"
+ }
+ [3]=>
+ &object(ReflectionProperty)#%d (2) {
+ ["name"]=>
+ string(6) "privs2"
+ ["class"]=>
+ string(1) "C"
+ }
+}
+Public or static properties:array(6) {
+ [0]=>
+ &object(ReflectionProperty)#%d (2) {
+ ["name"]=>
+ string(4) "pub1"
+ ["class"]=>
+ string(1) "C"
+ }
+ [1]=>
+ &object(ReflectionProperty)#%d (2) {
+ ["name"]=>
+ string(4) "pub2"
+ ["class"]=>
+ string(1) "C"
+ }
+ [2]=>
+ &object(ReflectionProperty)#%d (2) {
+ ["name"]=>
+ string(4) "pubs"
+ ["class"]=>
+ string(1) "C"
+ }
+ [3]=>
+ &object(ReflectionProperty)#%d (2) {
+ ["name"]=>
+ string(5) "pubs2"
+ ["class"]=>
+ string(1) "C"
+ }
+ [4]=>
+ &object(ReflectionProperty)#%d (2) {
+ ["name"]=>
+ string(6) "privs1"
+ ["class"]=>
+ string(1) "C"
+ }
+ [5]=>
+ &object(ReflectionProperty)#%d (2) {
+ ["name"]=>
+ string(6) "privs2"
+ ["class"]=>
+ string(1) "C"
+ }
+}
+Private or static properties:array(6) {
+ [0]=>
+ &object(ReflectionProperty)#%d (2) {
+ ["name"]=>
+ string(5) "priv1"
+ ["class"]=>
+ string(1) "C"
+ }
+ [1]=>
+ &object(ReflectionProperty)#%d (2) {
+ ["name"]=>
+ string(5) "priv2"
+ ["class"]=>
+ string(1) "C"
+ }
+ [2]=>
+ &object(ReflectionProperty)#%d (2) {
+ ["name"]=>
+ string(4) "pubs"
+ ["class"]=>
+ string(1) "C"
+ }
+ [3]=>
+ &object(ReflectionProperty)#%d (2) {
+ ["name"]=>
+ string(5) "pubs2"
+ ["class"]=>
+ string(1) "C"
+ }
+ [4]=>
+ &object(ReflectionProperty)#%d (2) {
+ ["name"]=>
+ string(6) "privs1"
+ ["class"]=>
+ string(1) "C"
+ }
+ [5]=>
+ &object(ReflectionProperty)#%d (2) {
+ ["name"]=>
+ string(6) "privs2"
+ ["class"]=>
+ string(1) "C"
+ }
+} \ No newline at end of file
diff --git a/ext/reflection/tests/ReflectionClass_getProperty_001.phpt b/ext/reflection/tests/ReflectionClass_getProperty_001.phpt
new file mode 100644
index 0000000..9e174b7
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_getProperty_001.phpt
@@ -0,0 +1,146 @@
+--TEST--
+ReflectionClass::getProperty()
+--CREDITS--
+Robin Fernandes <robinf@php.net>
+Steve Seear <stevseea@php.net>
+--FILE--
+<?php
+class pubf {
+ public $a;
+ static public $s;
+}
+class subpubf extends pubf {
+}
+
+class protf {
+ protected $a;
+ static protected $s;
+}
+class subprotf extends protf {
+}
+
+class privf {
+ private $a;
+ static protected $s;
+}
+class subprivf extends privf {
+}
+
+$classes = array("pubf", "subpubf", "protf", "subprotf",
+ "privf", "subprivf");
+foreach($classes as $class) {
+ echo "Reflecting on class $class: \n";
+ $rc = new ReflectionClass($class);
+ try {
+ echo " --> Check for s: ";
+ var_dump($rc->getProperty("s"));
+ } catch (exception $e) {
+ echo $e->getMessage() . "\n";
+ }
+ try {
+ echo " --> Check for a: ";
+ var_dump($rc->getProperty("a"));
+ } catch (exception $e) {
+ echo $e->getMessage() . "\n";
+ }
+ try {
+ echo " --> Check for A: ";
+ var_dump($rc->getProperty("A"));
+ } catch (exception $e) {
+ echo $e->getMessage() . "\n";
+ }
+ try {
+ echo " --> Check for doesntExist: ";
+ var_dump($rc->getProperty("doesntExist"));
+ } catch (exception $e) {
+ echo $e->getMessage() . "\n";
+ }
+
+}
+?>
+--EXPECTF--
+Reflecting on class pubf:
+ --> Check for s: object(ReflectionProperty)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(1) "s"
+ [%u|b%"class"]=>
+ %unicode|string%(4) "pubf"
+}
+ --> Check for a: object(ReflectionProperty)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(1) "a"
+ [%u|b%"class"]=>
+ %unicode|string%(4) "pubf"
+}
+ --> Check for A: Property A does not exist
+ --> Check for doesntExist: Property doesntExist does not exist
+Reflecting on class subpubf:
+ --> Check for s: object(ReflectionProperty)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(1) "s"
+ [%u|b%"class"]=>
+ %unicode|string%(4) "pubf"
+}
+ --> Check for a: object(ReflectionProperty)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(1) "a"
+ [%u|b%"class"]=>
+ %unicode|string%(4) "pubf"
+}
+ --> Check for A: Property A does not exist
+ --> Check for doesntExist: Property doesntExist does not exist
+Reflecting on class protf:
+ --> Check for s: object(ReflectionProperty)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(1) "s"
+ [%u|b%"class"]=>
+ %unicode|string%(5) "protf"
+}
+ --> Check for a: object(ReflectionProperty)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(1) "a"
+ [%u|b%"class"]=>
+ %unicode|string%(5) "protf"
+}
+ --> Check for A: Property A does not exist
+ --> Check for doesntExist: Property doesntExist does not exist
+Reflecting on class subprotf:
+ --> Check for s: object(ReflectionProperty)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(1) "s"
+ [%u|b%"class"]=>
+ %unicode|string%(5) "protf"
+}
+ --> Check for a: object(ReflectionProperty)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(1) "a"
+ [%u|b%"class"]=>
+ %unicode|string%(5) "protf"
+}
+ --> Check for A: Property A does not exist
+ --> Check for doesntExist: Property doesntExist does not exist
+Reflecting on class privf:
+ --> Check for s: object(ReflectionProperty)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(1) "s"
+ [%u|b%"class"]=>
+ %unicode|string%(5) "privf"
+}
+ --> Check for a: object(ReflectionProperty)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(1) "a"
+ [%u|b%"class"]=>
+ %unicode|string%(5) "privf"
+}
+ --> Check for A: Property A does not exist
+ --> Check for doesntExist: Property doesntExist does not exist
+Reflecting on class subprivf:
+ --> Check for s: object(ReflectionProperty)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(1) "s"
+ [%u|b%"class"]=>
+ %unicode|string%(5) "privf"
+}
+ --> Check for a: Property a does not exist
+ --> Check for A: Property A does not exist
+ --> Check for doesntExist: Property doesntExist does not exist
diff --git a/ext/reflection/tests/ReflectionClass_getProperty_002.phpt b/ext/reflection/tests/ReflectionClass_getProperty_002.phpt
new file mode 100644
index 0000000..be7bb53
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_getProperty_002.phpt
@@ -0,0 +1,72 @@
+--TEST--
+ReflectionClass::getProperty() - error cases
+--CREDITS--
+Robin Fernandes <robinf@php.net>
+Steve Seear <stevseea@php.net>
+--FILE--
+<?php
+class C {
+ public $a;
+}
+
+$rc = new ReflectionClass("C");
+echo "Check invalid params:\n";
+try {
+ var_dump($rc->getProperty());
+} catch (exception $e) {
+ echo $e->getMessage() . "\n";
+}
+try {
+ var_dump($rc->getProperty("a", "a"));
+} catch (exception $e) {
+ echo $e->getMessage() . "\n";
+}
+try {
+ var_dump($rc->getProperty(null));
+} catch (exception $e) {
+ echo $e->getMessage() . "\n";
+}
+try {
+ var_dump($rc->getProperty(1));
+} catch (exception $e) {
+ echo $e->getMessage() . "\n";
+}
+try {
+ var_dump($rc->getProperty(1.5));
+} catch (exception $e) {
+ echo $e->getMessage() . "\n";
+}
+try {
+ var_dump($rc->getProperty(true));
+} catch (exception $e) {
+ echo $e->getMessage() . "\n";
+}
+try {
+ var_dump($rc->getProperty(array(1,2,3)));
+} catch (exception $e) {
+ echo $e->getMessage() . "\n";
+}
+try {
+ var_dump($rc->getProperty(new C));
+} catch (exception $e) {
+ echo $e->getMessage() . "\n";
+}
+?>
+--EXPECTF--
+Check invalid params:
+
+Warning: ReflectionClass::getProperty() expects exactly 1 parameter, 0 given in %s on line 9
+NULL
+
+Warning: ReflectionClass::getProperty() expects exactly 1 parameter, 2 given in %s on line 14
+NULL
+Property does not exist
+Property 1 does not exist
+Property 1.5 does not exist
+Property 1 does not exist
+
+Warning: ReflectionClass::getProperty() expects parameter 1 to be string, array given in %s on line 39
+NULL
+
+Warning: ReflectionClass::getProperty() expects parameter 1 to be string, object given in %s on line 44
+NULL \ No newline at end of file
diff --git a/ext/reflection/tests/ReflectionClass_getProperty_003.phpt b/ext/reflection/tests/ReflectionClass_getProperty_003.phpt
new file mode 100644
index 0000000..515d986
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_getProperty_003.phpt
@@ -0,0 +1,251 @@
+--TEST--
+ReflectionClass::getProperty()
+--CREDITS--
+Robin Fernandes <robinf@php.net>
+Steve Seear <stevseea@php.net>
+--FILE--
+<?php
+class A {
+ static public $pubC = "pubC in A";
+ static protected $protC = "protC in A";
+ static private $privC = "privC in A";
+
+ static public $pubA = "pubA in A";
+ static protected $protA = "protA in A";
+ static private $privA = "privA in A";
+}
+
+class B extends A {
+ static public $pubC = "pubC in B";
+ static protected $protC = "protC in B";
+ static private $privC = "privC in B";
+
+ static public $pubB = "pubB in B";
+ static protected $protB = "protB in B";
+ static private $privB = "privB in B";
+}
+
+class C extends B {
+ static public $pubC = "pubC in C";
+ static protected $protC = "protC in C";
+ static private $privC = "privC in C";
+}
+
+class X {
+ static public $pubC = "pubC in X";
+ static protected $protC = "protC in X";
+ static private $privC = "privC in X";
+}
+
+$myC = new C;
+$rc = new ReflectionClass("C");
+
+function showInfo($name) {
+ global $rc, $myC;
+ echo "--- (Reflecting on $name) ---\n";
+ try {
+ $rp = $rc->getProperty($name);
+ } catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+ return;
+ }
+ try {
+ var_dump($rp);
+ var_dump($rp->getValue($myC));
+ } catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+ return;
+ }
+}
+
+
+showInfo("pubA");
+showInfo("protA");
+showInfo("privA");
+
+showInfo("pubB");
+showInfo("protB");
+showInfo("privB");
+
+showInfo("pubC");
+showInfo("protC");
+showInfo("privC");
+showInfo("doesntExist");
+
+showInfo("A::pubC");
+showInfo("A::protC");
+showInfo("A::privC");
+
+showInfo("B::pubC");
+showInfo("B::protC");
+showInfo("B::privC");
+
+showInfo("c::pubC");
+showInfo("c::PUBC");
+showInfo("C::pubC");
+showInfo("C::protC");
+showInfo("C::privC");
+
+showInfo("X::pubC");
+showInfo("X::protC");
+showInfo("X::privC");
+showInfo("X::doesntExist");
+
+showInfo("doesntexist::doesntExist");
+
+?>
+--EXPECTF--
+--- (Reflecting on pubA) ---
+object(ReflectionProperty)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(4) "pubA"
+ [%u|b%"class"]=>
+ %unicode|string%(1) "A"
+}
+%unicode|string%(9) "pubA in A"
+--- (Reflecting on protA) ---
+object(ReflectionProperty)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(5) "protA"
+ [%u|b%"class"]=>
+ %unicode|string%(1) "A"
+}
+Cannot access non-public member C::protA
+--- (Reflecting on privA) ---
+Property privA does not exist
+--- (Reflecting on pubB) ---
+object(ReflectionProperty)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(4) "pubB"
+ [%u|b%"class"]=>
+ %unicode|string%(1) "B"
+}
+%unicode|string%(9) "pubB in B"
+--- (Reflecting on protB) ---
+object(ReflectionProperty)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(5) "protB"
+ [%u|b%"class"]=>
+ %unicode|string%(1) "B"
+}
+Cannot access non-public member C::protB
+--- (Reflecting on privB) ---
+Property privB does not exist
+--- (Reflecting on pubC) ---
+object(ReflectionProperty)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(4) "pubC"
+ [%u|b%"class"]=>
+ %unicode|string%(1) "C"
+}
+%unicode|string%(9) "pubC in C"
+--- (Reflecting on protC) ---
+object(ReflectionProperty)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(5) "protC"
+ [%u|b%"class"]=>
+ %unicode|string%(1) "C"
+}
+Cannot access non-public member C::protC
+--- (Reflecting on privC) ---
+object(ReflectionProperty)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(5) "privC"
+ [%u|b%"class"]=>
+ %unicode|string%(1) "C"
+}
+Cannot access non-public member C::privC
+--- (Reflecting on doesntExist) ---
+Property doesntExist does not exist
+--- (Reflecting on A::pubC) ---
+object(ReflectionProperty)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(4) "pubC"
+ [%u|b%"class"]=>
+ %unicode|string%(1) "A"
+}
+%unicode|string%(9) "pubC in A"
+--- (Reflecting on A::protC) ---
+object(ReflectionProperty)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(5) "protC"
+ [%u|b%"class"]=>
+ %unicode|string%(1) "A"
+}
+Cannot access non-public member A::protC
+--- (Reflecting on A::privC) ---
+object(ReflectionProperty)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(5) "privC"
+ [%u|b%"class"]=>
+ %unicode|string%(1) "A"
+}
+Cannot access non-public member A::privC
+--- (Reflecting on B::pubC) ---
+object(ReflectionProperty)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(4) "pubC"
+ [%u|b%"class"]=>
+ %unicode|string%(1) "B"
+}
+%unicode|string%(9) "pubC in B"
+--- (Reflecting on B::protC) ---
+object(ReflectionProperty)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(5) "protC"
+ [%u|b%"class"]=>
+ %unicode|string%(1) "B"
+}
+Cannot access non-public member B::protC
+--- (Reflecting on B::privC) ---
+object(ReflectionProperty)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(5) "privC"
+ [%u|b%"class"]=>
+ %unicode|string%(1) "B"
+}
+Cannot access non-public member B::privC
+--- (Reflecting on c::pubC) ---
+object(ReflectionProperty)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(4) "pubC"
+ [%u|b%"class"]=>
+ %unicode|string%(1) "C"
+}
+%unicode|string%(9) "pubC in C"
+--- (Reflecting on c::PUBC) ---
+Property PUBC does not exist
+--- (Reflecting on C::pubC) ---
+object(ReflectionProperty)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(4) "pubC"
+ [%u|b%"class"]=>
+ %unicode|string%(1) "C"
+}
+%unicode|string%(9) "pubC in C"
+--- (Reflecting on C::protC) ---
+object(ReflectionProperty)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(5) "protC"
+ [%u|b%"class"]=>
+ %unicode|string%(1) "C"
+}
+Cannot access non-public member C::protC
+--- (Reflecting on C::privC) ---
+object(ReflectionProperty)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(5) "privC"
+ [%u|b%"class"]=>
+ %unicode|string%(1) "C"
+}
+Cannot access non-public member C::privC
+--- (Reflecting on X::pubC) ---
+Fully qualified property name X::pubC does not specify a base class of C
+--- (Reflecting on X::protC) ---
+Fully qualified property name X::protC does not specify a base class of C
+--- (Reflecting on X::privC) ---
+Fully qualified property name X::privC does not specify a base class of C
+--- (Reflecting on X::doesntExist) ---
+Fully qualified property name X::doesntExist does not specify a base class of C
+--- (Reflecting on doesntexist::doesntExist) ---
+Class doesntexist does not exist
diff --git a/ext/reflection/tests/ReflectionClass_getProperty_004.phpt b/ext/reflection/tests/ReflectionClass_getProperty_004.phpt
new file mode 100644
index 0000000..1070d57
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_getProperty_004.phpt
@@ -0,0 +1,251 @@
+--TEST--
+ReflectionClass::getProperty()
+--CREDITS--
+Robin Fernandes <robinf@php.net>
+Steve Seear <stevseea@php.net>
+--FILE--
+<?php
+class A {
+ public $pubC = "pubC in A";
+ protected $protC = "protC in A";
+ private $privC = "privC in A";
+
+ public $pubA = "pubA in A";
+ protected $protA = "protA in A";
+ private $privA = "privA in A";
+}
+
+class B extends A {
+ public $pubC = "pubC in B";
+ protected $protC = "protC in B";
+ private $privC = "privC in B";
+
+ public $pubB = "pubB in B";
+ protected $protB = "protB in B";
+ private $privB = "privB in B";
+}
+
+class C extends B {
+ public $pubC = "pubC in C";
+ protected $protC = "protC in C";
+ private $privC = "privC in C";
+}
+
+class X {
+ public $pubC = "pubC in X";
+ protected $protC = "protC in X";
+ private $privC = "privC in X";
+}
+
+$myC = new C;
+$rc = new ReflectionClass("C");
+
+function showInfo($name) {
+ global $rc, $myC;
+ echo "--- (Reflecting on $name) ---\n";
+ try {
+ $rp = $rc->getProperty($name);
+ } catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+ return;
+ }
+ try {
+ var_dump($rp);
+ var_dump($rp->getValue($myC));
+ } catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+ return;
+ }
+}
+
+
+showInfo("pubA");
+showInfo("protA");
+showInfo("privA");
+
+showInfo("pubB");
+showInfo("protB");
+showInfo("privB");
+
+showInfo("pubC");
+showInfo("protC");
+showInfo("privC");
+showInfo("doesntExist");
+
+showInfo("A::pubC");
+showInfo("A::protC");
+showInfo("A::privC");
+
+showInfo("B::pubC");
+showInfo("B::protC");
+showInfo("B::privC");
+
+showInfo("c::pubC");
+showInfo("c::PUBC");
+showInfo("C::pubC");
+showInfo("C::protC");
+showInfo("C::privC");
+
+showInfo("X::pubC");
+showInfo("X::protC");
+showInfo("X::privC");
+showInfo("X::doesntExist");
+
+showInfo("doesntexist::doesntExist");
+
+?>
+--EXPECTF--
+--- (Reflecting on pubA) ---
+object(ReflectionProperty)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(4) "pubA"
+ [%u|b%"class"]=>
+ %unicode|string%(1) "A"
+}
+%unicode|string%(9) "pubA in A"
+--- (Reflecting on protA) ---
+object(ReflectionProperty)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(5) "protA"
+ [%u|b%"class"]=>
+ %unicode|string%(1) "A"
+}
+Cannot access non-public member C::protA
+--- (Reflecting on privA) ---
+Property privA does not exist
+--- (Reflecting on pubB) ---
+object(ReflectionProperty)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(4) "pubB"
+ [%u|b%"class"]=>
+ %unicode|string%(1) "B"
+}
+%unicode|string%(9) "pubB in B"
+--- (Reflecting on protB) ---
+object(ReflectionProperty)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(5) "protB"
+ [%u|b%"class"]=>
+ %unicode|string%(1) "B"
+}
+Cannot access non-public member C::protB
+--- (Reflecting on privB) ---
+Property privB does not exist
+--- (Reflecting on pubC) ---
+object(ReflectionProperty)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(4) "pubC"
+ [%u|b%"class"]=>
+ %unicode|string%(1) "C"
+}
+%unicode|string%(9) "pubC in C"
+--- (Reflecting on protC) ---
+object(ReflectionProperty)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(5) "protC"
+ [%u|b%"class"]=>
+ %unicode|string%(1) "C"
+}
+Cannot access non-public member C::protC
+--- (Reflecting on privC) ---
+object(ReflectionProperty)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(5) "privC"
+ [%u|b%"class"]=>
+ %unicode|string%(1) "C"
+}
+Cannot access non-public member C::privC
+--- (Reflecting on doesntExist) ---
+Property doesntExist does not exist
+--- (Reflecting on A::pubC) ---
+object(ReflectionProperty)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(4) "pubC"
+ [%u|b%"class"]=>
+ %unicode|string%(1) "A"
+}
+%unicode|string%(9) "pubC in C"
+--- (Reflecting on A::protC) ---
+object(ReflectionProperty)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(5) "protC"
+ [%u|b%"class"]=>
+ %unicode|string%(1) "A"
+}
+Cannot access non-public member A::protC
+--- (Reflecting on A::privC) ---
+object(ReflectionProperty)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(5) "privC"
+ [%u|b%"class"]=>
+ %unicode|string%(1) "A"
+}
+Cannot access non-public member A::privC
+--- (Reflecting on B::pubC) ---
+object(ReflectionProperty)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(4) "pubC"
+ [%u|b%"class"]=>
+ %unicode|string%(1) "B"
+}
+%unicode|string%(9) "pubC in C"
+--- (Reflecting on B::protC) ---
+object(ReflectionProperty)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(5) "protC"
+ [%u|b%"class"]=>
+ %unicode|string%(1) "B"
+}
+Cannot access non-public member B::protC
+--- (Reflecting on B::privC) ---
+object(ReflectionProperty)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(5) "privC"
+ [%u|b%"class"]=>
+ %unicode|string%(1) "B"
+}
+Cannot access non-public member B::privC
+--- (Reflecting on c::pubC) ---
+object(ReflectionProperty)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(4) "pubC"
+ [%u|b%"class"]=>
+ %unicode|string%(1) "C"
+}
+%unicode|string%(9) "pubC in C"
+--- (Reflecting on c::PUBC) ---
+Property PUBC does not exist
+--- (Reflecting on C::pubC) ---
+object(ReflectionProperty)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(4) "pubC"
+ [%u|b%"class"]=>
+ %unicode|string%(1) "C"
+}
+%unicode|string%(9) "pubC in C"
+--- (Reflecting on C::protC) ---
+object(ReflectionProperty)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(5) "protC"
+ [%u|b%"class"]=>
+ %unicode|string%(1) "C"
+}
+Cannot access non-public member C::protC
+--- (Reflecting on C::privC) ---
+object(ReflectionProperty)#%d (2) {
+ [%u|b%"name"]=>
+ %unicode|string%(5) "privC"
+ [%u|b%"class"]=>
+ %unicode|string%(1) "C"
+}
+Cannot access non-public member C::privC
+--- (Reflecting on X::pubC) ---
+Fully qualified property name X::pubC does not specify a base class of C
+--- (Reflecting on X::protC) ---
+Fully qualified property name X::protC does not specify a base class of C
+--- (Reflecting on X::privC) ---
+Fully qualified property name X::privC does not specify a base class of C
+--- (Reflecting on X::doesntExist) ---
+Fully qualified property name X::doesntExist does not specify a base class of C
+--- (Reflecting on doesntexist::doesntExist) ---
+Class doesntexist does not exist
diff --git a/ext/reflection/tests/ReflectionClass_getStaticPropertyValue_001.phpt b/ext/reflection/tests/ReflectionClass_getStaticPropertyValue_001.phpt
new file mode 100644
index 0000000..ffd81ff
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_getStaticPropertyValue_001.phpt
@@ -0,0 +1,69 @@
+--TEST--
+ReflectionClass::getStaticPropertyValue()
+--CREDITS--
+Robin Fernandes <robinf@php.net>
+Steve Seear <stevseea@php.net>
+--SKIPIF--
+<?php if (version_compare(zend_version(), '2.4.0', '>=')) die('skip ZendEngine 2.3 or below needed'); ?>
+--FILE--
+<?php
+class A {
+ static private $privateOverridden = "original private";
+ static protected $protectedOverridden = "original protected";
+ static public $publicOverridden = "original public";
+}
+
+class B extends A {
+ static private $privateOverridden = "changed private";
+ static protected $protectedOverridden = "changed protected";
+ static public $publicOverridden = "changed public";
+}
+
+echo "Retrieving static values from A:\n";
+$rcA = new ReflectionClass('A');
+var_dump($rcA->getStaticPropertyValue("privateOverridden", "default value"));
+var_dump($rcA->getStaticPropertyValue("\0A\0privateOverridden"));
+var_dump($rcA->getStaticPropertyValue("protectedOverridden", "default value"));
+var_dump($rcA->getStaticPropertyValue("\0*\0protectedOverridden"));
+var_dump($rcA->getStaticPropertyValue("publicOverridden"));
+
+echo "\nRetrieving static values from B:\n";
+$rcB = new ReflectionClass('B');
+var_dump($rcB->getStaticPropertyValue("\0A\0privateOverridden"));
+var_dump($rcB->getStaticPropertyValue("\0B\0privateOverridden"));
+var_dump($rcB->getStaticPropertyValue("\0*\0protectedOverridden"));
+var_dump($rcB->getStaticPropertyValue("publicOverridden"));
+
+echo "\nRetrieving non-existent values from A with no default value:\n";
+try {
+ var_dump($rcA->getStaticPropertyValue("protectedOverridden"));
+ echo "you should not see this";
+} catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+
+try {
+ var_dump($rcA->getStaticPropertyValue("privateOverridden"));
+ echo "you should not see this";
+} catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+
+?>
+--EXPECTF--
+Retrieving static values from A:
+string(13) "default value"
+string(16) "original private"
+string(13) "default value"
+string(18) "original protected"
+string(15) "original public"
+
+Retrieving static values from B:
+string(16) "original private"
+string(15) "changed private"
+string(17) "changed protected"
+string(14) "changed public"
+
+Retrieving non-existent values from A with no default value:
+Class A does not have a property named protectedOverridden
+Class A does not have a property named privateOverridden
diff --git a/ext/reflection/tests/ReflectionClass_getStaticPropertyValue_001_2_4.phpt b/ext/reflection/tests/ReflectionClass_getStaticPropertyValue_001_2_4.phpt
new file mode 100644
index 0000000..c299412
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_getStaticPropertyValue_001_2_4.phpt
@@ -0,0 +1,61 @@
+--TEST--
+ReflectionClass::getStaticPropertyValue()
+--CREDITS--
+Robin Fernandes <robinf@php.net>
+Steve Seear <stevseea@php.net>
+--SKIPIF--
+<?php if (version_compare(zend_version(), '2.4.0', '<')) die('skip ZendEngine 2.4 needed'); ?>
+--FILE--
+<?php
+class A {
+ static private $privateOverridden = "original private";
+ static protected $protectedOverridden = "original protected";
+ static public $publicOverridden = "original public";
+}
+
+class B extends A {
+ static private $privateOverridden = "changed private";
+ static protected $protectedOverridden = "changed protected";
+ static public $publicOverridden = "changed public";
+}
+
+echo "Retrieving static values from A:\n";
+$rcA = new ReflectionClass('A');
+var_dump($rcA->getStaticPropertyValue("privateOverridden", "default value"));
+var_dump($rcA->getStaticPropertyValue("\0A\0privateOverridden"));
+var_dump($rcA->getStaticPropertyValue("protectedOverridden", "default value"));
+var_dump($rcA->getStaticPropertyValue("\0*\0protectedOverridden"));
+var_dump($rcA->getStaticPropertyValue("publicOverridden"));
+
+echo "\nRetrieving static values from B:\n";
+$rcB = new ReflectionClass('B');
+var_dump($rcB->getStaticPropertyValue("\0A\0privateOverridden"));
+var_dump($rcB->getStaticPropertyValue("\0B\0privateOverridden"));
+var_dump($rcB->getStaticPropertyValue("\0*\0protectedOverridden"));
+var_dump($rcB->getStaticPropertyValue("publicOverridden"));
+
+echo "\nRetrieving non-existent values from A with no default value:\n";
+try {
+ var_dump($rcA->getStaticPropertyValue("protectedOverridden"));
+ echo "you should not see this";
+} catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+
+try {
+ var_dump($rcA->getStaticPropertyValue("privateOverridden"));
+ echo "you should not see this";
+} catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+
+?>
+--EXPECTF--
+Retrieving static values from A:
+string(13) "default value"
+
+Fatal error: Uncaught exception 'ReflectionException' with message 'Class A does not have a property named ' in %sReflectionClass_getStaticPropertyValue_001_2_4.php:%d
+Stack trace:
+#0 %sReflectionClass_getStaticPropertyValue_001_2_4.php(%d): ReflectionClass->getStaticPropertyValue('?A?privateOverr...')
+#1 {main}
+ thrown in %sReflectionClass_getStaticPropertyValue_001_2_4.php on line %d
diff --git a/ext/reflection/tests/ReflectionClass_getStaticPropertyValue_002.phpt b/ext/reflection/tests/ReflectionClass_getStaticPropertyValue_002.phpt
new file mode 100644
index 0000000..36b4744
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_getStaticPropertyValue_002.phpt
@@ -0,0 +1,52 @@
+--TEST--
+ReflectionClass::getStaticPropertyValue() - bad params
+--CREDITS--
+Robin Fernandes <robinf@php.net>
+Steve Seear <stevseea@php.net>
+--FILE--
+<?php
+class C {
+ public static $x;
+}
+
+$rc = new ReflectionClass('C');
+try {
+ var_dump($rc->getStaticPropertyValue("x", "default value", 'blah'));
+} catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+try {
+ var_dump($rc->getStaticPropertyValue());
+} catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+try {
+ var_dump($rc->getStaticPropertyValue(null));
+} catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+try {
+ var_dump($rc->getStaticPropertyValue(1.5, 'def'));
+} catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+try {
+ var_dump($rc->getStaticPropertyValue(array(1,2,3)));
+} catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+
+
+?>
+--EXPECTF--
+
+Warning: ReflectionClass::getStaticPropertyValue() expects at most 2 parameters, 3 given in %s on line 8
+NULL
+
+Warning: ReflectionClass::getStaticPropertyValue() expects at least 1 parameter, 0 given in %s on line 13
+NULL
+Class C does not have a property named
+string(3) "def"
+
+Warning: ReflectionClass::getStaticPropertyValue() expects parameter 1 to be string, array given in %s on line 28
+NULL \ No newline at end of file
diff --git a/ext/reflection/tests/ReflectionClass_hasConstant_001.phpt b/ext/reflection/tests/ReflectionClass_hasConstant_001.phpt
new file mode 100644
index 0000000..6e6d434
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_hasConstant_001.phpt
@@ -0,0 +1,36 @@
+--TEST--
+ReflectionClass::hasConstant()
+--CREDITS--
+Robin Fernandes <robinf@php.net>
+Steve Seear <stevseea@php.net>
+--FILE--
+<?php
+class C {
+ const myConst = 1;
+}
+
+class D extends C {
+}
+
+
+$rc = new ReflectionClass("C");
+echo "Check existing constant: ";
+var_dump($rc->hasConstant("myConst"));
+echo "Check existing constant, different case: ";
+var_dump($rc->hasConstant("MyCoNsT"));
+echo "Check absent constant: ";
+var_dump($rc->hasConstant("doesntExist"));
+
+
+$rd = new ReflectionClass("D");
+echo "Check inherited constant: ";
+var_dump($rd->hasConstant("myConst"));
+echo "Check absent constant: ";
+var_dump($rd->hasConstant("doesntExist"));
+?>
+--EXPECTF--
+Check existing constant: bool(true)
+Check existing constant, different case: bool(false)
+Check absent constant: bool(false)
+Check inherited constant: bool(true)
+Check absent constant: bool(false) \ No newline at end of file
diff --git a/ext/reflection/tests/ReflectionClass_hasConstant_002.phpt b/ext/reflection/tests/ReflectionClass_hasConstant_002.phpt
new file mode 100644
index 0000000..a0a76f0
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_hasConstant_002.phpt
@@ -0,0 +1,40 @@
+--TEST--
+ReflectionClass::hasConstant() - error cases
+--CREDITS--
+Robin Fernandes <robinf@php.net>
+Steve Seear <stevseea@php.net>
+--FILE--
+<?php
+class C {
+ const myConst = 1;
+}
+
+$rc = new ReflectionClass("C");
+echo "Check invalid params:\n";
+var_dump($rc->hasConstant());
+var_dump($rc->hasConstant("myConst", "myConst"));
+var_dump($rc->hasConstant(null));
+var_dump($rc->hasConstant(1));
+var_dump($rc->hasConstant(1.5));
+var_dump($rc->hasConstant(true));
+var_dump($rc->hasConstant(array(1,2,3)));
+var_dump($rc->hasConstant(new C));
+?>
+--EXPECTF--
+Check invalid params:
+
+Warning: ReflectionClass::hasConstant() expects exactly 1 parameter, 0 given in %s on line 8
+NULL
+
+Warning: ReflectionClass::hasConstant() expects exactly 1 parameter, 2 given in %s on line 9
+NULL
+bool(false)
+bool(false)
+bool(false)
+bool(false)
+
+Warning: ReflectionClass::hasConstant() expects parameter 1 to be string, array given in %s on line 14
+NULL
+
+Warning: ReflectionClass::hasConstant() expects parameter 1 to be string, object given in %s on line 15
+NULL \ No newline at end of file
diff --git a/ext/reflection/tests/ReflectionClass_hasConstant_basic.phpt b/ext/reflection/tests/ReflectionClass_hasConstant_basic.phpt
new file mode 100644
index 0000000..0ff2523
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_hasConstant_basic.phpt
@@ -0,0 +1,23 @@
+--TEST--
+ReflectionClass::hasConstant()
+--CREDITS--
+Marc Veldman <marc@ibuildings.nl>
+#testfest roosendaal on 2008-05-10
+--FILE--
+<?php
+//New instance of class C - defined below
+$rc = new ReflectionClass("C");
+
+//Check if C has constant foo
+var_dump($rc->hasConstant('foo'));
+
+//C should not have constant bar
+var_dump($rc->hasConstant('bar'));
+
+Class C {
+ const foo=1;
+}
+?>
+--EXPECTF--
+bool(true)
+bool(false)
diff --git a/ext/reflection/tests/ReflectionClass_hasMethod_001.phpt b/ext/reflection/tests/ReflectionClass_hasMethod_001.phpt
new file mode 100644
index 0000000..81614bd
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_hasMethod_001.phpt
@@ -0,0 +1,75 @@
+--TEST--
+ReflectionClass::hasMethod()
+--CREDITS--
+Robin Fernandes <robinf@php.net>
+Steve Seear <stevseea@php.net>
+--FILE--
+<?php
+class pubf {
+ public function f() {}
+ static public function s() {}
+}
+class subpubf extends pubf {
+}
+
+class protf {
+ protected function f() {}
+ static protected function s() {}
+}
+class subprotf extends protf {
+}
+
+class privf {
+ private function f() {}
+ static private function s() {}
+}
+class subprivf extends privf {
+}
+
+$classes = array("pubf", "subpubf", "protf", "subprotf",
+ "privf", "subprivf");
+foreach($classes as $class) {
+ echo "Reflecting on class $class: \n";
+ $rc = new ReflectionClass($class);
+ echo " --> Check for f(): ";
+ var_dump($rc->hasMethod("f"));
+ echo " --> Check for s(): ";
+ var_dump($rc->hasMethod("s"));
+ echo " --> Check for F(): ";
+ var_dump($rc->hasMethod("F"));
+ echo " --> Check for doesntExist(): ";
+ var_dump($rc->hasMethod("doesntExist"));
+}
+?>
+--EXPECTF--
+Reflecting on class pubf:
+ --> Check for f(): bool(true)
+ --> Check for s(): bool(true)
+ --> Check for F(): bool(true)
+ --> Check for doesntExist(): bool(false)
+Reflecting on class subpubf:
+ --> Check for f(): bool(true)
+ --> Check for s(): bool(true)
+ --> Check for F(): bool(true)
+ --> Check for doesntExist(): bool(false)
+Reflecting on class protf:
+ --> Check for f(): bool(true)
+ --> Check for s(): bool(true)
+ --> Check for F(): bool(true)
+ --> Check for doesntExist(): bool(false)
+Reflecting on class subprotf:
+ --> Check for f(): bool(true)
+ --> Check for s(): bool(true)
+ --> Check for F(): bool(true)
+ --> Check for doesntExist(): bool(false)
+Reflecting on class privf:
+ --> Check for f(): bool(true)
+ --> Check for s(): bool(true)
+ --> Check for F(): bool(true)
+ --> Check for doesntExist(): bool(false)
+Reflecting on class subprivf:
+ --> Check for f(): bool(true)
+ --> Check for s(): bool(true)
+ --> Check for F(): bool(true)
+ --> Check for doesntExist(): bool(false)
+ \ No newline at end of file
diff --git a/ext/reflection/tests/ReflectionClass_hasMethod_002.phpt b/ext/reflection/tests/ReflectionClass_hasMethod_002.phpt
new file mode 100644
index 0000000..63fe879
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_hasMethod_002.phpt
@@ -0,0 +1,40 @@
+--TEST--
+ReflectionClass::hasMethod() - error cases
+--CREDITS--
+Robin Fernandes <robinf@php.net>
+Steve Seear <stevseea@php.net>
+--FILE--
+<?php
+class C {
+ function f() {}
+}
+
+$rc = new ReflectionClass("C");
+echo "Check invalid params:\n";
+var_dump($rc->hasMethod());
+var_dump($rc->hasMethod("f", "f"));
+var_dump($rc->hasMethod(null));
+var_dump($rc->hasMethod(1));
+var_dump($rc->hasMethod(1.5));
+var_dump($rc->hasMethod(true));
+var_dump($rc->hasMethod(array(1,2,3)));
+var_dump($rc->hasMethod(new C));
+?>
+--EXPECTF--
+Check invalid params:
+
+Warning: ReflectionClass::hasMethod() expects exactly 1 parameter, 0 given in %s on line 8
+NULL
+
+Warning: ReflectionClass::hasMethod() expects exactly 1 parameter, 2 given in %s on line 9
+NULL
+bool(false)
+bool(false)
+bool(false)
+bool(false)
+
+Warning: ReflectionClass::hasMethod() expects parameter 1 to be string, array given in %s on line 14
+NULL
+
+Warning: ReflectionClass::hasMethod() expects parameter 1 to be string, object given in %s on line 15
+NULL
diff --git a/ext/reflection/tests/ReflectionClass_hasMethod_basic.phpt b/ext/reflection/tests/ReflectionClass_hasMethod_basic.phpt
new file mode 100644
index 0000000..fa4ee48
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_hasMethod_basic.phpt
@@ -0,0 +1,57 @@
+--TEST--
+ReflectionClass::hasMethod()
+--CREDITS--
+Marc Veldman <marc@ibuildings.nl>
+#testfest roosendaal on 2008-05-10
+--FILE--
+<?php
+//New instance of class C - defined below
+$rc = new ReflectionClass("C");
+
+//Check if C has public method publicFoo
+var_dump($rc->hasMethod('publicFoo'));
+
+//Check if C has protected method protectedFoo
+var_dump($rc->hasMethod('protectedFoo'));
+
+//Check if C has private method privateFoo
+var_dump($rc->hasMethod('privateFoo'));
+
+//Check if C has static method staticFoo
+var_dump($rc->hasMethod('staticFoo'));
+
+//C should not have method bar
+var_dump($rc->hasMethod('bar'));
+
+//Method names are case insensitive
+var_dump($rc->hasMethod('PUBLICfOO'));
+
+Class C {
+ public function publicFoo()
+ {
+ return true;
+ }
+
+ protected function protectedFoo()
+ {
+ return true;
+ }
+
+ private function privateFoo()
+ {
+ return true;
+ }
+
+ static function staticFoo()
+ {
+ return true;
+ }
+}
+?>
+--EXPECTF--
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(false)
+bool(true)
diff --git a/ext/reflection/tests/ReflectionClass_hasProperty_001.phpt b/ext/reflection/tests/ReflectionClass_hasProperty_001.phpt
new file mode 100644
index 0000000..88c4cd5
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_hasProperty_001.phpt
@@ -0,0 +1,75 @@
+--TEST--
+ReflectionClass::hasProperty()
+--CREDITS--
+Robin Fernandes <robinf@php.net>
+Steve Seear <stevseea@php.net>
+--FILE--
+<?php
+class pubf {
+ public $a;
+ static public $s;
+}
+class subpubf extends pubf {
+}
+
+class protf {
+ protected $a;
+ static protected $s;
+}
+class subprotf extends protf {
+}
+
+class privf {
+ private $a;
+ static protected $s;
+}
+class subprivf extends privf {
+}
+
+$classes = array("pubf", "subpubf", "protf", "subprotf",
+ "privf", "subprivf");
+foreach($classes as $class) {
+ echo "Reflecting on class $class: \n";
+ $rc = new ReflectionClass($class);
+ echo " --> Check for s: ";
+ var_dump($rc->hasProperty("s"));
+ echo " --> Check for a: ";
+ var_dump($rc->hasProperty("a"));
+ echo " --> Check for A: ";
+ var_dump($rc->hasProperty("A"));
+ echo " --> Check for doesntExist: ";
+ var_dump($rc->hasProperty("doesntExist"));
+}
+?>
+--EXPECTF--
+Reflecting on class pubf:
+ --> Check for s: bool(true)
+ --> Check for a: bool(true)
+ --> Check for A: bool(false)
+ --> Check for doesntExist: bool(false)
+Reflecting on class subpubf:
+ --> Check for s: bool(true)
+ --> Check for a: bool(true)
+ --> Check for A: bool(false)
+ --> Check for doesntExist: bool(false)
+Reflecting on class protf:
+ --> Check for s: bool(true)
+ --> Check for a: bool(true)
+ --> Check for A: bool(false)
+ --> Check for doesntExist: bool(false)
+Reflecting on class subprotf:
+ --> Check for s: bool(true)
+ --> Check for a: bool(true)
+ --> Check for A: bool(false)
+ --> Check for doesntExist: bool(false)
+Reflecting on class privf:
+ --> Check for s: bool(true)
+ --> Check for a: bool(true)
+ --> Check for A: bool(false)
+ --> Check for doesntExist: bool(false)
+Reflecting on class subprivf:
+ --> Check for s: bool(true)
+ --> Check for a: bool(false)
+ --> Check for A: bool(false)
+ --> Check for doesntExist: bool(false)
+
diff --git a/ext/reflection/tests/ReflectionClass_hasProperty_002.phpt b/ext/reflection/tests/ReflectionClass_hasProperty_002.phpt
new file mode 100644
index 0000000..7538903
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_hasProperty_002.phpt
@@ -0,0 +1,40 @@
+--TEST--
+ReflectionClass::hasProperty() - error cases
+--CREDITS--
+Robin Fernandes <robinf@php.net>
+Steve Seear <stevseea@php.net>
+--FILE--
+<?php
+class C {
+ public $a;
+}
+
+$rc = new ReflectionClass("C");
+echo "Check invalid params:\n";
+var_dump($rc->hasProperty());
+var_dump($rc->hasProperty("a", "a"));
+var_dump($rc->hasProperty(null));
+var_dump($rc->hasProperty(1));
+var_dump($rc->hasProperty(1.5));
+var_dump($rc->hasProperty(true));
+var_dump($rc->hasProperty(array(1,2,3)));
+var_dump($rc->hasProperty(new C));
+?>
+--EXPECTF--
+Check invalid params:
+
+Warning: ReflectionClass::hasProperty() expects exactly 1 parameter, 0 given in %s on line 8
+NULL
+
+Warning: ReflectionClass::hasProperty() expects exactly 1 parameter, 2 given in %s on line 9
+NULL
+bool(false)
+bool(false)
+bool(false)
+bool(false)
+
+Warning: ReflectionClass::hasProperty() expects parameter 1 to be string, array given in %s on line 14
+NULL
+
+Warning: ReflectionClass::hasProperty() expects parameter 1 to be string, object given in %s on line 15
+NULL
diff --git a/ext/reflection/tests/ReflectionClass_hasProperty_basic.phpt b/ext/reflection/tests/ReflectionClass_hasProperty_basic.phpt
new file mode 100644
index 0000000..d6dda7c
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_hasProperty_basic.phpt
@@ -0,0 +1,38 @@
+--TEST--
+ReflectionClass::hasProperty()
+--CREDITS--
+Marc Veldman <marc@ibuildings.nl>
+#testfest roosendaal on 2008-05-10
+--FILE--
+<?php
+//New instance of class C - defined below
+$rc = new ReflectionClass("C");
+
+//Check if C has public property publicFoo
+var_dump($rc->hasProperty('publicFoo'));
+
+//Check if C has protected property protectedFoo
+var_dump($rc->hasProperty('protectedFoo'));
+
+//Check if C has private property privateFoo
+var_dump($rc->hasProperty('privateFoo'));
+
+//Check if C has static property staticFoo
+var_dump($rc->hasProperty('staticFoo'));
+
+//C should not have property bar
+var_dump($rc->hasProperty('bar'));
+
+Class C {
+ public $publicFoo;
+ protected $protectedFoo;
+ private $privateFoo;
+ public static $staticFoo;
+}
+?>
+--EXPECTF--
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(false)
diff --git a/ext/reflection/tests/ReflectionClass_implementsInterface_001.phpt b/ext/reflection/tests/ReflectionClass_implementsInterface_001.phpt
new file mode 100644
index 0000000..9c2fded
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_implementsInterface_001.phpt
@@ -0,0 +1,155 @@
+--TEST--
+ReflectionClass::implementsInterface()
+--CREDITS--
+Robin Fernandes <robinf@php.net>
+Steve Seear <stevseea@php.net>
+--FILE--
+<?php
+interface I1 {}
+class A implements I1 {}
+class B extends A {}
+
+interface I2 extends I1 {}
+class C implements I2 {}
+
+$classNames = array('A', 'B', 'C', 'I1', 'I2');
+
+foreach ($classNames as $className) {
+ $rcs[$className] = new ReflectionClass($className);
+}
+
+foreach ($rcs as $childName => $child) {
+ foreach ($rcs as $parentName => $parent) {
+ echo "Does " . $childName . " implement " . $parentName . "? \n";
+ echo " - Using object argument: ";
+ try {
+ var_dump($child->implementsInterface($parent));
+ } catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+ }
+ echo " - Using string argument: ";
+ try {
+ var_dump($child->implementsInterface($parentName));
+ } catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+ }
+ }
+}
+
+
+
+echo "\n\nTest bad arguments:\n";
+try {
+ var_dump($rcs['A']->implementsInterface());
+} catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+try {
+ var_dump($rcs['A']->implementsInterface('C', 'C'));
+} catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+try {
+ var_dump($rcs['A']->implementsInterface(null));
+} catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+try {
+ var_dump($rcs['A']->implementsInterface('ThisClassDoesNotExist'));
+} catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+try {
+ var_dump($rcs['A']->implementsInterface(2));
+} catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+?>
+--EXPECTF--
+Does A implement A?
+ - Using object argument: Interface A is a Class
+ - Using string argument: Interface A is a Class
+Does A implement B?
+ - Using object argument: Interface B is a Class
+ - Using string argument: Interface B is a Class
+Does A implement C?
+ - Using object argument: Interface C is a Class
+ - Using string argument: Interface C is a Class
+Does A implement I1?
+ - Using object argument: bool(true)
+ - Using string argument: bool(true)
+Does A implement I2?
+ - Using object argument: bool(false)
+ - Using string argument: bool(false)
+Does B implement A?
+ - Using object argument: Interface A is a Class
+ - Using string argument: Interface A is a Class
+Does B implement B?
+ - Using object argument: Interface B is a Class
+ - Using string argument: Interface B is a Class
+Does B implement C?
+ - Using object argument: Interface C is a Class
+ - Using string argument: Interface C is a Class
+Does B implement I1?
+ - Using object argument: bool(true)
+ - Using string argument: bool(true)
+Does B implement I2?
+ - Using object argument: bool(false)
+ - Using string argument: bool(false)
+Does C implement A?
+ - Using object argument: Interface A is a Class
+ - Using string argument: Interface A is a Class
+Does C implement B?
+ - Using object argument: Interface B is a Class
+ - Using string argument: Interface B is a Class
+Does C implement C?
+ - Using object argument: Interface C is a Class
+ - Using string argument: Interface C is a Class
+Does C implement I1?
+ - Using object argument: bool(true)
+ - Using string argument: bool(true)
+Does C implement I2?
+ - Using object argument: bool(true)
+ - Using string argument: bool(true)
+Does I1 implement A?
+ - Using object argument: Interface A is a Class
+ - Using string argument: Interface A is a Class
+Does I1 implement B?
+ - Using object argument: Interface B is a Class
+ - Using string argument: Interface B is a Class
+Does I1 implement C?
+ - Using object argument: Interface C is a Class
+ - Using string argument: Interface C is a Class
+Does I1 implement I1?
+ - Using object argument: bool(true)
+ - Using string argument: bool(true)
+Does I1 implement I2?
+ - Using object argument: bool(false)
+ - Using string argument: bool(false)
+Does I2 implement A?
+ - Using object argument: Interface A is a Class
+ - Using string argument: Interface A is a Class
+Does I2 implement B?
+ - Using object argument: Interface B is a Class
+ - Using string argument: Interface B is a Class
+Does I2 implement C?
+ - Using object argument: Interface C is a Class
+ - Using string argument: Interface C is a Class
+Does I2 implement I1?
+ - Using object argument: bool(true)
+ - Using string argument: bool(true)
+Does I2 implement I2?
+ - Using object argument: bool(true)
+ - Using string argument: bool(true)
+
+
+Test bad arguments:
+
+Warning: ReflectionClass::implementsInterface() expects exactly 1 parameter, 0 given in %s on line 37
+NULL
+
+Warning: ReflectionClass::implementsInterface() expects exactly 1 parameter, 2 given in %s on line 42
+NULL
+Parameter one must either be a string or a ReflectionClass object
+Interface ThisClassDoesNotExist does not exist
+Parameter one must either be a string or a ReflectionClass object
diff --git a/ext/reflection/tests/ReflectionClass_isAbstract_basic.phpt b/ext/reflection/tests/ReflectionClass_isAbstract_basic.phpt
new file mode 100644
index 0000000..a7d1982
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_isAbstract_basic.phpt
@@ -0,0 +1,21 @@
+--TEST--
+ReflectionClass::isAbstract() method
+--CREDITS--
+Felix De Vliegher <felix.devliegher@gmail.com>
+#testfest roosendaal on 2008-05-10
+--FILE--
+<?php
+
+class TestClass {}
+abstract class TestAbstractClass {}
+
+$testClass = new ReflectionClass('TestClass');
+$abstractClass = new ReflectionClass('TestAbstractClass');
+
+var_dump($testClass->isAbstract());
+var_dump($abstractClass->isAbstract());
+
+?>
+--EXPECT--
+bool(false)
+bool(true)
diff --git a/ext/reflection/tests/ReflectionClass_isCloneable_001.phpt b/ext/reflection/tests/ReflectionClass_isCloneable_001.phpt
new file mode 100644
index 0000000..f1042cc
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_isCloneable_001.phpt
@@ -0,0 +1,71 @@
+--TEST--
+Testing ReflectionClass::isCloneable()
+--SKIPIF--
+<?php if (!extension_loaded('simplexml') || !extension_loaded('xmlwriter')) die("skip SimpleXML and XMLWriter is required for this test"); ?>
+--FILE--
+<?php
+
+class foo {
+}
+$foo = new foo;
+
+print "User class\n";
+$obj = new ReflectionClass($foo);
+var_dump($obj->isCloneable());
+$obj = new ReflectionObject($foo);
+var_dump($obj->isCloneable());
+$h = clone $foo;
+
+class bar {
+ private function __clone() {
+ }
+}
+$bar = new bar;
+print "User class - private __clone\n";
+$obj = new ReflectionClass($bar);
+var_dump($obj->isCloneable());
+$obj = new ReflectionObject($bar);
+var_dump($obj->isCloneable());
+$h = clone $foo;
+
+print "Closure\n";
+$closure = function () { };
+$obj = new ReflectionClass($closure);
+var_dump($obj->isCloneable());
+$obj = new ReflectionObject($closure);
+var_dump($obj->isCloneable());
+$h = clone $closure;
+
+print "Internal class - SimpleXMLElement\n";
+$obj = new ReflectionClass('simplexmlelement');
+var_dump($obj->isCloneable());
+$obj = new ReflectionObject(new simplexmlelement('<test></test>'));
+var_dump($obj->isCloneable());
+$h = clone new simplexmlelement('<test></test>');
+
+print "Internal class - XMLWriter\n";
+$obj = new ReflectionClass('xmlwriter');
+var_dump($obj->isCloneable());
+$obj = new ReflectionObject(new XMLWriter);
+var_dump($obj->isCloneable());
+$h = clone new xmlwriter;
+
+?>
+--EXPECTF--
+User class
+bool(true)
+bool(true)
+User class - private __clone
+bool(false)
+bool(false)
+Closure
+bool(true)
+bool(true)
+Internal class - SimpleXMLElement
+bool(true)
+bool(true)
+Internal class - XMLWriter
+bool(false)
+bool(false)
+
+Fatal error: Trying to clone an uncloneable object of class XMLWriter in %s on line %d
diff --git a/ext/reflection/tests/ReflectionClass_isCloneable_002.phpt b/ext/reflection/tests/ReflectionClass_isCloneable_002.phpt
new file mode 100644
index 0000000..7cde576
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_isCloneable_002.phpt
@@ -0,0 +1,25 @@
+--TEST--
+Testing ReflectionClass::isCloneable() with non instantiable objects
+--FILE--
+<?php
+
+trait foo {
+}
+$obj = new ReflectionClass('foo');
+var_dump($obj->isCloneable());
+
+abstract class bar {
+}
+$obj = new ReflectionClass('bar');
+var_dump($obj->isCloneable());
+
+interface baz {
+}
+$obj = new ReflectionClass('baz');
+var_dump($obj->isCloneable());
+
+?>
+--EXPECT--
+bool(false)
+bool(false)
+bool(false)
diff --git a/ext/reflection/tests/ReflectionClass_isFinal_basic.phpt b/ext/reflection/tests/ReflectionClass_isFinal_basic.phpt
new file mode 100644
index 0000000..57e577a
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_isFinal_basic.phpt
@@ -0,0 +1,21 @@
+--TEST--
+ReflectionClass::isFinal() method
+--CREDITS--
+Felix De Vliegher <felix.devliegher@gmail.com>
+#testfest roosendaal on 2008-05-10
+--FILE--
+<?php
+
+class TestClass {}
+final class TestFinalClass {}
+
+$normalClass = new ReflectionClass('TestClass');
+$finalClass = new ReflectionClass('TestFinalClass');
+
+var_dump($normalClass->isFinal());
+var_dump($finalClass->isFinal());
+
+?>
+--EXPECT--
+bool(false)
+bool(true)
diff --git a/ext/reflection/tests/ReflectionClass_isInstance_basic.phpt b/ext/reflection/tests/ReflectionClass_isInstance_basic.phpt
new file mode 100644
index 0000000..2da0944
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_isInstance_basic.phpt
@@ -0,0 +1,51 @@
+--TEST--
+ReflectionClass::isInstance()
+--FILE--
+<?php
+class A {}
+class B extends A {}
+
+interface I {}
+class C implements I {}
+
+class X {}
+
+$classes = array("A", "B", "C", "I", "X");
+
+$instances = array( "myA" => new A,
+ "myB" => new B,
+ "myC" => new C,
+ "myX" => new X );
+
+foreach ($classes as $class) {
+ $rc = new ReflectionClass($class);
+
+ foreach ($instances as $name => $instance) {
+ echo "is $name a $class? ";
+ var_dump($rc->isInstance($instance));
+ }
+
+}
+
+?>
+--EXPECTF--
+is myA a A? bool(true)
+is myB a A? bool(true)
+is myC a A? bool(false)
+is myX a A? bool(false)
+is myA a B? bool(false)
+is myB a B? bool(true)
+is myC a B? bool(false)
+is myX a B? bool(false)
+is myA a C? bool(false)
+is myB a C? bool(false)
+is myC a C? bool(true)
+is myX a C? bool(false)
+is myA a I? bool(false)
+is myB a I? bool(false)
+is myC a I? bool(true)
+is myX a I? bool(false)
+is myA a X? bool(false)
+is myB a X? bool(false)
+is myC a X? bool(false)
+is myX a X? bool(true)
diff --git a/ext/reflection/tests/ReflectionClass_isInstance_error.phpt b/ext/reflection/tests/ReflectionClass_isInstance_error.phpt
new file mode 100644
index 0000000..2c4f49b
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_isInstance_error.phpt
@@ -0,0 +1,39 @@
+--TEST--
+ReflectionClass::isInstance() - invalid params
+--FILE--
+<?php
+class X {}
+
+$rc = new ReflectionClass("X");
+$instance = new X;
+
+var_dump($rc->isInstance());
+var_dump($rc->isInstance($instance, $instance));
+var_dump($rc->isInstance(1));
+var_dump($rc->isInstance(1.5));
+var_dump($rc->isInstance(true));
+var_dump($rc->isInstance('X'));
+var_dump($rc->isInstance(null));
+
+?>
+--EXPECTF--
+Warning: ReflectionClass::isInstance() expects exactly 1 parameter, 0 given in %s on line 7
+NULL
+
+Warning: ReflectionClass::isInstance() expects exactly 1 parameter, 2 given in %s on line 8
+NULL
+
+Warning: ReflectionClass::isInstance() expects parameter 1 to be object, %s given in %s on line 9
+NULL
+
+Warning: ReflectionClass::isInstance() expects parameter 1 to be object, double given in %s on line 10
+NULL
+
+Warning: ReflectionClass::isInstance() expects parameter 1 to be object, boolean given in %s on line 11
+NULL
+
+Warning: ReflectionClass::isInstance() expects parameter 1 to be object, string given in %s on line 12
+NULL
+
+Warning: ReflectionClass::isInstance() expects parameter 1 to be object, null given in %s on line 13
+NULL
diff --git a/ext/reflection/tests/ReflectionClass_isInstantiable_basic.phpt b/ext/reflection/tests/ReflectionClass_isInstantiable_basic.phpt
new file mode 100644
index 0000000..6ebcfa9
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_isInstantiable_basic.phpt
@@ -0,0 +1,40 @@
+--TEST--
+ReflectionClass::IsInstantiable()
+--FILE--
+<?php
+class C {
+}
+
+interface iface {
+ function f1();
+}
+
+class ifaceImpl implements iface {
+ function f1() {}
+}
+
+abstract class abstractClass {
+ function f1() {}
+ abstract function f2();
+}
+
+class D extends abstractClass {
+ function f2() {}
+}
+
+$classes = array("C", "iface", "ifaceImpl", "abstractClass", "D");
+
+foreach($classes as $class ) {
+ $reflectionClass = new ReflectionClass($class);
+ echo "Is $class instantiable? ";
+ var_dump($reflectionClass->IsInstantiable());
+
+}
+
+?>
+--EXPECTF--
+Is C instantiable? bool(true)
+Is iface instantiable? bool(false)
+Is ifaceImpl instantiable? bool(true)
+Is abstractClass instantiable? bool(false)
+Is D instantiable? bool(true)
diff --git a/ext/reflection/tests/ReflectionClass_isInstantiable_error.phpt b/ext/reflection/tests/ReflectionClass_isInstantiable_error.phpt
new file mode 100644
index 0000000..52be239
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_isInstantiable_error.phpt
@@ -0,0 +1,19 @@
+--TEST--
+ReflectionClass::IsInstantiable()
+--FILE--
+<?php
+class privateCtorOld {
+ private function privateCtorOld() {}
+}
+$reflectionClass = new ReflectionClass("privateCtorOld");
+
+var_dump($reflectionClass->IsInstantiable('X'));
+var_dump($reflectionClass->IsInstantiable(0, null));
+
+?>
+--EXPECTF--
+Warning: ReflectionClass::isInstantiable() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionClass::isInstantiable() expects exactly 0 parameters, 2 given in %s on line %d
+NULL
diff --git a/ext/reflection/tests/ReflectionClass_isInstantiable_variation.phpt b/ext/reflection/tests/ReflectionClass_isInstantiable_variation.phpt
new file mode 100644
index 0000000..1cf3e61
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_isInstantiable_variation.phpt
@@ -0,0 +1,50 @@
+--TEST--
+ReflectionClass::IsInstantiable()
+--FILE--
+<?php
+class noCtor {
+}
+
+class publicCtorNew {
+ public function __construct() {}
+}
+
+class protectedCtorNew {
+ protected function __construct() {}
+}
+
+class privateCtorNew {
+ private function __construct() {}
+}
+
+class publicCtorOld {
+ public function publicCtorOld() {}
+}
+
+class protectedCtorOld {
+ protected function protectedCtorOld() {}
+}
+
+class privateCtorOld {
+ private function privateCtorOld() {}
+}
+
+
+$classes = array("noCtor", "publicCtorNew", "protectedCtorNew", "privateCtorNew",
+ "publicCtorOld", "protectedCtorOld", "privateCtorOld");
+
+foreach($classes as $class ) {
+ $reflectionClass = new ReflectionClass($class);
+ echo "Is $class instantiable? ";
+ var_dump($reflectionClass->IsInstantiable());
+}
+
+?>
+--EXPECTF--
+Is noCtor instantiable? bool(true)
+Is publicCtorNew instantiable? bool(true)
+Is protectedCtorNew instantiable? bool(false)
+Is privateCtorNew instantiable? bool(false)
+Is publicCtorOld instantiable? bool(true)
+Is protectedCtorOld instantiable? bool(false)
+Is privateCtorOld instantiable? bool(false)
diff --git a/ext/reflection/tests/ReflectionClass_isInterface_basic.phpt b/ext/reflection/tests/ReflectionClass_isInterface_basic.phpt
new file mode 100644
index 0000000..66c9ae7
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_isInterface_basic.phpt
@@ -0,0 +1,25 @@
+--TEST--
+ReflectionClass::isInterface() method
+--CREDITS--
+Felix De Vliegher <felix.devliegher@gmail.com>
+#testfest roosendaal on 2008-05-10
+--FILE--
+<?php
+
+interface TestInterface {}
+class TestClass {}
+interface DerivedInterface extends TestInterface {}
+
+$reflectionClass = new ReflectionClass('TestInterface');
+$reflectionClass2 = new ReflectionClass('TestClass');
+$reflectionClass3 = new ReflectionClass('DerivedInterface');
+
+var_dump($reflectionClass->isInterface());
+var_dump($reflectionClass2->isInterface());
+var_dump($reflectionClass3->isInterface());
+
+?>
+--EXPECT--
+bool(true)
+bool(false)
+bool(true)
diff --git a/ext/reflection/tests/ReflectionClass_isInternal_basic.phpt b/ext/reflection/tests/ReflectionClass_isInternal_basic.phpt
new file mode 100644
index 0000000..2eaacb6
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_isInternal_basic.phpt
@@ -0,0 +1,22 @@
+--TEST--
+ReflectionClass::isInternal()
+--FILE--
+<?php
+class C {
+}
+
+$r1 = new ReflectionClass("stdClass");
+$r2 = new ReflectionClass("ReflectionClass");
+$r3 = new ReflectionClass("ReflectionProperty");
+$r4 = new ReflectionClass("Exception");
+$r5 = new ReflectionClass("C");
+
+var_dump($r1->isInternal(), $r2->isInternal(), $r3->isInternal(),
+ $r4->isInternal(), $r5->isInternal());
+?>
+--EXPECTF--
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(false)
diff --git a/ext/reflection/tests/ReflectionClass_isInternal_error.phpt b/ext/reflection/tests/ReflectionClass_isInternal_error.phpt
new file mode 100644
index 0000000..ef69a4c
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_isInternal_error.phpt
@@ -0,0 +1,14 @@
+--TEST--
+ReflectionClass::isInternal() - invalid params
+--FILE--
+<?php
+$r1 = new ReflectionClass("stdClass");
+var_dump($r1->isInternal('X'));
+var_dump($r1->isInternal('X', true));
+?>
+--EXPECTF--
+Warning: ReflectionClass::isInternal() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionClass::isInternal() expects exactly 0 parameters, 2 given in %s on line %d
+NULL
diff --git a/ext/reflection/tests/ReflectionClass_isIterateable_001.phpt b/ext/reflection/tests/ReflectionClass_isIterateable_001.phpt
new file mode 100644
index 0000000..4936413
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_isIterateable_001.phpt
@@ -0,0 +1,89 @@
+--TEST--
+ReflectionClass::isIterateable()
+--CREDITS--
+Robin Fernandes <robinf@php.net>
+Steve Seear <stevseea@php.net>
+--FILE--
+<?php
+Interface ExtendsIterator extends Iterator {
+}
+Interface ExtendsIteratorAggregate extends IteratorAggregate {
+}
+Class IteratorImpl implements Iterator {
+ public function next() {}
+ public function key() {}
+ public function rewind() {}
+ public function current() {}
+ public function valid() {}
+}
+Class IterarorAggregateImpl implements IteratorAggregate {
+ public function getIterator() {}
+}
+Class ExtendsIteratorImpl extends IteratorImpl {
+}
+Class ExtendsIteratorAggregateImpl extends IterarorAggregateImpl {
+}
+Class A {
+}
+
+$classes = array('Traversable', 'Iterator', 'IteratorAggregate', 'ExtendsIterator', 'ExtendsIteratorAggregate',
+ 'IteratorImpl', 'IterarorAggregateImpl', 'ExtendsIteratorImpl', 'ExtendsIteratorAggregateImpl', 'A');
+
+foreach($classes as $class) {
+ $rc = new ReflectionClass($class);
+ echo "Is $class iterable? ";
+ var_dump($rc->isIterateable());
+}
+
+echo "\nTest invalid params:\n";
+$rc = new ReflectionClass('IteratorImpl');
+var_dump($rc->isIterateable(null));
+var_dump($rc->isIterateable(null, null));
+var_dump($rc->isIterateable(1));
+var_dump($rc->isIterateable(1.5));
+var_dump($rc->isIterateable(true));
+var_dump($rc->isIterateable('X'));
+var_dump($rc->isIterateable(null));
+
+echo "\nTest static invocation:\n";
+ReflectionClass::isIterateable();
+
+?>
+--EXPECTF--
+Is Traversable iterable? bool(false)
+Is Iterator iterable? bool(false)
+Is IteratorAggregate iterable? bool(false)
+Is ExtendsIterator iterable? bool(false)
+Is ExtendsIteratorAggregate iterable? bool(false)
+Is IteratorImpl iterable? bool(true)
+Is IterarorAggregateImpl iterable? bool(true)
+Is ExtendsIteratorImpl iterable? bool(true)
+Is ExtendsIteratorAggregateImpl iterable? bool(true)
+Is A iterable? bool(false)
+
+Test invalid params:
+
+Warning: ReflectionClass::isIterateable() expects exactly 0 parameters, 1 given in %s on line 34
+NULL
+
+Warning: ReflectionClass::isIterateable() expects exactly 0 parameters, 2 given in %s on line 35
+NULL
+
+Warning: ReflectionClass::isIterateable() expects exactly 0 parameters, 1 given in %s on line 36
+NULL
+
+Warning: ReflectionClass::isIterateable() expects exactly 0 parameters, 1 given in %s on line 37
+NULL
+
+Warning: ReflectionClass::isIterateable() expects exactly 0 parameters, 1 given in %s on line 38
+NULL
+
+Warning: ReflectionClass::isIterateable() expects exactly 0 parameters, 1 given in %s on line 39
+NULL
+
+Warning: ReflectionClass::isIterateable() expects exactly 0 parameters, 1 given in %s on line 40
+NULL
+
+Test static invocation:
+
+Fatal error: Non-static method ReflectionClass::isIterateable() cannot be called statically in %s on line 43 \ No newline at end of file
diff --git a/ext/reflection/tests/ReflectionClass_isIterateable_basic.phpt b/ext/reflection/tests/ReflectionClass_isIterateable_basic.phpt
new file mode 100644
index 0000000..8b65b9a
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_isIterateable_basic.phpt
@@ -0,0 +1,34 @@
+--TEST--
+ReflectionClass::isIterateable() basic
+--CREDITS--
+Felix De Vliegher <felix.devliegher@gmail.com>, Marc Veldman <marc@ibuildings.nl>
+--FILE--
+<?php
+
+class IteratorClass implements Iterator {
+ public function __construct() { }
+ public function key() {}
+ public function current() {}
+ function next() {}
+ function valid() {}
+ function rewind() {}
+}
+class DerivedClass extends IteratorClass {}
+class NonIterator {}
+
+function dump_iterateable($class) {
+ $reflection = new ReflectionClass($class);
+ var_dump($reflection->isIterateable());
+}
+
+$classes = array("ArrayObject", "IteratorClass", "DerivedClass", "NonIterator");
+foreach ($classes as $class) {
+ echo "Is $class iterateable? ";
+ dump_iterateable($class);
+}
+?>
+--EXPECT--
+Is ArrayObject iterateable? bool(true)
+Is IteratorClass iterateable? bool(true)
+Is DerivedClass iterateable? bool(true)
+Is NonIterator iterateable? bool(false)
diff --git a/ext/reflection/tests/ReflectionClass_isIterateable_variation1.phpt b/ext/reflection/tests/ReflectionClass_isIterateable_variation1.phpt
new file mode 100644
index 0000000..f6d0d53
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_isIterateable_variation1.phpt
@@ -0,0 +1,25 @@
+--TEST--
+ReflectionClass::isIterateable() variations
+--CREDITS--
+Felix De Vliegher <felix.devliegher@gmail.com>
+--FILE--
+<?php
+
+class BasicClass {}
+
+function dump_iterateable($obj)
+{
+ $reflection = new ReflectionClass($obj);
+ var_dump($reflection->isIterateable());
+}
+
+$basicClass = new BasicClass();
+$stdClass = new StdClass();
+
+dump_iterateable($basicClass);
+dump_iterateable($stdClass);
+
+?>
+--EXPECT--
+bool(false)
+bool(false)
diff --git a/ext/reflection/tests/ReflectionClass_isSubclassOf_002.phpt b/ext/reflection/tests/ReflectionClass_isSubclassOf_002.phpt
new file mode 100644
index 0000000..083b277
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_isSubclassOf_002.phpt
@@ -0,0 +1,49 @@
+--TEST--
+ReflectionObject::isSubclassOf() - bad arguments
+--CREDITS--
+Robin Fernandes <robinf@php.net>
+Steve Seear <stevseea@php.net>
+--FILE--
+<?php
+class A {}
+$rc = new ReflectionClass('A');
+
+echo "\n\nTest bad arguments:\n";
+try {
+ var_dump($rc->isSubclassOf());
+} catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+try {
+ var_dump($rc->isSubclassOf('C', 'C'));
+} catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+try {
+ var_dump($rc->isSubclassOf(null));
+} catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+try {
+ var_dump($rc->isSubclassOf('ThisClassDoesNotExist'));
+} catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+try {
+ var_dump($rc->isSubclassOf(2));
+} catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+?>
+--EXPECTF--
+
+Test bad arguments:
+
+Warning: ReflectionClass::isSubclassOf() expects exactly 1 parameter, 0 given in %s on line 7
+NULL
+
+Warning: ReflectionClass::isSubclassOf() expects exactly 1 parameter, 2 given in %s on line 12
+NULL
+Parameter one must either be a string or a ReflectionClass object
+Class ThisClassDoesNotExist does not exist
+Parameter one must either be a string or a ReflectionClass object \ No newline at end of file
diff --git a/ext/reflection/tests/ReflectionClass_isSubclassOf_basic.phpt b/ext/reflection/tests/ReflectionClass_isSubclassOf_basic.phpt
new file mode 100644
index 0000000..94fcf00
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_isSubclassOf_basic.phpt
@@ -0,0 +1,103 @@
+--TEST--
+ReflectionClass::isSubclassOf()
+--FILE--
+<?php
+class A {}
+class B extends A {}
+class C extends B {}
+
+interface I {}
+class X implements I {}
+
+$classNames = array('A', 'B', 'C', 'I', 'X');
+
+foreach ($classNames as $className) {
+ $rcs[$className] = new ReflectionClass($className);
+}
+
+foreach ($rcs as $childName => $child) {
+ foreach ($rcs as $parentName => $parent) {
+ echo "Is " . $childName . " a subclass of " . $parentName . "? \n";
+ echo " - Using object argument: ";
+ var_dump($child->isSubclassOf($parent));
+ echo " - Using string argument: ";
+ var_dump($child->isSubclassOf($parentName));
+ }
+}
+?>
+--EXPECTF--
+Is A a subclass of A?
+ - Using object argument: bool(false)
+ - Using string argument: bool(false)
+Is A a subclass of B?
+ - Using object argument: bool(false)
+ - Using string argument: bool(false)
+Is A a subclass of C?
+ - Using object argument: bool(false)
+ - Using string argument: bool(false)
+Is A a subclass of I?
+ - Using object argument: bool(false)
+ - Using string argument: bool(false)
+Is A a subclass of X?
+ - Using object argument: bool(false)
+ - Using string argument: bool(false)
+Is B a subclass of A?
+ - Using object argument: bool(true)
+ - Using string argument: bool(true)
+Is B a subclass of B?
+ - Using object argument: bool(false)
+ - Using string argument: bool(false)
+Is B a subclass of C?
+ - Using object argument: bool(false)
+ - Using string argument: bool(false)
+Is B a subclass of I?
+ - Using object argument: bool(false)
+ - Using string argument: bool(false)
+Is B a subclass of X?
+ - Using object argument: bool(false)
+ - Using string argument: bool(false)
+Is C a subclass of A?
+ - Using object argument: bool(true)
+ - Using string argument: bool(true)
+Is C a subclass of B?
+ - Using object argument: bool(true)
+ - Using string argument: bool(true)
+Is C a subclass of C?
+ - Using object argument: bool(false)
+ - Using string argument: bool(false)
+Is C a subclass of I?
+ - Using object argument: bool(false)
+ - Using string argument: bool(false)
+Is C a subclass of X?
+ - Using object argument: bool(false)
+ - Using string argument: bool(false)
+Is I a subclass of A?
+ - Using object argument: bool(false)
+ - Using string argument: bool(false)
+Is I a subclass of B?
+ - Using object argument: bool(false)
+ - Using string argument: bool(false)
+Is I a subclass of C?
+ - Using object argument: bool(false)
+ - Using string argument: bool(false)
+Is I a subclass of I?
+ - Using object argument: bool(false)
+ - Using string argument: bool(false)
+Is I a subclass of X?
+ - Using object argument: bool(false)
+ - Using string argument: bool(false)
+Is X a subclass of A?
+ - Using object argument: bool(false)
+ - Using string argument: bool(false)
+Is X a subclass of B?
+ - Using object argument: bool(false)
+ - Using string argument: bool(false)
+Is X a subclass of C?
+ - Using object argument: bool(false)
+ - Using string argument: bool(false)
+Is X a subclass of I?
+ - Using object argument: bool(true)
+ - Using string argument: bool(true)
+Is X a subclass of X?
+ - Using object argument: bool(false)
+ - Using string argument: bool(false)
diff --git a/ext/reflection/tests/ReflectionClass_isSubclassOf_error.phpt b/ext/reflection/tests/ReflectionClass_isSubclassOf_error.phpt
new file mode 100644
index 0000000..7d929fa
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_isSubclassOf_error.phpt
@@ -0,0 +1,17 @@
+--TEST--
+ReflectionClass::isSubclassOf() - invalid number of parameters
+--FILE--
+<?php
+class A {}
+$rc = new ReflectionClass('A');
+
+var_dump($rc->isSubclassOf());
+var_dump($rc->isSubclassOf('A',5));
+
+?>
+--EXPECTF--
+Warning: ReflectionClass::isSubclassOf() expects exactly 1 parameter, 0 given in %s on line 5
+NULL
+
+Warning: ReflectionClass::isSubclassOf() expects exactly 1 parameter, 2 given in %s on line 6
+NULL
diff --git a/ext/reflection/tests/ReflectionClass_isSubclassOf_error1.phpt b/ext/reflection/tests/ReflectionClass_isSubclassOf_error1.phpt
new file mode 100644
index 0000000..2fabd02
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_isSubclassOf_error1.phpt
@@ -0,0 +1,16 @@
+--TEST--
+ReflectionClass::isSubclassOf() - non-existent class error
+--FILE--
+<?php
+class A {}
+$rc = new ReflectionClass('A');
+
+var_dump($rc->isSubclassOf('X'));
+
+?>
+--EXPECTF--
+Fatal error: Uncaught exception 'ReflectionException' with message 'Class X does not exist' in %s:5
+Stack trace:
+#0 %s(5): ReflectionClass->isSubclassOf('X')
+#1 {main}
+ thrown in %s on line 5
diff --git a/ext/reflection/tests/ReflectionClass_isUserDefined_basic.phpt b/ext/reflection/tests/ReflectionClass_isUserDefined_basic.phpt
new file mode 100644
index 0000000..af43fce
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_isUserDefined_basic.phpt
@@ -0,0 +1,22 @@
+--TEST--
+ReflectionClass::isUserDefined()
+--FILE--
+<?php
+class C {
+}
+
+$r1 = new ReflectionClass("stdClass");
+$r2 = new ReflectionClass("ReflectionClass");
+$r3 = new ReflectionClass("ReflectionProperty");
+$r4 = new ReflectionClass("Exception");
+$r5 = new ReflectionClass("C");
+
+var_dump($r1->isUserDefined(), $r2->isUserDefined(), $r3->isUserDefined(),
+ $r4->isUserDefined(), $r5->isUserDefined());
+?>
+--EXPECTF--
+bool(false)
+bool(false)
+bool(false)
+bool(false)
+bool(true)
diff --git a/ext/reflection/tests/ReflectionClass_isUserDefined_error.phpt b/ext/reflection/tests/ReflectionClass_isUserDefined_error.phpt
new file mode 100644
index 0000000..ac88884
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_isUserDefined_error.phpt
@@ -0,0 +1,14 @@
+--TEST--
+ReflectionClass::isUserDefined() - invalid params.
+--FILE--
+<?php
+$r1 = new ReflectionClass("stdClass");
+var_dump($r1->isUserDefined('X'));
+var_dump($r1->isUserDefined('X', true));
+?>
+--EXPECTF--
+Warning: ReflectionClass::isUserDefined() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionClass::isUserDefined() expects exactly 0 parameters, 2 given in %s on line %d
+NULL
diff --git a/ext/reflection/tests/ReflectionClass_modifiers_001.phpt b/ext/reflection/tests/ReflectionClass_modifiers_001.phpt
new file mode 100644
index 0000000..941bfe5
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_modifiers_001.phpt
@@ -0,0 +1,44 @@
+--TEST--
+Modifiers
+--CREDITS--
+Robin Fernandes <robinf@php.net>
+Steve Seear <stevseea@php.net>
+--FILE--
+<?php
+abstract class A {}
+class B extends A {}
+class C {}
+final class D {}
+interface I {}
+
+$classes = array("A", "B", "C", "D", "I");
+
+foreach ($classes as $class) {
+ $rc = new ReflectionClass($class);
+ var_dump($rc->isFinal());
+ var_dump($rc->isInterface());
+ var_dump($rc->isAbstract());
+ var_dump($rc->getModifiers());
+}
+?>
+--EXPECTF--
+bool(false)
+bool(false)
+bool(true)
+int(32)
+bool(false)
+bool(false)
+bool(false)
+int(0)
+bool(false)
+bool(false)
+bool(false)
+int(0)
+bool(true)
+bool(false)
+bool(false)
+int(64)
+bool(false)
+bool(true)
+bool(false)
+int(128) \ No newline at end of file
diff --git a/ext/reflection/tests/ReflectionClass_modifiers_002.phpt b/ext/reflection/tests/ReflectionClass_modifiers_002.phpt
new file mode 100644
index 0000000..a3a567c
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_modifiers_002.phpt
@@ -0,0 +1,27 @@
+--TEST--
+Modifiers - wrong param count
+--CREDITS--
+Robin Fernandes <robinf@php.net>
+Steve Seear <stevseea@php.net>
+--FILE--
+<?php
+class C {}
+$rc = new ReflectionClass("C");
+var_dump($rc->isFinal('X'));
+var_dump($rc->isInterface(null));
+var_dump($rc->isAbstract(true));
+var_dump($rc->getModifiers(array(1,2,3)));
+
+?>
+--EXPECTF--
+Warning: ReflectionClass::isFinal() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionClass::isInterface() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionClass::isAbstract() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionClass::getModifiers() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
diff --git a/ext/reflection/tests/ReflectionClass_newInstanceArgs_001.phpt b/ext/reflection/tests/ReflectionClass_newInstanceArgs_001.phpt
new file mode 100644
index 0000000..981d675
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_newInstanceArgs_001.phpt
@@ -0,0 +1,98 @@
+--TEST--
+ReflectionClass::newInstanceArgs
+--CREDITS--
+Robin Fernandes <robinf@php.net>
+Steve Seear <stevseea@php.net>
+--FILE--
+<?php
+class A {
+ public function A() {
+ echo "In constructor of class A\n";
+ }
+}
+
+class B {
+ public function __construct($a, $b) {
+ echo "In constructor of class B with args $a, $b\n";
+ }
+}
+
+class C {
+ protected function __construct() {
+ echo "In constructor of class C\n";
+ }
+}
+
+class D {
+ private function __construct() {
+ echo "In constructor of class D\n";
+ }
+}
+class E {
+}
+
+
+$rcA = new ReflectionClass('A');
+$rcB = new ReflectionClass('B');
+$rcC = new ReflectionClass('C');
+$rcD = new ReflectionClass('D');
+$rcE = new ReflectionClass('E');
+
+$a1 = $rcA->newInstanceArgs();
+$a2 = $rcA->newInstanceArgs(array('x'));
+var_dump($a1, $a2);
+
+$b1 = $rcB->newInstanceArgs();
+$b2 = $rcB->newInstanceArgs(array('x', 123));
+var_dump($b1, $b2);
+
+try {
+ $rcC->newInstanceArgs();
+ echo "you should not see this\n";
+} catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+
+try {
+ $rcD->newInstanceArgs();
+ echo "you should not see this\n";
+} catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+
+$e1 = $rcE->newInstanceArgs();
+var_dump($e1);
+
+try {
+ $e2 = $rcE->newInstanceArgs(array('x'));
+ echo "you should not see this\n";
+} catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+?>
+--EXPECTF--
+In constructor of class A
+In constructor of class A
+object(A)#%d (0) {
+}
+object(A)#%d (0) {
+}
+
+Warning: Missing argument 1 for B::__construct() in %s on line 9
+
+Warning: Missing argument 2 for B::__construct() in %s on line 9
+
+Notice: Undefined variable: a in %s on line 10
+
+Notice: Undefined variable: b in %s on line 10
+In constructor of class B with args ,
+In constructor of class B with args x, 123
+object(B)#%d (0) {
+}
+object(B)#%d (0) {
+}
+Access to non-public constructor of class C
+Access to non-public constructor of class D
+object(E)#%d (0) {
+}
+Class E does not have a constructor, so you cannot pass any constructor arguments \ No newline at end of file
diff --git a/ext/reflection/tests/ReflectionClass_newInstanceArgs_002.phpt b/ext/reflection/tests/ReflectionClass_newInstanceArgs_002.phpt
new file mode 100644
index 0000000..dd6f438
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_newInstanceArgs_002.phpt
@@ -0,0 +1,20 @@
+--TEST--
+ReflectionClass::newInstanceArgs() - wrong arg type
+--CREDITS--
+Robin Fernandes <robinf@php.net>
+Steve Seear <stevseea@php.net>
+--FILE--
+<?php
+class A {
+ public function __construct($a, $b) {
+ echo "In constructor of class B with arg $a\n";
+ }
+}
+$rc = new ReflectionClass('A');
+$a = $rc->newInstanceArgs('x');
+var_dump($a);
+
+?>
+--EXPECTF--
+
+Catchable fatal error: Argument 1 passed to ReflectionClass::newInstanceArgs() must be of the type array, string given in %s on line 8
diff --git a/ext/reflection/tests/ReflectionClass_newInstanceWithoutConstructor.phpt b/ext/reflection/tests/ReflectionClass_newInstanceWithoutConstructor.phpt
new file mode 100644
index 0000000..1932dbf
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_newInstanceWithoutConstructor.phpt
@@ -0,0 +1,33 @@
+--TEST--
+ReflectionClass::newInstanceWithoutConstructor()
+--CREDITS--
+Sebastian Bergmann <sebastian@php.net>
+--FILE--
+<?php
+class Foo
+{
+ public function __construct()
+ {
+ print __METHOD__;
+ }
+}
+
+$class = new ReflectionClass('Foo');
+var_dump($class->newInstanceWithoutConstructor());
+
+$class = new ReflectionClass('StdClass');
+var_dump($class->newInstanceWithoutConstructor());
+
+$class = new ReflectionClass('DateTime');
+var_dump($class->newInstanceWithoutConstructor());
+--EXPECTF--
+object(Foo)#%d (0) {
+}
+object(stdClass)#%d (0) {
+}
+
+Fatal error: Uncaught exception 'ReflectionException' with message 'Class DateTime is an internal class that cannot be instantiated without invoking its constructor' in %sReflectionClass_newInstanceWithoutConstructor.php:%d
+Stack trace:
+#0 %sReflectionClass_newInstanceWithoutConstructor.php(%d): ReflectionClass->newInstanceWithoutConstructor()
+#1 {main}
+ thrown in %sReflectionClass_newInstanceWithoutConstructor.php on line %d
diff --git a/ext/reflection/tests/ReflectionClass_newInstance_001.phpt b/ext/reflection/tests/ReflectionClass_newInstance_001.phpt
new file mode 100644
index 0000000..3cdb5d7
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_newInstance_001.phpt
@@ -0,0 +1,98 @@
+--TEST--
+ReflectionClass::newInstance()
+--CREDITS--
+Robin Fernandes <robinf@php.net>
+Steve Seear <stevseea@php.net>
+--FILE--
+<?php
+class A {
+ public function A() {
+ echo "In constructor of class A\n";
+ }
+}
+
+class B {
+ public function __construct($a, $b) {
+ echo "In constructor of class B with args $a, $b\n";
+ }
+}
+
+class C {
+ protected function __construct() {
+ echo "In constructor of class C\n";
+ }
+}
+
+class D {
+ private function __construct() {
+ echo "In constructor of class D\n";
+ }
+}
+class E {
+}
+
+
+$rcA = new ReflectionClass('A');
+$rcB = new ReflectionClass('B');
+$rcC = new ReflectionClass('C');
+$rcD = new ReflectionClass('D');
+$rcE = new ReflectionClass('E');
+
+$a1 = $rcA->newInstance();
+$a2 = $rcA->newInstance('x');
+var_dump($a1, $a2);
+
+$b1 = $rcB->newInstance();
+$b2 = $rcB->newInstance('x', 123);
+var_dump($b1, $b2);
+
+try {
+ $rcC->newInstance();
+ echo "you should not see this\n";
+} catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+
+try {
+ $rcD->newInstance();
+ echo "you should not see this\n";
+} catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+
+$e1 = $rcE->newInstance();
+var_dump($e1);
+
+try {
+ $e2 = $rcE->newInstance('x');
+ echo "you should not see this\n";
+} catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+?>
+--EXPECTF--
+In constructor of class A
+In constructor of class A
+object(A)#%d (0) {
+}
+object(A)#%d (0) {
+}
+
+Warning: Missing argument 1 for B::__construct() in %s on line 9
+
+Warning: Missing argument 2 for B::__construct() in %s on line 9
+
+Notice: Undefined variable: a in %s on line 10
+
+Notice: Undefined variable: b in %s on line 10
+In constructor of class B with args ,
+In constructor of class B with args x, 123
+object(B)#%d (0) {
+}
+object(B)#%d (0) {
+}
+Access to non-public constructor of class C
+Access to non-public constructor of class D
+object(E)#%d (0) {
+}
+Class E does not have a constructor, so you cannot pass any constructor arguments \ No newline at end of file
diff --git a/ext/reflection/tests/ReflectionClass_setStaticPropertyValue_001.phpt b/ext/reflection/tests/ReflectionClass_setStaticPropertyValue_001.phpt
new file mode 100644
index 0000000..9e8f01e
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_setStaticPropertyValue_001.phpt
@@ -0,0 +1,79 @@
+--TEST--
+ReflectionClass::setStaticPropertyValue()
+--CREDITS--
+Robin Fernandes <robinf@php.net>
+Steve Seear <stevseea@php.net>
+--SKIPIF--
+<?php if (version_compare(zend_version(), '2.4.0', '>=')) die('skip ZendEngine 2.3 or below needed'); ?>
+--FILE--
+<?php
+class A {
+ static private $privateOverridden = "original private";
+ static protected $protectedOverridden = "original protected";
+ static public $publicOverridden = "original public";
+}
+
+class B extends A {
+ static private $privateOverridden = "changed private";
+ static protected $protectedOverridden = "changed protected";
+ static public $publicOverridden = "changed public";
+}
+
+echo "Set static values in A:\n";
+$rcA = new ReflectionClass('A');
+$rcA->setStaticPropertyValue("\0A\0privateOverridden", "new value 1");
+$rcA->setStaticPropertyValue("\0*\0protectedOverridden", "new value 2");
+$rcA->setStaticPropertyValue("publicOverridden", "new value 3");
+print_r($rcA->getStaticProperties());
+
+echo "\nSet static values in B:\n";
+$rcB = new ReflectionClass('B');
+$rcB->setStaticPropertyValue("\0A\0privateOverridden", "new value 4");
+$rcB->setStaticPropertyValue("\0B\0privateOverridden", "new value 5");
+$rcB->setStaticPropertyValue("\0*\0protectedOverridden", "new value 6");
+$rcB->setStaticPropertyValue("publicOverridden", "new value 7");
+print_r($rcA->getStaticProperties());
+print_r($rcB->getStaticProperties());
+
+echo "\nSet non-existent values from A with no default value:\n";
+try {
+ var_dump($rcA->setStaticPropertyValue("protectedOverridden", "new value 8"));
+ echo "you should not see this";
+} catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+
+try {
+ var_dump($rcA->setStaticPropertyValue("privateOverridden", "new value 9"));
+ echo "you should not see this";
+} catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+
+?>
+--EXPECTF--
+Set static values in A:
+Array
+(
+ [privateOverridden] => new value 1
+ [protectedOverridden] => new value 2
+ [publicOverridden] => new value 3
+)
+
+Set static values in B:
+Array
+(
+ [privateOverridden] => new value 4
+ [protectedOverridden] => new value 2
+ [publicOverridden] => new value 3
+)
+Array
+(
+ [privateOverridden] => new value 5
+ [protectedOverridden] => new value 6
+ [publicOverridden] => new value 7
+)
+
+Set non-existent values from A with no default value:
+Class A does not have a property named protectedOverridden
+Class A does not have a property named privateOverridden
diff --git a/ext/reflection/tests/ReflectionClass_setStaticPropertyValue_001_2_4.phpt b/ext/reflection/tests/ReflectionClass_setStaticPropertyValue_001_2_4.phpt
new file mode 100644
index 0000000..1092f65
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_setStaticPropertyValue_001_2_4.phpt
@@ -0,0 +1,61 @@
+--TEST--
+ReflectionClass::setStaticPropertyValue()
+--CREDITS--
+Robin Fernandes <robinf@php.net>
+Steve Seear <stevseea@php.net>
+--SKIPIF--
+<?php if (version_compare(zend_version(), '2.4.0', '<')) die('skip ZendEngine 2.4 needed'); ?>
+--FILE--
+<?php
+class A {
+ static private $privateOverridden = "original private";
+ static protected $protectedOverridden = "original protected";
+ static public $publicOverridden = "original public";
+}
+
+class B extends A {
+ static private $privateOverridden = "changed private";
+ static protected $protectedOverridden = "changed protected";
+ static public $publicOverridden = "changed public";
+}
+
+echo "Set static values in A:\n";
+$rcA = new ReflectionClass('A');
+$rcA->setStaticPropertyValue("\0A\0privateOverridden", "new value 1");
+$rcA->setStaticPropertyValue("\0*\0protectedOverridden", "new value 2");
+$rcA->setStaticPropertyValue("publicOverridden", "new value 3");
+print_r($rcA->getStaticProperties());
+
+echo "\nSet static values in B:\n";
+$rcB = new ReflectionClass('B');
+$rcB->setStaticPropertyValue("\0A\0privateOverridden", "new value 4");
+$rcB->setStaticPropertyValue("\0B\0privateOverridden", "new value 5");
+$rcB->setStaticPropertyValue("\0*\0protectedOverridden", "new value 6");
+$rcB->setStaticPropertyValue("publicOverridden", "new value 7");
+print_r($rcA->getStaticProperties());
+print_r($rcB->getStaticProperties());
+
+echo "\nSet non-existent values from A with no default value:\n";
+try {
+ var_dump($rcA->setStaticPropertyValue("protectedOverridden", "new value 8"));
+ echo "you should not see this";
+} catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+
+try {
+ var_dump($rcA->setStaticPropertyValue("privateOverridden", "new value 9"));
+ echo "you should not see this";
+} catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+
+?>
+--EXPECTF--
+Set static values in A:
+
+Fatal error: Uncaught exception 'ReflectionException' with message 'Class A does not have a property named ' in %sReflectionClass_setStaticPropertyValue_001_2_4.php:%d
+Stack trace:
+#0 %sReflectionClass_setStaticPropertyValue_001_2_4.php(%d): ReflectionClass->setStaticPropertyValue('?A?privateOverr...', 'new value 1')
+#1 {main}
+ thrown in %sReflectionClass_setStaticPropertyValue_001_2_4.php on line %d
diff --git a/ext/reflection/tests/ReflectionClass_setStaticPropertyValue_002.phpt b/ext/reflection/tests/ReflectionClass_setStaticPropertyValue_002.phpt
new file mode 100644
index 0000000..3244ec3
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_setStaticPropertyValue_002.phpt
@@ -0,0 +1,60 @@
+--TEST--
+ReflectionClass::getStaticPropertyValue() - bad params
+--CREDITS--
+Robin Fernandes <robinf@php.net>
+Steve Seear <stevseea@php.net>
+--FILE--
+<?php
+class C {
+ public static $x;
+}
+
+$rc = new ReflectionClass('C');
+try {
+ var_dump($rc->setStaticPropertyValue("x", "default value", 'blah'));
+} catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+try {
+ var_dump($rc->setStaticPropertyValue());
+} catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+try {
+ var_dump($rc->setStaticPropertyValue(null));
+} catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+try {
+ var_dump($rc->setStaticPropertyValue(null,null));
+} catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+try {
+ var_dump($rc->setStaticPropertyValue(1.5, 'def'));
+} catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+try {
+ var_dump($rc->setStaticPropertyValue(array(1,2,3), 'blah'));
+} catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+
+
+?>
+--EXPECTF--
+
+Warning: ReflectionClass::setStaticPropertyValue() expects exactly 2 parameters, 3 given in %s on line 8
+NULL
+
+Warning: ReflectionClass::setStaticPropertyValue() expects exactly 2 parameters, 0 given in %s on line 13
+NULL
+
+Warning: ReflectionClass::setStaticPropertyValue() expects exactly 2 parameters, 1 given in %s on line 18
+NULL
+Class C does not have a property named
+Class C does not have a property named 1.5
+
+Warning: ReflectionClass::setStaticPropertyValue() expects parameter 1 to be string, array given in %s on line 33
+NULL \ No newline at end of file
diff --git a/ext/reflection/tests/ReflectionClass_toString_001.phpt b/ext/reflection/tests/ReflectionClass_toString_001.phpt
new file mode 100644
index 0000000..508530a
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_toString_001.phpt
@@ -0,0 +1,350 @@
+--TEST--
+ReflectionClass::__toString()
+--CREDITS--
+Robin Fernandes <robinf@php.net>
+Steve Seear <stevseea@php.net>
+--FILE--
+<?php
+$rc = new ReflectionClass("ReflectionClass");
+echo $rc;
+?>
+--EXPECTF--
+Class [ <internal:Reflection> class ReflectionClass implements Reflector ] {
+
+ - Constants [3] {
+ Constant [ integer IS_IMPLICIT_ABSTRACT ] { 16 }
+ Constant [ integer IS_EXPLICIT_ABSTRACT ] { 32 }
+ Constant [ integer IS_FINAL ] { 64 }
+ }
+
+ - Static properties [0] {
+ }
+
+ - Static methods [1] {
+ Method [ <internal:Reflection> static public method export ] {
+
+ - Parameters [2] {
+ Parameter #0 [ <required> $argument ]
+ Parameter #1 [ <optional> $return ]
+ }
+ }
+ }
+
+ - Properties [1] {
+ Property [ <default> public $name ]
+ }
+
+ - Methods [49] {
+ Method [ <internal:Reflection> final private method __clone ] {
+
+ - Parameters [0] {
+ }
+ }
+
+ Method [ <internal:Reflection, ctor> public method __construct ] {
+
+ - Parameters [1] {
+ Parameter #0 [ <required> $argument ]
+ }
+ }
+
+ Method [ <internal:Reflection> public method __toString ] {
+
+ - Parameters [0] {
+ }
+ }
+
+ Method [ <internal:Reflection> public method getName ] {
+
+ - Parameters [0] {
+ }
+ }
+
+ Method [ <internal:Reflection> public method isInternal ] {
+
+ - Parameters [0] {
+ }
+ }
+
+ Method [ <internal:Reflection> public method isUserDefined ] {
+
+ - Parameters [0] {
+ }
+ }
+
+ Method [ <internal:Reflection> public method isInstantiable ] {
+
+ - Parameters [0] {
+ }
+ }
+
+ Method [ <internal:Reflection> public method isCloneable ] {
+
+ - Parameters [0] {
+ }
+ }
+
+ Method [ <internal:Reflection> public method getFileName ] {
+
+ - Parameters [0] {
+ }
+ }
+
+ Method [ <internal:Reflection> public method getStartLine ] {
+
+ - Parameters [0] {
+ }
+ }
+
+ Method [ <internal:Reflection> public method getEndLine ] {
+
+ - Parameters [0] {
+ }
+ }
+
+ Method [ <internal:Reflection> public method getDocComment ] {
+
+ - Parameters [0] {
+ }
+ }
+
+ Method [ <internal:Reflection> public method getConstructor ] {
+
+ - Parameters [0] {
+ }
+ }
+
+ Method [ <internal:Reflection> public method hasMethod ] {
+
+ - Parameters [1] {
+ Parameter #0 [ <required> $name ]
+ }
+ }
+
+ Method [ <internal:Reflection> public method getMethod ] {
+
+ - Parameters [1] {
+ Parameter #0 [ <required> $name ]
+ }
+ }
+
+ Method [ <internal:Reflection> public method getMethods ] {
+
+ - Parameters [1] {
+ Parameter #0 [ <optional> $filter ]
+ }
+ }
+
+ Method [ <internal:Reflection> public method hasProperty ] {
+
+ - Parameters [1] {
+ Parameter #0 [ <required> $name ]
+ }
+ }
+
+ Method [ <internal:Reflection> public method getProperty ] {
+
+ - Parameters [1] {
+ Parameter #0 [ <required> $name ]
+ }
+ }
+
+ Method [ <internal:Reflection> public method getProperties ] {
+
+ - Parameters [1] {
+ Parameter #0 [ <optional> $filter ]
+ }
+ }
+
+ Method [ <internal:Reflection> public method hasConstant ] {
+
+ - Parameters [1] {
+ Parameter #0 [ <required> $name ]
+ }
+ }
+
+ Method [ <internal:Reflection> public method getConstants ] {
+
+ - Parameters [0] {
+ }
+ }
+
+ Method [ <internal:Reflection> public method getConstant ] {
+
+ - Parameters [1] {
+ Parameter #0 [ <required> $name ]
+ }
+ }
+
+ Method [ <internal:Reflection> public method getInterfaces ] {
+
+ - Parameters [0] {
+ }
+ }
+
+ Method [ <internal:Reflection> public method getInterfaceNames ] {
+
+ - Parameters [0] {
+ }
+ }
+
+ Method [ <internal:Reflection> public method isInterface ] {
+
+ - Parameters [0] {
+ }
+ }
+
+ Method [ <internal:Reflection> public method getTraits ] {
+
+ - Parameters [0] {
+ }
+ }
+
+ Method [ <internal:Reflection> public method getTraitNames ] {
+
+ - Parameters [0] {
+ }
+ }
+
+ Method [ <internal:Reflection> public method getTraitAliases ] {
+
+ - Parameters [0] {
+ }
+ }
+
+ Method [ <internal:Reflection> public method isTrait ] {
+
+ - Parameters [0] {
+ }
+ }
+
+ Method [ <internal:Reflection> public method isAbstract ] {
+
+ - Parameters [0] {
+ }
+ }
+
+ Method [ <internal:Reflection> public method isFinal ] {
+
+ - Parameters [0] {
+ }
+ }
+
+ Method [ <internal:Reflection> public method getModifiers ] {
+
+ - Parameters [0] {
+ }
+ }
+
+ Method [ <internal:Reflection> public method isInstance ] {
+
+ - Parameters [1] {
+ Parameter #0 [ <required> $object ]
+ }
+ }
+
+ Method [ <internal:Reflection> public method newInstance ] {
+
+ - Parameters [1] {
+ Parameter #0 [ <required> $args ]
+ }
+ }
+
+ Method [ <internal:Reflection> public method newInstanceWithoutConstructor ] {
+
+ - Parameters [0] {
+ }
+ }
+
+ Method [ <internal:Reflection> public method newInstanceArgs ] {
+
+ - Parameters [1] {
+ Parameter #0 [ <optional> array $args ]
+ }
+ }
+
+ Method [ <internal:Reflection> public method getParentClass ] {
+
+ - Parameters [0] {
+ }
+ }
+
+ Method [ <internal:Reflection> public method isSubclassOf ] {
+
+ - Parameters [1] {
+ Parameter #0 [ <required> $class ]
+ }
+ }
+
+ Method [ <internal:Reflection> public method getStaticProperties ] {
+
+ - Parameters [0] {
+ }
+ }
+
+ Method [ <internal:Reflection> public method getStaticPropertyValue ] {
+
+ - Parameters [2] {
+ Parameter #0 [ <required> $name ]
+ Parameter #1 [ <optional> $default ]
+ }
+ }
+
+ Method [ <internal:Reflection> public method setStaticPropertyValue ] {
+
+ - Parameters [2] {
+ Parameter #0 [ <required> $name ]
+ Parameter #1 [ <required> $value ]
+ }
+ }
+
+ Method [ <internal:Reflection> public method getDefaultProperties ] {
+
+ - Parameters [0] {
+ }
+ }
+
+ Method [ <internal:Reflection> public method isIterateable ] {
+
+ - Parameters [0] {
+ }
+ }
+
+ Method [ <internal:Reflection> public method implementsInterface ] {
+
+ - Parameters [1] {
+ Parameter #0 [ <required> $interface ]
+ }
+ }
+
+ Method [ <internal:Reflection> public method getExtension ] {
+
+ - Parameters [0] {
+ }
+ }
+
+ Method [ <internal:Reflection> public method getExtensionName ] {
+
+ - Parameters [0] {
+ }
+ }
+
+ Method [ <internal:Reflection> public method inNamespace ] {
+
+ - Parameters [0] {
+ }
+ }
+
+ Method [ <internal:Reflection> public method getNamespaceName ] {
+
+ - Parameters [0] {
+ }
+ }
+
+ Method [ <internal:Reflection> public method getShortName ] {
+
+ - Parameters [0] {
+ }
+ }
+ }
+}
diff --git a/ext/reflection/tests/ReflectionClass_toString_002.phpt b/ext/reflection/tests/ReflectionClass_toString_002.phpt
new file mode 100644
index 0000000..e9aaa50
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_toString_002.phpt
@@ -0,0 +1,123 @@
+--TEST--
+ReflectionClass::__toString() - verify 'inherits', 'overwrites' and 'prototype' parts of method representation
+--CREDITS--
+Robin Fernandes <robinf@php.net>
+Steve Seear <stevseea@php.net>
+--FILE--
+<?php
+Class A {
+ function f() {}
+}
+Class B extends A {
+ function f() {}
+}
+Class C extends B {
+
+}
+Class D extends C {
+ function f() {}
+}
+foreach (array('A', 'B', 'C', 'D') as $class) {
+ echo "\n\n----( Reflection class $class: )----\n";
+ $rc = new ReflectionClass($class);
+ echo $rc;
+}
+
+?>
+--EXPECTF--
+
+
+----( Reflection class A: )----
+Class [ <user> class A ] {
+ @@ %s 2-4
+
+ - Constants [0] {
+ }
+
+ - Static properties [0] {
+ }
+
+ - Static methods [0] {
+ }
+
+ - Properties [0] {
+ }
+
+ - Methods [1] {
+ Method [ <user> public method f ] {
+ @@ %s 3 - 3
+ }
+ }
+}
+
+
+----( Reflection class B: )----
+Class [ <user> class B extends A ] {
+ @@ %s 5-7
+
+ - Constants [0] {
+ }
+
+ - Static properties [0] {
+ }
+
+ - Static methods [0] {
+ }
+
+ - Properties [0] {
+ }
+
+ - Methods [1] {
+ Method [ <user, overwrites A, prototype A> public method f ] {
+ @@ %s 6 - 6
+ }
+ }
+}
+
+
+----( Reflection class C: )----
+Class [ <user> class C extends B ] {
+ @@ %s 8-10
+
+ - Constants [0] {
+ }
+
+ - Static properties [0] {
+ }
+
+ - Static methods [0] {
+ }
+
+ - Properties [0] {
+ }
+
+ - Methods [1] {
+ Method [ <user, inherits B, prototype A> public method f ] {
+ @@ %s 6 - 6
+ }
+ }
+}
+
+
+----( Reflection class D: )----
+Class [ <user> class D extends C ] {
+ @@ %s 11-13
+
+ - Constants [0] {
+ }
+
+ - Static properties [0] {
+ }
+
+ - Static methods [0] {
+ }
+
+ - Properties [0] {
+ }
+
+ - Methods [1] {
+ Method [ <user, overwrites B, prototype A> public method f ] {
+ @@ %s 12 - 12
+ }
+ }
+} \ No newline at end of file
diff --git a/ext/reflection/tests/ReflectionClass_toString_003.phpt b/ext/reflection/tests/ReflectionClass_toString_003.phpt
new file mode 100644
index 0000000..ce5afb0
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_toString_003.phpt
@@ -0,0 +1,120 @@
+--TEST--
+ReflectionClass::__toString() - verify 'inherits', 'overwrites' and 'prototype' parts of method representation with private methods
+--CREDITS--
+Robin Fernandes <robinf@php.net>
+Steve Seear <stevseea@php.net>
+--FILE--
+<?php
+Class A {
+ private function f() {}
+}
+Class B extends A {
+ private function f() {}
+}
+Class C extends B {
+
+}
+Class D extends C {
+ private function f() {}
+}
+foreach (array('A', 'B', 'C', 'D') as $class) {
+ echo "\n\n----( Reflection class $class: )----\n";
+ $rc = new ReflectionClass($class);
+ echo $rc;
+}
+
+?>
+--EXPECTF--
+
+
+----( Reflection class A: )----
+Class [ <user> class A ] {
+ @@ %s 2-4
+
+ - Constants [0] {
+ }
+
+ - Static properties [0] {
+ }
+
+ - Static methods [0] {
+ }
+
+ - Properties [0] {
+ }
+
+ - Methods [1] {
+ Method [ <user> private method f ] {
+ @@ %s 3 - 3
+ }
+ }
+}
+
+
+----( Reflection class B: )----
+Class [ <user> class B extends A ] {
+ @@ %s 5-7
+
+ - Constants [0] {
+ }
+
+ - Static properties [0] {
+ }
+
+ - Static methods [0] {
+ }
+
+ - Properties [0] {
+ }
+
+ - Methods [1] {
+ Method [ <user, overwrites A> private method f ] {
+ @@ %s 6 - 6
+ }
+ }
+}
+
+
+----( Reflection class C: )----
+Class [ <user> class C extends B ] {
+ @@ %s 8-10
+
+ - Constants [0] {
+ }
+
+ - Static properties [0] {
+ }
+
+ - Static methods [0] {
+ }
+
+ - Properties [0] {
+ }
+
+ - Methods [0] {
+ }
+}
+
+
+----( Reflection class D: )----
+Class [ <user> class D extends C ] {
+ @@ %s 11-13
+
+ - Constants [0] {
+ }
+
+ - Static properties [0] {
+ }
+
+ - Static methods [0] {
+ }
+
+ - Properties [0] {
+ }
+
+ - Methods [1] {
+ Method [ <user, overwrites B> private method f ] {
+ @@ %s 12 - 12
+ }
+ }
+}
diff --git a/ext/reflection/tests/ReflectionExtension_constructor_basic.phpt b/ext/reflection/tests/ReflectionExtension_constructor_basic.phpt
new file mode 100644
index 0000000..72c8ac6
--- /dev/null
+++ b/ext/reflection/tests/ReflectionExtension_constructor_basic.phpt
@@ -0,0 +1,15 @@
+--TEST--
+ReflectionExtension::__construct()
+--CREDITS--
+Gerrit "Remi" te Sligte <remi@wolerized.com>
+Leon Luijkx <leon@phpgg.nl>
+--FILE--
+<?php
+$obj = new ReflectionExtension('reflection');
+$test = $obj instanceof ReflectionExtension;
+var_dump($test);
+?>
+==DONE==
+--EXPECT--
+bool(true)
+==DONE==
diff --git a/ext/reflection/tests/ReflectionExtension_constructor_error.phpt b/ext/reflection/tests/ReflectionExtension_constructor_error.phpt
new file mode 100644
index 0000000..9eae206
--- /dev/null
+++ b/ext/reflection/tests/ReflectionExtension_constructor_error.phpt
@@ -0,0 +1,16 @@
+--TEST--
+ReflectionExtension::__construct()
+--CREDITS--
+Gerrit "Remi" te Sligte <remi@wolerized.com>
+Leon Luijkx <leon@phpgg.nl>
+--FILE--
+<?php
+$obj = new ReflectionExtension();
+$test = $obj instanceof ReflectionExtension;
+var_dump($test);
+?>
+==DONE==
+--EXPECTF--
+Warning: ReflectionExtension::__construct() expects exactly %d parameter, %d given in %s.php on line %d
+bool(true)
+==DONE==
diff --git a/ext/reflection/tests/ReflectionExtension_export_basic.phpt b/ext/reflection/tests/ReflectionExtension_export_basic.phpt
new file mode 100644
index 0000000..3fa7a66
--- /dev/null
+++ b/ext/reflection/tests/ReflectionExtension_export_basic.phpt
@@ -0,0 +1,22 @@
+--TEST--
+ReflectionExtension::export()
+--CREDITS--
+Gerrit "Remi" te Sligte <remi@wolerized.com>
+Leon Luijkx <leon@phpgg.nl>
+--FILE--
+<?php
+ob_start();
+ReflectionExtension::export("reflection", true);
+$test = ob_get_clean();
+var_dump(empty($test));
+unset($test);
+ob_start();
+ReflectionExtension::export("reflection", false);
+$test = ob_get_clean();
+var_dump(empty($test));
+?>
+==DONE==
+--EXPECT--
+bool(true)
+bool(false)
+==DONE==
diff --git a/ext/reflection/tests/ReflectionExtension_getClassNames_basic.phpt b/ext/reflection/tests/ReflectionExtension_getClassNames_basic.phpt
new file mode 100644
index 0000000..465e868
--- /dev/null
+++ b/ext/reflection/tests/ReflectionExtension_getClassNames_basic.phpt
@@ -0,0 +1,20 @@
+--TEST--
+ReflectionExtension::getClassNames() method on an extension which acually returns some information
+--CREDITS--
+Felix De Vliegher <felix.devliegher@gmail.com>
+--FILE--
+<?php
+$standard = new ReflectionExtension('standard');
+var_dump($standard->getClassNames());
+?>
+==DONE==
+--EXPECTF--
+array(3) {
+ [0]=>
+ %s(22) "__PHP_Incomplete_Class"
+ [1]=>
+ %s(15) "php_user_filter"
+ [2]=>
+ %s(9) "Directory"
+}
+==DONE==
diff --git a/ext/reflection/tests/ReflectionExtension_getClassNames_variation1.phpt b/ext/reflection/tests/ReflectionExtension_getClassNames_variation1.phpt
new file mode 100644
index 0000000..cd5dc0b
--- /dev/null
+++ b/ext/reflection/tests/ReflectionExtension_getClassNames_variation1.phpt
@@ -0,0 +1,14 @@
+--TEST--
+ReflectionExtension::getClassNames() method on an extension with no classes
+--CREDITS--
+Felix De Vliegher <felix.devliegher@gmail.com>
+--FILE--
+<?php
+$ereg = new ReflectionExtension('ereg');
+var_dump($ereg->getClassNames());
+?>
+==DONE==
+--EXPECT--
+array(0) {
+}
+==DONE==
diff --git a/ext/reflection/tests/ReflectionExtension_getClasses_basic.phpt b/ext/reflection/tests/ReflectionExtension_getClasses_basic.phpt
new file mode 100644
index 0000000..5df9e08
--- /dev/null
+++ b/ext/reflection/tests/ReflectionExtension_getClasses_basic.phpt
@@ -0,0 +1,74 @@
+--TEST--
+ReflectionExtension::getClasses();
+--CREDITS--
+Thijs Lensselink <tl@lenss.nl>
+--FILE--
+<?php
+$ext = new ReflectionExtension('reflection');
+var_dump($ext->getClasses());
+?>
+==DONE==
+--EXPECT--
+array(12) {
+ ["ReflectionException"]=>
+ &object(ReflectionClass)#2 (1) {
+ ["name"]=>
+ string(19) "ReflectionException"
+ }
+ ["Reflection"]=>
+ &object(ReflectionClass)#3 (1) {
+ ["name"]=>
+ string(10) "Reflection"
+ }
+ ["Reflector"]=>
+ &object(ReflectionClass)#4 (1) {
+ ["name"]=>
+ string(9) "Reflector"
+ }
+ ["ReflectionFunctionAbstract"]=>
+ &object(ReflectionClass)#5 (1) {
+ ["name"]=>
+ string(26) "ReflectionFunctionAbstract"
+ }
+ ["ReflectionFunction"]=>
+ &object(ReflectionClass)#6 (1) {
+ ["name"]=>
+ string(18) "ReflectionFunction"
+ }
+ ["ReflectionParameter"]=>
+ &object(ReflectionClass)#7 (1) {
+ ["name"]=>
+ string(19) "ReflectionParameter"
+ }
+ ["ReflectionMethod"]=>
+ &object(ReflectionClass)#8 (1) {
+ ["name"]=>
+ string(16) "ReflectionMethod"
+ }
+ ["ReflectionClass"]=>
+ &object(ReflectionClass)#9 (1) {
+ ["name"]=>
+ string(15) "ReflectionClass"
+ }
+ ["ReflectionObject"]=>
+ &object(ReflectionClass)#10 (1) {
+ ["name"]=>
+ string(16) "ReflectionObject"
+ }
+ ["ReflectionProperty"]=>
+ &object(ReflectionClass)#11 (1) {
+ ["name"]=>
+ string(18) "ReflectionProperty"
+ }
+ ["ReflectionExtension"]=>
+ &object(ReflectionClass)#12 (1) {
+ ["name"]=>
+ string(19) "ReflectionExtension"
+ }
+ ["ReflectionZendExtension"]=>
+ &object(ReflectionClass)#13 (1) {
+ ["name"]=>
+ string(23) "ReflectionZendExtension"
+ }
+}
+==DONE==
diff --git a/ext/reflection/tests/ReflectionExtension_getDependencies_basic.phpt b/ext/reflection/tests/ReflectionExtension_getDependencies_basic.phpt
new file mode 100644
index 0000000..8b5293a
--- /dev/null
+++ b/ext/reflection/tests/ReflectionExtension_getDependencies_basic.phpt
@@ -0,0 +1,22 @@
+--TEST--
+ReflectionExtension::getDependencies() method on an extension with a required and conflicting dependency
+--CREDITS--
+Felix De Vliegher <felix.devliegher@gmail.com>
+--SKIPIF--
+<?php
+if (!extension_loaded("dom")) die("skip no dom extension");
+?>
+--FILE--
+<?php
+$dom = new ReflectionExtension('dom');
+var_dump($dom->getDependencies());
+?>
+==DONE==
+--EXPECTF--
+array(2) {
+ ["libxml"]=>
+ %s(8) "Required"
+ ["domxml"]=>
+ %s(9) "Conflicts"
+}
+==DONE==
diff --git a/ext/reflection/tests/ReflectionExtension_getDependencies_variation2.phpt b/ext/reflection/tests/ReflectionExtension_getDependencies_variation2.phpt
new file mode 100644
index 0000000..5b0ade5
--- /dev/null
+++ b/ext/reflection/tests/ReflectionExtension_getDependencies_variation2.phpt
@@ -0,0 +1,16 @@
+--TEST--
+ReflectionExtension::getDependencies() method on an extension with one optional dependency
+--CREDITS--
+Felix De Vliegher <felix.devliegher@gmail.com>
+--FILE--
+<?php
+$standard = new ReflectionExtension('standard');
+var_dump($standard->getDependencies());
+?>
+==DONE==
+--EXPECTF--
+array(1) {
+ ["session"]=>
+ %s(8) "Optional"
+}
+==DONE==
diff --git a/ext/reflection/tests/ReflectionExtension_getName_basic.phpt b/ext/reflection/tests/ReflectionExtension_getName_basic.phpt
new file mode 100644
index 0000000..9dae1f3
--- /dev/null
+++ b/ext/reflection/tests/ReflectionExtension_getName_basic.phpt
@@ -0,0 +1,14 @@
+--TEST--
+ReflectionExtension::getName()
+--CREDITS--
+Gerrit "Remi" te Sligte <remi@wolerized.com>
+Leon Luijkx <leon@phpgg.nl>
+--FILE--
+<?php
+$obj = new ReflectionExtension('reflection');
+var_dump($obj->getName());
+?>
+==DONE==
+--EXPECT--
+string(10) "Reflection"
+==DONE==
diff --git a/ext/reflection/tests/ReflectionExtension_getVersion_basic.phpt b/ext/reflection/tests/ReflectionExtension_getVersion_basic.phpt
new file mode 100644
index 0000000..19dee82
--- /dev/null
+++ b/ext/reflection/tests/ReflectionExtension_getVersion_basic.phpt
@@ -0,0 +1,16 @@
+--TEST--
+ReflectionExtension::getVersion()
+--CREDITS--
+Gerrit "Remi" te Sligte <remi@wolerized.com>
+Leon Luijkx <leon@phpgg.nl>
+--FILE--
+<?php
+$obj = new ReflectionExtension('reflection');
+$var = $obj->getVersion() ? $obj->getVersion() : null;
+$test = floatval($var) == $var ? true : false;
+var_dump($test);
+?>
+==DONE==
+--EXPECT--
+bool(true)
+==DONE==
diff --git a/ext/reflection/tests/ReflectionExtension_info_basic.phpt b/ext/reflection/tests/ReflectionExtension_info_basic.phpt
new file mode 100644
index 0000000..48f6a65
--- /dev/null
+++ b/ext/reflection/tests/ReflectionExtension_info_basic.phpt
@@ -0,0 +1,19 @@
+--TEST--
+ReflectionExtension::info()
+--CREDITS--
+Gerrit "Remi" te Sligte <remi@wolerized.com>
+Leon Luijkx <leon@phpgg.nl>
+--FILE--
+<?php
+$obj = new ReflectionExtension('reflection');
+ob_start();
+$testa = $obj->info();
+$testb = ob_get_clean();
+var_dump($testa);
+var_dump(strlen($testb) > 24);
+?>
+==DONE==
+--EXPECT--
+NULL
+bool(true)
+==DONE==
diff --git a/ext/reflection/tests/ReflectionExtension_isPersistant.phpt b/ext/reflection/tests/ReflectionExtension_isPersistant.phpt
new file mode 100644
index 0000000..a78a8bb
--- /dev/null
+++ b/ext/reflection/tests/ReflectionExtension_isPersistant.phpt
@@ -0,0 +1,11 @@
+--TEST--
+ReflectionExtension::isPersistent()
+--FILE--
+<?php
+$obj = new ReflectionExtension('reflection');
+var_dump($obj->isPersistent());
+?>
+==DONE==
+--EXPECT--
+bool(true)
+==DONE==
diff --git a/ext/reflection/tests/ReflectionExtension_isTemporary.phpt b/ext/reflection/tests/ReflectionExtension_isTemporary.phpt
new file mode 100644
index 0000000..be97641
--- /dev/null
+++ b/ext/reflection/tests/ReflectionExtension_isTemporary.phpt
@@ -0,0 +1,11 @@
+--TEST--
+ReflectionExtension::isTemporary()
+--FILE--
+<?php
+$obj = new ReflectionExtension('reflection');
+var_dump($obj->isTemporary());
+?>
+==DONE==
+--EXPECT--
+bool(false)
+==DONE==
diff --git a/ext/reflection/tests/ReflectionFunction_001.phpt b/ext/reflection/tests/ReflectionFunction_001.phpt
new file mode 100644
index 0000000..7c592dc
--- /dev/null
+++ b/ext/reflection/tests/ReflectionFunction_001.phpt
@@ -0,0 +1,67 @@
+--TEST--
+ReflectionFunction methods
+--CREDITS--
+Robin Fernandes <robinf@php.net>
+Steve Seear <stevseea@php.net>
+--FILE--
+<?php
+
+/**
+ * my doc comment
+ */
+function foo () {
+ static $c;
+ static $a = 1;
+ static $b = "hello";
+ $d = 5;
+}
+
+/***
+ * not a doc comment
+ */
+function bar () {}
+
+
+function dumpFuncInfo($name) {
+ $funcInfo = new ReflectionFunction($name);
+ var_dump($funcInfo->getName());
+ var_dump($funcInfo->isInternal());
+ var_dump($funcInfo->isUserDefined());
+ var_dump($funcInfo->getStartLine());
+ var_dump($funcInfo->getEndLine());
+ var_dump($funcInfo->getStaticVariables());
+}
+
+dumpFuncInfo('foo');
+dumpFuncInfo('bar');
+dumpFuncInfo('extract');
+
+?>
+--EXPECT--
+string(3) "foo"
+bool(false)
+bool(true)
+int(6)
+int(11)
+array(3) {
+ ["c"]=>
+ NULL
+ ["a"]=>
+ int(1)
+ ["b"]=>
+ string(5) "hello"
+}
+string(3) "bar"
+bool(false)
+bool(true)
+int(16)
+int(16)
+array(0) {
+}
+string(7) "extract"
+bool(true)
+bool(false)
+bool(false)
+bool(false)
+array(0) {
+} \ No newline at end of file
diff --git a/ext/reflection/tests/ReflectionFunction_construct.001.phpt b/ext/reflection/tests/ReflectionFunction_construct.001.phpt
new file mode 100644
index 0000000..c8e0a17
--- /dev/null
+++ b/ext/reflection/tests/ReflectionFunction_construct.001.phpt
@@ -0,0 +1,23 @@
+--TEST--
+ReflectionFunction constructor errors
+--CREDITS--
+Robin Fernandes <robinf@php.net>
+Steve Seear <stevseea@php.net>
+--FILE--
+<?php
+
+$a = new ReflectionFunction(array(1, 2, 3));
+try {
+ $a = new ReflectionFunction('nonExistentFunction');
+} catch (Exception $e) {
+ echo $e->getMessage();
+}
+$a = new ReflectionFunction();
+$a = new ReflectionFunction(1, 2);
+?>
+--EXPECTF--
+Warning: ReflectionFunction::__construct() expects parameter 1 to be string, array given in %s on line %d
+Function nonExistentFunction() does not exist
+Warning: ReflectionFunction::__construct() expects exactly 1 parameter, 0 given in %s on line %d
+
+Warning: ReflectionFunction::__construct() expects exactly 1 parameter, 2 given in %s on line %d
diff --git a/ext/reflection/tests/ReflectionFunction_getClosureScopeClass.phpt b/ext/reflection/tests/ReflectionFunction_getClosureScopeClass.phpt
new file mode 100644
index 0000000..f725dfd
--- /dev/null
+++ b/ext/reflection/tests/ReflectionFunction_getClosureScopeClass.phpt
@@ -0,0 +1,31 @@
+--TEST--
+Reflection::getClosureScopeClass()
+--SKIPIF--
+<?php
+if (!extension_loaded('reflection') || !defined('PHP_VERSION_ID') || PHP_VERSION_ID < 50399) {
+ print 'skip';
+}
+?>
+--FILE--
+<?php
+$closure = function($param) { return "this is a closure"; };
+$rf = new ReflectionFunction($closure);
+var_dump($rf->getClosureScopeClass());
+
+Class A {
+ public static function getClosure() {
+ return function($param) { return "this is a closure"; };
+ }
+}
+
+$closure = A::getClosure();
+$rf = new ReflectionFunction($closure);
+var_dump($rf->getClosureScopeClass());
+echo "Done!\n";
+--EXPECTF--
+NULL
+object(ReflectionClass)#%d (1) {
+ ["name"]=>
+ string(1) "A"
+}
+Done!
diff --git a/ext/reflection/tests/ReflectionFunction_getClosureThis.phpt b/ext/reflection/tests/ReflectionFunction_getClosureThis.phpt
new file mode 100644
index 0000000..776bfaf
--- /dev/null
+++ b/ext/reflection/tests/ReflectionFunction_getClosureThis.phpt
@@ -0,0 +1,17 @@
+--TEST--
+Reflection::getClosureThis()
+--SKIPIF--
+<?php
+if (!extension_loaded('reflection') || !defined('PHP_VERSION_ID') || PHP_VERSION_ID < 50300) {
+ print 'skip';
+}
+?>
+--FILE--
+<?php
+$closure = function($param) { return "this is a closure"; };
+$rf = new ReflectionFunction($closure);
+var_dump($rf->getClosureThis());
+echo "Done!\n";
+--EXPECTF--
+NULL
+Done!
diff --git a/ext/reflection/tests/ReflectionFunction_getClosure_basic.phpt b/ext/reflection/tests/ReflectionFunction_getClosure_basic.phpt
new file mode 100644
index 0000000..786be05
--- /dev/null
+++ b/ext/reflection/tests/ReflectionFunction_getClosure_basic.phpt
@@ -0,0 +1,37 @@
+--TEST--
+Test ReflectionFunction::getClosure() function : basic functionality
+--FILE--
+<?php
+/* Prototype : public mixed ReflectionFunction::getClosure()
+ * Description: Returns a dynamically created closure for the function
+ * Source code: ext/reflection/php_reflection.c
+ * Alias to functions:
+ */
+
+echo "*** Testing ReflectionFunction::getClosure() : basic functionality ***\n";
+
+function foo()
+{
+ var_dump( "Inside foo function" );
+}
+
+function bar( $arg )
+{
+ var_dump( "Arg is " . $arg );
+}
+
+$func = new ReflectionFunction( 'foo' );
+$closure = $func->getClosure();
+$closure();
+
+$func = new ReflectionFunction( 'bar' );
+$closure = $func->getClosure();
+$closure( 'succeeded' );
+
+?>
+===DONE===
+--EXPECTF--
+*** Testing ReflectionFunction::getClosure() : basic functionality ***
+string(19) "Inside foo function"
+string(16) "Arg is succeeded"
+===DONE===
diff --git a/ext/reflection/tests/ReflectionFunction_getClosure_error.phpt b/ext/reflection/tests/ReflectionFunction_getClosure_error.phpt
new file mode 100644
index 0000000..9a963e4
--- /dev/null
+++ b/ext/reflection/tests/ReflectionFunction_getClosure_error.phpt
@@ -0,0 +1,27 @@
+--TEST--
+Test ReflectionFunction::getClosure() function : error functionality
+--FILE--
+<?php
+/* Prototype : public mixed ReflectionFunction::getClosure()
+ * Description: Returns a dynamically created closure for the function
+ * Source code: ext/reflection/php_reflection.c
+ * Alias to functions:
+ */
+
+echo "*** Testing ReflectionFunction::getClosure() : error conditions ***\n";
+
+function foo()
+{
+ var_dump( "Inside foo function" );
+}
+
+$func = new ReflectionFunction( 'foo' );
+$closure = $func->getClosure('bar');
+
+?>
+===DONE===
+--EXPECTF--
+*** Testing ReflectionFunction::getClosure() : error conditions ***
+
+Warning: ReflectionFunction::getClosure() expects exactly 0 parameters, 1 given in %s on line %d
+===DONE===
diff --git a/ext/reflection/tests/ReflectionFunction_getDocComment.001.phpt b/ext/reflection/tests/ReflectionFunction_getDocComment.001.phpt
new file mode 100644
index 0000000..38c278d
--- /dev/null
+++ b/ext/reflection/tests/ReflectionFunction_getDocComment.001.phpt
@@ -0,0 +1,41 @@
+--TEST--
+ReflectionFunction::getDocComment()
+--CREDITS--
+Robin Fernandes <robinf@php.net>
+Steve Seear <stevseea@php.net>
+--FILE--
+<?php
+
+/**
+ * my doc comment
+ */
+function foo () {
+ static $c;
+ static $a = 1;
+ static $b = "hello";
+ $d = 5;
+}
+
+/***
+ * not a doc comment
+ */
+function bar () {}
+
+
+function dumpFuncInfo($name) {
+ $funcInfo = new ReflectionFunction($name);
+ var_dump($funcInfo->getDocComment());
+}
+
+dumpFuncInfo('foo');
+dumpFuncInfo('bar');
+dumpFuncInfo('extract');
+
+?>
+--EXPECTF--
+string(%d) "/**
+ * my doc comment
+ */"
+bool(false)
+bool(false)
+
diff --git a/ext/reflection/tests/ReflectionFunction_getExtension.phpt b/ext/reflection/tests/ReflectionFunction_getExtension.phpt
new file mode 100644
index 0000000..1834589
--- /dev/null
+++ b/ext/reflection/tests/ReflectionFunction_getExtension.phpt
@@ -0,0 +1,19 @@
+--TEST--
+ReflectionFunction::getExtension()
+--FILE--
+<?php
+function foo () {}
+
+$function = new ReflectionFunction('sort');
+var_dump($function->getExtension());
+
+$function = new ReflectionFunction('foo');
+var_dump($function->getExtension());
+?>
+--EXPECTF--
+object(ReflectionExtension)#%i (1) {
+ ["name"]=>
+ string(8) "standard"
+}
+NULL
+
diff --git a/ext/reflection/tests/ReflectionFunction_getExtensionName.phpt b/ext/reflection/tests/ReflectionFunction_getExtensionName.phpt
new file mode 100644
index 0000000..7553a50
--- /dev/null
+++ b/ext/reflection/tests/ReflectionFunction_getExtensionName.phpt
@@ -0,0 +1,16 @@
+--TEST--
+ReflectionFunction::getExtensionName()
+--FILE--
+<?php
+function foo() {}
+
+$function = new ReflectionFunction('sort');
+var_dump($function->getExtensionName());
+
+$function = new ReflectionFunction('foo');
+var_dump($function->getExtensionName());
+?>
+--EXPECT--
+string(8) "standard"
+bool(false)
+
diff --git a/ext/reflection/tests/ReflectionFunction_getFileName.001.phpt b/ext/reflection/tests/ReflectionFunction_getFileName.001.phpt
new file mode 100644
index 0000000..5dbe7b5
--- /dev/null
+++ b/ext/reflection/tests/ReflectionFunction_getFileName.001.phpt
@@ -0,0 +1,18 @@
+--TEST--
+ReflectionFunction::getFileName() with function in an included file
+--CREDITS--
+Robin Fernandes <robinf@php.net>
+Steve Seear <stevseea@php.net>
+--FILE--
+<?php
+
+include "included4.inc";
+
+$funcInfo = new ReflectionFunction('g');
+var_dump($funcInfo->getFileName());
+
+?>
+--EXPECTF--
+%sincluded4.inc
+%d
+string(%d) "%sincluded4.inc" \ No newline at end of file
diff --git a/ext/reflection/tests/ReflectionFunction_getFileName.002.phpt b/ext/reflection/tests/ReflectionFunction_getFileName.002.phpt
new file mode 100644
index 0000000..455935e
--- /dev/null
+++ b/ext/reflection/tests/ReflectionFunction_getFileName.002.phpt
@@ -0,0 +1,39 @@
+--TEST--
+ReflectionFunction::getFileName()
+--CREDITS--
+Robin Fernandes <robinf@php.net>
+Steve Seear <stevseea@php.net>
+--FILE--
+<?php
+
+/**
+ * my doc comment
+ */
+function foo () {
+ static $c;
+ static $a = 1;
+ static $b = "hello";
+ $d = 5;
+}
+
+/***
+ * not a doc comment
+ */
+function bar () {}
+
+
+function dumpFuncInfo($name) {
+ $funcInfo = new ReflectionFunction($name);
+ var_dump($funcInfo->getFileName());
+}
+
+dumpFuncInfo('foo');
+dumpFuncInfo('bar');
+dumpFuncInfo('extract');
+
+?>
+--EXPECTF--
+string(%d) "%sReflectionFunction_getFileName.002.php"
+string(%d) "%sReflectionFunction_getFileName.002.php"
+bool(false)
+
diff --git a/ext/reflection/tests/ReflectionFunction_getNamespaceName.phpt b/ext/reflection/tests/ReflectionFunction_getNamespaceName.phpt
new file mode 100644
index 0000000..08b3ddd
--- /dev/null
+++ b/ext/reflection/tests/ReflectionFunction_getNamespaceName.phpt
@@ -0,0 +1,29 @@
+--TEST--
+ReflectionFunction::getNamespaceName()
+--FILE--
+<?php
+namespace A\B;
+function foo() {}
+
+$function = new \ReflectionFunction('sort');
+var_dump($function->inNamespace());
+var_dump($function->getName());
+var_dump($function->getNamespaceName());
+var_dump($function->getShortName());
+
+$function = new \ReflectionFunction('A\\B\\foo');
+var_dump($function->inNamespace());
+var_dump($function->getName());
+var_dump($function->getNamespaceName());
+var_dump($function->getShortName());
+?>
+--EXPECT--
+bool(false)
+string(4) "sort"
+string(0) ""
+string(4) "sort"
+bool(true)
+string(7) "A\B\foo"
+string(3) "A\B"
+string(3) "foo"
+
diff --git a/ext/reflection/tests/ReflectionFunction_isClosure_basic.phpt b/ext/reflection/tests/ReflectionFunction_isClosure_basic.phpt
new file mode 100644
index 0000000..eeaf8d3
--- /dev/null
+++ b/ext/reflection/tests/ReflectionFunction_isClosure_basic.phpt
@@ -0,0 +1,18 @@
+--TEST--
+Reflection::isClosure
+--CREDITS--
+Stefan Koopmanschap <stefan@phpgg.nl>
+TestFest PHP|Tek
+--SKIPIF--
+<?php
+if (!extension_loaded('reflection') || !defined('PHP_VERSION_ID') || PHP_VERSION_ID < 50300) {
+ print 'skip';
+}
+?>
+--FILE--
+<?php
+$closure = function($param) { return "this is a closure"; };
+$rc = new ReflectionFunction($closure);
+echo var_dump($rc->isClosure());
+--EXPECTF--
+bool(true)
diff --git a/ext/reflection/tests/ReflectionFunction_isDeprecated_basic.phpt b/ext/reflection/tests/ReflectionFunction_isDeprecated_basic.phpt
new file mode 100644
index 0000000..31d37a8
--- /dev/null
+++ b/ext/reflection/tests/ReflectionFunction_isDeprecated_basic.phpt
@@ -0,0 +1,15 @@
+--TEST--
+ReflectionFunction::isDeprecated
+--CREDITS--
+Stefan Koopmanschap <stefan@phpgg.nl>
+TestFest PHP|Tek
+--SKIPIF--
+<?php
+if (!extension_loaded('reflection') || !defined('PHP_VERSION_ID') || PHP_VERSION_ID < 50300) print 'skip';
+?>
+--FILE--
+<?php
+$rc = new ReflectionFunction('ereg');
+echo var_dump($rc->isDeprecated());
+--EXPECTF--
+bool(true)
diff --git a/ext/reflection/tests/ReflectionFunction_isDisabled_basic.phpt b/ext/reflection/tests/ReflectionFunction_isDisabled_basic.phpt
new file mode 100644
index 0000000..c71b96b
--- /dev/null
+++ b/ext/reflection/tests/ReflectionFunction_isDisabled_basic.phpt
@@ -0,0 +1,17 @@
+--TEST--
+ReflectionFunction::isDisabled
+--CREDITS--
+Stefan Koopmanschap <stefan@phpgg.nl>
+TestFest PHP|Tek
+--SKIPIF--
+<?php
+if (!extension_loaded('reflection')) print 'skip';
+?>
+--INI--
+disable_functions=is_file
+--FILE--
+<?php
+$rc = new ReflectionFunction('is_file');
+echo var_dump($rc->isDisabled());
+--EXPECTF--
+bool(true)
diff --git a/ext/reflection/tests/ReflectionMethod_006.phpt b/ext/reflection/tests/ReflectionMethod_006.phpt
new file mode 100644
index 0000000..a516419
--- /dev/null
+++ b/ext/reflection/tests/ReflectionMethod_006.phpt
@@ -0,0 +1,100 @@
+--TEST--
+ReflectionMethod methods - wrong num args
+--CREDITS--
+Robin Fernandes <robinf@php.net>
+Steve Seear <stevseea@php.net>
+--FILE--
+<?php
+
+var_dump(new ReflectionMethod());
+var_dump(new ReflectionMethod('a', 'b', 'c'));
+
+class C {
+ public function f() {}
+}
+
+$rm = new ReflectionMethod('C', 'f');
+
+var_dump($rm->isFinal(1));
+var_dump($rm->isAbstract(1));
+var_dump($rm->isPrivate(1));
+var_dump($rm->isProtected(1));
+var_dump($rm->isPublic(1));
+var_dump($rm->isStatic(1));
+var_dump($rm->isConstructor(1));
+var_dump($rm->isDestructor(1));
+var_dump($rm->getModifiers(1));
+var_dump($rm->isInternal(1));
+var_dump($rm->isUserDefined(1));
+var_dump($rm->getFileName(1));
+var_dump($rm->getStartLine(1));
+var_dump($rm->getEndLine(1));
+var_dump($rm->getStaticVariables(1));
+var_dump($rm->getName(1));
+
+
+?>
+--EXPECTF--
+Warning: ReflectionMethod::__construct() expects exactly 1 parameter, 0 given in %s on line %d
+object(ReflectionMethod)#%d (2) {
+ ["name"]=>
+ string(0) ""
+ ["class"]=>
+ string(0) ""
+}
+
+Warning: ReflectionMethod::__construct() expects exactly 1 parameter, 3 given in %s on line %d
+object(ReflectionMethod)#%d (2) {
+ ["name"]=>
+ string(0) ""
+ ["class"]=>
+ string(0) ""
+}
+
+Warning: ReflectionMethod::isFinal() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionMethod::isAbstract() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionMethod::isPrivate() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionMethod::isProtected() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionMethod::isPublic() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionMethod::isStatic() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionMethod::isConstructor() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionMethod::isDestructor() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionMethod::getModifiers() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionFunctionAbstract::isInternal() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionFunctionAbstract::isUserDefined() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionFunctionAbstract::getFileName() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionFunctionAbstract::getStartLine() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionFunctionAbstract::getEndLine() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionFunctionAbstract::getStaticVariables() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionFunctionAbstract::getName() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
diff --git a/ext/reflection/tests/ReflectionMethod_basic1.phpt b/ext/reflection/tests/ReflectionMethod_basic1.phpt
new file mode 100644
index 0000000..75ab957
--- /dev/null
+++ b/ext/reflection/tests/ReflectionMethod_basic1.phpt
@@ -0,0 +1,298 @@
+--TEST--
+ReflectionMethod class - various methods
+--FILE--
+<?php
+
+function reflectMethod($class, $method) {
+ $methodInfo = new ReflectionMethod($class, $method);
+ echo "**********************************\n";
+ echo "Reflecting on method $class::$method()\n\n";
+ echo "\nisFinal():\n";
+ var_dump($methodInfo->isFinal());
+ echo "\nisAbstract():\n";
+ var_dump($methodInfo->isAbstract());
+ echo "\nisPublic():\n";
+ var_dump($methodInfo->isPublic());
+ echo "\nisPrivate():\n";
+ var_dump($methodInfo->isPrivate());
+ echo "\nisProtected():\n";
+ var_dump($methodInfo->isProtected());
+ echo "\nisStatic():\n";
+ var_dump($methodInfo->isStatic());
+ echo "\nisConstructor():\n";
+ var_dump($methodInfo->isConstructor());
+ echo "\nisDestructor():\n";
+ var_dump($methodInfo->isDestructor());
+ echo "\n**********************************\n";
+}
+
+class TestClass
+{
+ public function foo() {
+ echo "Called foo()\n";
+ }
+
+ static function stat() {
+ echo "Called stat()\n";
+ }
+
+ private function priv() {
+ echo "Called priv()\n";
+ }
+
+ protected function prot() {}
+
+ public function __destruct() {}
+}
+
+class DerivedClass extends TestClass {}
+
+interface TestInterface {
+ public function int();
+}
+
+reflectMethod("DerivedClass", "foo");
+reflectMethod("TestClass", "stat");
+reflectMethod("TestClass", "priv");
+reflectMethod("TestClass", "prot");
+reflectMethod("DerivedClass", "prot");
+reflectMethod("TestInterface", "int");
+reflectMethod("ReflectionProperty", "__construct");
+reflectMethod("TestClass", "__destruct");
+
+?>
+--EXPECT--
+**********************************
+Reflecting on method DerivedClass::foo()
+
+
+isFinal():
+bool(false)
+
+isAbstract():
+bool(false)
+
+isPublic():
+bool(true)
+
+isPrivate():
+bool(false)
+
+isProtected():
+bool(false)
+
+isStatic():
+bool(false)
+
+isConstructor():
+bool(false)
+
+isDestructor():
+bool(false)
+
+**********************************
+**********************************
+Reflecting on method TestClass::stat()
+
+
+isFinal():
+bool(false)
+
+isAbstract():
+bool(false)
+
+isPublic():
+bool(true)
+
+isPrivate():
+bool(false)
+
+isProtected():
+bool(false)
+
+isStatic():
+bool(true)
+
+isConstructor():
+bool(false)
+
+isDestructor():
+bool(false)
+
+**********************************
+**********************************
+Reflecting on method TestClass::priv()
+
+
+isFinal():
+bool(false)
+
+isAbstract():
+bool(false)
+
+isPublic():
+bool(false)
+
+isPrivate():
+bool(true)
+
+isProtected():
+bool(false)
+
+isStatic():
+bool(false)
+
+isConstructor():
+bool(false)
+
+isDestructor():
+bool(false)
+
+**********************************
+**********************************
+Reflecting on method TestClass::prot()
+
+
+isFinal():
+bool(false)
+
+isAbstract():
+bool(false)
+
+isPublic():
+bool(false)
+
+isPrivate():
+bool(false)
+
+isProtected():
+bool(true)
+
+isStatic():
+bool(false)
+
+isConstructor():
+bool(false)
+
+isDestructor():
+bool(false)
+
+**********************************
+**********************************
+Reflecting on method DerivedClass::prot()
+
+
+isFinal():
+bool(false)
+
+isAbstract():
+bool(false)
+
+isPublic():
+bool(false)
+
+isPrivate():
+bool(false)
+
+isProtected():
+bool(true)
+
+isStatic():
+bool(false)
+
+isConstructor():
+bool(false)
+
+isDestructor():
+bool(false)
+
+**********************************
+**********************************
+Reflecting on method TestInterface::int()
+
+
+isFinal():
+bool(false)
+
+isAbstract():
+bool(true)
+
+isPublic():
+bool(true)
+
+isPrivate():
+bool(false)
+
+isProtected():
+bool(false)
+
+isStatic():
+bool(false)
+
+isConstructor():
+bool(false)
+
+isDestructor():
+bool(false)
+
+**********************************
+**********************************
+Reflecting on method ReflectionProperty::__construct()
+
+
+isFinal():
+bool(false)
+
+isAbstract():
+bool(false)
+
+isPublic():
+bool(true)
+
+isPrivate():
+bool(false)
+
+isProtected():
+bool(false)
+
+isStatic():
+bool(false)
+
+isConstructor():
+bool(true)
+
+isDestructor():
+bool(false)
+
+**********************************
+**********************************
+Reflecting on method TestClass::__destruct()
+
+
+isFinal():
+bool(false)
+
+isAbstract():
+bool(false)
+
+isPublic():
+bool(true)
+
+isPrivate():
+bool(false)
+
+isProtected():
+bool(false)
+
+isStatic():
+bool(false)
+
+isConstructor():
+bool(false)
+
+isDestructor():
+bool(true)
+
+**********************************
+
+
diff --git a/ext/reflection/tests/ReflectionMethod_basic2.phpt b/ext/reflection/tests/ReflectionMethod_basic2.phpt
new file mode 100644
index 0000000..c91af67
--- /dev/null
+++ b/ext/reflection/tests/ReflectionMethod_basic2.phpt
@@ -0,0 +1,188 @@
+--TEST--
+ReflectionMethod class __toString() and export() methods
+--FILE--
+<?php
+
+function reflectMethod($class, $method) {
+ $methodInfo = new ReflectionMethod($class, $method);
+ echo "**********************************\n";
+ echo "Reflecting on method $class::$method()\n\n";
+ echo "__toString():\n";
+ var_dump($methodInfo->__toString());
+ echo "\nexport():\n";
+ var_dump(ReflectionMethod::export($class, $method, true));
+ echo "\n**********************************\n";
+}
+
+class TestClass
+{
+ public function foo() {
+ echo "Called foo()\n";
+ }
+
+ static function stat() {
+ echo "Called stat()\n";
+ }
+
+ private function priv() {
+ echo "Called priv()\n";
+ }
+
+ protected function prot() {}
+
+ public function __destruct() {}
+}
+
+class DerivedClass extends TestClass {}
+
+interface TestInterface {
+ public function int();
+}
+
+reflectMethod("DerivedClass", "foo");
+reflectMethod("TestClass", "stat");
+reflectMethod("TestClass", "priv");
+reflectMethod("TestClass", "prot");
+reflectMethod("DerivedClass", "prot");
+reflectMethod("TestInterface", "int");
+reflectMethod("ReflectionProperty", "__construct");
+reflectMethod("TestClass", "__destruct");
+
+?>
+--EXPECTF--
+**********************************
+Reflecting on method DerivedClass::foo()
+
+__toString():
+string(%d) "Method [ <user, inherits TestClass> public method foo ] {
+ @@ %s 16 - 18
+}
+"
+
+export():
+string(%d) "Method [ <user, inherits TestClass> public method foo ] {
+ @@ %s 16 - 18
+}
+"
+
+**********************************
+**********************************
+Reflecting on method TestClass::stat()
+
+__toString():
+string(%d) "Method [ <user> static public method stat ] {
+ @@ %s 20 - 22
+}
+"
+
+export():
+string(%d) "Method [ <user> static public method stat ] {
+ @@ %s 20 - 22
+}
+"
+
+**********************************
+**********************************
+Reflecting on method TestClass::priv()
+
+__toString():
+string(%d) "Method [ <user> private method priv ] {
+ @@ %s 24 - 26
+}
+"
+
+export():
+string(%d) "Method [ <user> private method priv ] {
+ @@ %s 24 - 26
+}
+"
+
+**********************************
+**********************************
+Reflecting on method TestClass::prot()
+
+__toString():
+string(%d) "Method [ <user> protected method prot ] {
+ @@ %s 28 - 28
+}
+"
+
+export():
+string(%d) "Method [ <user> protected method prot ] {
+ @@ %s 28 - 28
+}
+"
+
+**********************************
+**********************************
+Reflecting on method DerivedClass::prot()
+
+__toString():
+string(%d) "Method [ <user, inherits TestClass> protected method prot ] {
+ @@ %s 28 - 28
+}
+"
+
+export():
+string(%d) "Method [ <user, inherits TestClass> protected method prot ] {
+ @@ %s 28 - 28
+}
+"
+
+**********************************
+**********************************
+Reflecting on method TestInterface::int()
+
+__toString():
+string(%d) "Method [ <user> abstract public method int ] {
+ @@ %s 36 - 36
+}
+"
+
+export():
+string(%d) "Method [ <user> abstract public method int ] {
+ @@ %s 36 - 36
+}
+"
+
+**********************************
+**********************************
+Reflecting on method ReflectionProperty::__construct()
+
+__toString():
+string(%d) "Method [ <internal:Reflection, ctor> public method __construct ] {
+
+ - Parameters [2] {
+ Parameter #0 [ <required> $class ]
+ Parameter #1 [ <required> $name ]
+ }
+}
+"
+
+export():
+string(%d) "Method [ <internal:Reflection, ctor> public method __construct ] {
+
+ - Parameters [2] {
+ Parameter #0 [ <required> $class ]
+ Parameter #1 [ <required> $name ]
+ }
+}
+"
+
+**********************************
+**********************************
+Reflecting on method TestClass::__destruct()
+
+__toString():
+string(%d) "Method [ <user, dtor> public method __destruct ] {
+ @@ %s 30 - 30
+}
+"
+
+export():
+string(%d) "Method [ <user, dtor> public method __destruct ] {
+ @@ %s 30 - 30
+}
+"
+
+**********************************
diff --git a/ext/reflection/tests/ReflectionMethod_basic3.phpt b/ext/reflection/tests/ReflectionMethod_basic3.phpt
new file mode 100644
index 0000000..7b65927
--- /dev/null
+++ b/ext/reflection/tests/ReflectionMethod_basic3.phpt
@@ -0,0 +1,167 @@
+--TEST--
+ReflectionMethod class getName(), isInternal() and isUserDefined() methods
+--FILE--
+<?php
+
+function reflectMethod($class, $method) {
+ $methodInfo = new ReflectionMethod($class, $method);
+ echo "**********************************\n";
+ echo "Reflecting on method $class::$method()\n\n";
+ echo "\ngetName():\n";
+ var_dump($methodInfo->getName());
+ echo "\nisInternal():\n";
+ var_dump($methodInfo->isInternal());
+ echo "\nisUserDefined():\n";
+ var_dump($methodInfo->isUserDefined());
+ echo "\n**********************************\n";
+}
+
+class TestClass
+{
+ public function foo() {
+ echo "Called foo()\n";
+ }
+
+ static function stat() {
+ echo "Called stat()\n";
+ }
+
+ private function priv() {
+ echo "Called priv()\n";
+ }
+
+ protected function prot() {}
+
+ public function __destruct() {}
+}
+
+class DerivedClass extends TestClass {}
+
+interface TestInterface {
+ public function int();
+}
+
+reflectMethod("DerivedClass", "foo");
+reflectMethod("TestClass", "stat");
+reflectMethod("TestClass", "priv");
+reflectMethod("TestClass", "prot");
+reflectMethod("DerivedClass", "prot");
+reflectMethod("TestInterface", "int");
+reflectMethod("ReflectionProperty", "__construct");
+reflectMethod("TestClass", "__destruct");
+
+
+?>
+--EXPECT--
+**********************************
+Reflecting on method DerivedClass::foo()
+
+
+getName():
+string(3) "foo"
+
+isInternal():
+bool(false)
+
+isUserDefined():
+bool(true)
+
+**********************************
+**********************************
+Reflecting on method TestClass::stat()
+
+
+getName():
+string(4) "stat"
+
+isInternal():
+bool(false)
+
+isUserDefined():
+bool(true)
+
+**********************************
+**********************************
+Reflecting on method TestClass::priv()
+
+
+getName():
+string(4) "priv"
+
+isInternal():
+bool(false)
+
+isUserDefined():
+bool(true)
+
+**********************************
+**********************************
+Reflecting on method TestClass::prot()
+
+
+getName():
+string(4) "prot"
+
+isInternal():
+bool(false)
+
+isUserDefined():
+bool(true)
+
+**********************************
+**********************************
+Reflecting on method DerivedClass::prot()
+
+
+getName():
+string(4) "prot"
+
+isInternal():
+bool(false)
+
+isUserDefined():
+bool(true)
+
+**********************************
+**********************************
+Reflecting on method TestInterface::int()
+
+
+getName():
+string(3) "int"
+
+isInternal():
+bool(false)
+
+isUserDefined():
+bool(true)
+
+**********************************
+**********************************
+Reflecting on method ReflectionProperty::__construct()
+
+
+getName():
+string(11) "__construct"
+
+isInternal():
+bool(true)
+
+isUserDefined():
+bool(false)
+
+**********************************
+**********************************
+Reflecting on method TestClass::__destruct()
+
+
+getName():
+string(10) "__destruct"
+
+isInternal():
+bool(false)
+
+isUserDefined():
+bool(true)
+
+**********************************
diff --git a/ext/reflection/tests/ReflectionMethod_basic4.phpt b/ext/reflection/tests/ReflectionMethod_basic4.phpt
new file mode 100644
index 0000000..82672e4
--- /dev/null
+++ b/ext/reflection/tests/ReflectionMethod_basic4.phpt
@@ -0,0 +1,170 @@
+--TEST--
+ReflectionMethod class getFileName(), getStartLine() and getEndLine() methods
+--FILE--
+<?php
+
+function reflectMethod($class, $method) {
+ $methodInfo = new ReflectionMethod($class, $method);
+ echo "**********************************\n";
+ echo "Reflecting on method $class::$method()\n\n";
+ echo "\ngetFileName():\n";
+ var_dump($methodInfo->getFileName());
+ echo "\ngetStartLine():\n";
+ var_dump($methodInfo->getStartLine());
+ echo "\ngetEndLine():\n";
+ var_dump($methodInfo->getEndLine());
+ echo "\n**********************************\n";
+}
+
+class TestClass
+{
+ public function foo() {
+
+
+ echo "Called foo()\n";
+
+
+ }
+
+ static function stat() {
+ echo "Called stat()\n";
+ }
+
+ private function priv() {
+ echo "Called priv()\n";
+ }
+
+ protected function prot() {}
+
+ public function __destruct() {}
+}
+
+class DerivedClass extends TestClass {}
+
+interface TestInterface {
+ public function int();
+}
+
+reflectMethod("DerivedClass", "foo");
+reflectMethod("TestClass", "stat");
+reflectMethod("TestClass", "priv");
+reflectMethod("TestClass", "prot");
+reflectMethod("DerivedClass", "prot");
+reflectMethod("TestInterface", "int");
+reflectMethod("ReflectionProperty", "__construct");
+reflectMethod("TestClass", "__destruct");
+
+?>
+--EXPECTF--
+**********************************
+Reflecting on method DerivedClass::foo()
+
+
+getFileName():
+string(%d) "%sReflectionMethod_basic4.php"
+
+getStartLine():
+int(18)
+
+getEndLine():
+int(24)
+
+**********************************
+**********************************
+Reflecting on method TestClass::stat()
+
+
+getFileName():
+string(%d) "%sReflectionMethod_basic4.php"
+
+getStartLine():
+int(26)
+
+getEndLine():
+int(28)
+
+**********************************
+**********************************
+Reflecting on method TestClass::priv()
+
+
+getFileName():
+string(%d) "%sReflectionMethod_basic4.php"
+
+getStartLine():
+int(30)
+
+getEndLine():
+int(32)
+
+**********************************
+**********************************
+Reflecting on method TestClass::prot()
+
+
+getFileName():
+string(%d) "%sReflectionMethod_basic4.php"
+
+getStartLine():
+int(34)
+
+getEndLine():
+int(34)
+
+**********************************
+**********************************
+Reflecting on method DerivedClass::prot()
+
+
+getFileName():
+string(%d) "%sReflectionMethod_basic4.php"
+
+getStartLine():
+int(34)
+
+getEndLine():
+int(34)
+
+**********************************
+**********************************
+Reflecting on method TestInterface::int()
+
+
+getFileName():
+string(%d) "%sReflectionMethod_basic4.php"
+
+getStartLine():
+int(42)
+
+getEndLine():
+int(42)
+
+**********************************
+**********************************
+Reflecting on method ReflectionProperty::__construct()
+
+
+getFileName():
+bool(false)
+
+getStartLine():
+bool(false)
+
+getEndLine():
+bool(false)
+
+**********************************
+**********************************
+Reflecting on method TestClass::__destruct()
+
+
+getFileName():
+string(%d) "%sReflectionMethod_basic4.php"
+
+getStartLine():
+int(36)
+
+getEndLine():
+int(36)
+
+**********************************
diff --git a/ext/reflection/tests/ReflectionMethod_constructor_basic.phpt b/ext/reflection/tests/ReflectionMethod_constructor_basic.phpt
new file mode 100644
index 0000000..2a2f02f
--- /dev/null
+++ b/ext/reflection/tests/ReflectionMethod_constructor_basic.phpt
@@ -0,0 +1,117 @@
+--TEST--
+ReflectionMethod::isConstructor()
+--FILE--
+<?php
+
+class NewCtor {
+ function __construct() {
+ echo "In " . __METHOD__ . "\n";
+ }
+
+}
+echo "New-style constructor:\n";
+$methodInfo = new ReflectionMethod("NewCtor::__construct");
+var_dump($methodInfo->isConstructor());
+
+class ExtendsNewCtor extends NewCtor {
+}
+echo "\nInherited new-style constructor\n";
+$methodInfo = new ReflectionMethod("ExtendsNewCtor::__construct");
+var_dump($methodInfo->isConstructor());
+
+class OldCtor {
+ function OldCtor() {
+ echo "In " . __METHOD__ . "\n";
+ }
+}
+echo "\nOld-style constructor:\n";
+$methodInfo = new ReflectionMethod("OldCtor::OldCtor");
+var_dump($methodInfo->isConstructor());
+
+class ExtendsOldCtor extends OldCtor {
+}
+echo "\nInherited old-style constructor:\n";
+$methodInfo = new ReflectionMethod("ExtendsOldCtor::OldCtor");
+var_dump($methodInfo->isConstructor());
+
+class X {
+ function Y() {
+ echo "In " . __METHOD__ . "\n";
+ }
+}
+echo "\nNot a constructor:\n";
+$methodInfo = new ReflectionMethod("X::Y");
+var_dump($methodInfo->isConstructor());
+
+class Y extends X {
+}
+echo "\nInherited method of the same name as the class:\n";
+$methodInfo = new ReflectionMethod("Y::Y");
+var_dump($methodInfo->isConstructor());
+
+class OldAndNewCtor {
+ function OldAndNewCtor() {
+ echo "In " . __METHOD__ . "\n";
+ }
+
+ function __construct() {
+ echo "In " . __METHOD__ . "\n";
+ }
+}
+echo "\nOld-style constructor:\n";
+$methodInfo = new ReflectionMethod("OldAndNewCtor::OldAndNewCtor");
+var_dump($methodInfo->isConstructor());
+
+echo "\nRedefined constructor:\n";
+$methodInfo = new ReflectionMethod("OldAndNewCtor::__construct");
+var_dump($methodInfo->isConstructor());
+
+class NewAndOldCtor {
+ function __construct() {
+ echo "In " . __METHOD__ . "\n";
+ }
+
+ function NewAndOldCtor() {
+ echo "In " . __METHOD__ . "\n";
+ }
+}
+echo "\nNew-style constructor:\n";
+$methodInfo = new ReflectionMethod("NewAndOldCtor::__construct");
+var_dump($methodInfo->isConstructor());
+
+echo "\nRedefined old-style constructor:\n";
+$methodInfo = new ReflectionMethod("NewAndOldCtor::NewAndOldCtor");
+var_dump($methodInfo->isConstructor());
+
+?>
+--EXPECTF--
+Strict Standards: Redefining already defined constructor for class OldAndNewCtor in %s on line %d
+New-style constructor:
+bool(true)
+
+Inherited new-style constructor
+bool(true)
+
+Old-style constructor:
+bool(true)
+
+Inherited old-style constructor:
+bool(true)
+
+Not a constructor:
+bool(false)
+
+Inherited method of the same name as the class:
+bool(false)
+
+Old-style constructor:
+bool(false)
+
+Redefined constructor:
+bool(true)
+
+New-style constructor:
+bool(true)
+
+Redefined old-style constructor:
+bool(false)
diff --git a/ext/reflection/tests/ReflectionMethod_constructor_error1.phpt b/ext/reflection/tests/ReflectionMethod_constructor_error1.phpt
new file mode 100644
index 0000000..7052825
--- /dev/null
+++ b/ext/reflection/tests/ReflectionMethod_constructor_error1.phpt
@@ -0,0 +1,103 @@
+--TEST--
+ReflectionMethod constructor errors
+--CREDITS--
+Robin Fernandes <robinf@php.net>
+Steve Seear <stevseea@php.net>
+--FILE--
+<?php
+
+class TestClass
+{
+ public function foo() {
+ }
+}
+
+
+try {
+ echo "\nWrong type of argument (bool):\n";
+ $methodInfo = new ReflectionMethod(true);
+} catch (Exception $e) {
+ print $e->__toString();
+}
+try {
+ echo "\nWrong type of argument (int):\n";
+ $methodInfo = new ReflectionMethod(3);
+} catch (Exception $e) {
+ print $e->__toString();
+}
+try {
+ echo "\nWrong type of argument (bool, string):\n";
+ $methodInfo = new ReflectionMethod(true, "foo");
+} catch (Exception $e) {
+ print $e->__toString();
+}
+try {
+ echo "\nWrong type of argument (string, bool):\n";
+ $methodInfo = new ReflectionMethod('TestClass', true);
+} catch (Exception $e) {
+ print $e->__toString();
+}
+try {
+ echo "\nNo method given:\n";
+ $methodInfo = new ReflectionMethod("TestClass");
+} catch (Exception $e) {
+ print $e->__toString();
+}
+try {
+ echo "\nClass and Method in same string, bad method name:\n";
+ $methodInfo = new ReflectionMethod("TestClass::foop::dedoop");
+} catch (Exception $e) {
+ print $e->__toString();
+}
+try {
+ echo "\nClass and Method in same string, bad class name:\n";
+ $methodInfo = new ReflectionMethod("TestCla::foo");
+} catch (Exception $e) {
+ print $e->__toString();
+}
+try {
+ echo "\nClass and Method in same string (ok):\n";
+ $methodInfo = new ReflectionMethod("TestClass::foo");
+} catch (Exception $e) {
+ print $e->__toString();
+}
+
+?>
+--EXPECTF--
+Wrong type of argument (bool):
+exception 'ReflectionException' with message 'Invalid method name 1' in %s
+Stack trace:
+#0 %s ReflectionMethod->__construct('1')
+#1 {main}
+Wrong type of argument (int):
+exception 'ReflectionException' with message 'Invalid method name 3' in %s
+Stack trace:
+#0 %s ReflectionMethod->__construct('3')
+#1 {main}
+Wrong type of argument (bool, string):
+exception 'ReflectionException' with message 'The parameter class is expected to be either a string or an object' in %s
+Stack trace:
+#0 %s ReflectionMethod->__construct(true, 'foo')
+#1 {main}
+Wrong type of argument (string, bool):
+exception 'ReflectionException' with message 'Method TestClass::1() does not exist' in %s
+Stack trace:
+#0 %s ReflectionMethod->__construct('TestClass', '1')
+#1 {main}
+No method given:
+exception 'ReflectionException' with message 'Invalid method name TestClass' in %s
+Stack trace:
+#0 %s ReflectionMethod->__construct('TestClass')
+#1 {main}
+Class and Method in same string, bad method name:
+exception 'ReflectionException' with message 'Method TestClass::foop::dedoop() does not exist' in %s
+Stack trace:
+#0 %s ReflectionMethod->__construct('TestClass::foop...')
+#1 {main}
+Class and Method in same string, bad class name:
+exception 'ReflectionException' with message 'Class TestCla does not exist' in %s
+Stack trace:
+#0 %s ReflectionMethod->__construct('TestCla::foo')
+#1 {main}
+Class and Method in same string (ok):
+
diff --git a/ext/reflection/tests/ReflectionMethod_constructor_error2.phpt b/ext/reflection/tests/ReflectionMethod_constructor_error2.phpt
new file mode 100644
index 0000000..1c2d3a1
--- /dev/null
+++ b/ext/reflection/tests/ReflectionMethod_constructor_error2.phpt
@@ -0,0 +1,37 @@
+--TEST--
+ReflectionMethod constructor errors
+--CREDITS--
+Robin Fernandes <robinf@php.net>
+Steve Seear <stevseea@php.net>
+--FILE--
+<?php
+
+class TestClass
+{
+ public function foo() {
+ }
+}
+
+
+try {
+ echo "Too few arguments:\n";
+ $methodInfo = new ReflectionMethod();
+} catch (Exception $e) {
+ print $e->__toString();
+}
+try {
+ echo "\nToo many arguments:\n";
+ $methodInfo = new ReflectionMethod("TestClass", "foo", true);
+} catch (Exception $e) {
+ print $e->__toString();
+}
+
+?>
+--EXPECTF--
+Too few arguments:
+
+Warning: ReflectionMethod::__construct() expects exactly 1 parameter, 0 given in %s on line 12
+
+Too many arguments:
+
+Warning: ReflectionMethod::__construct() expects exactly 1 parameter, 3 given in %s on line 18
diff --git a/ext/reflection/tests/ReflectionMethod_getClosureThis.phpt b/ext/reflection/tests/ReflectionMethod_getClosureThis.phpt
new file mode 100644
index 0000000..58c0999
--- /dev/null
+++ b/ext/reflection/tests/ReflectionMethod_getClosureThis.phpt
@@ -0,0 +1,53 @@
+--TEST--
+Reflection::getClosureThis()
+--SKIPIF--
+<?php
+if (!extension_loaded('reflection') || !defined('PHP_VERSION_ID') || PHP_VERSION_ID < 50300) {
+ print 'skip';
+}
+?>
+--FILE--
+<?php
+class StaticExample
+{
+ static function foo()
+ {
+ var_dump( "Static Example class, Hello World!" );
+ }
+}
+
+class Example
+{
+ public $bar = 42;
+ public function foo()
+ {
+ var_dump( "Example class, bar: " . $this->bar );
+ }
+}
+
+// Initialize classes
+$class = new ReflectionClass( 'Example' );
+$staticclass = new ReflectionClass( 'StaticExample' );
+$object = new Example();
+
+$method = $staticclass->getMethod( 'foo' );
+$closure = $method->getClosure();
+$rf = new ReflectionFunction($closure);
+
+var_dump($rf->getClosureThis());
+
+$method = $class->getMethod( 'foo' );
+
+$closure = $method->getClosure( $object );
+$rf = new ReflectionFunction($closure);
+
+var_dump($rf->getClosureThis());
+
+echo "Done!\n";
+--EXPECTF--
+NULL
+object(Example)#%d (1) {
+ ["bar"]=>
+ int(42)
+}
+Done!
diff --git a/ext/reflection/tests/ReflectionMethod_getClosure_basic.phpt b/ext/reflection/tests/ReflectionMethod_getClosure_basic.phpt
new file mode 100644
index 0000000..c97c41c
--- /dev/null
+++ b/ext/reflection/tests/ReflectionMethod_getClosure_basic.phpt
@@ -0,0 +1,55 @@
+--TEST--
+Test ReflectionMethod::getClosure() function : basic functionality
+--FILE--
+<?php
+/* Prototype : public mixed ReflectionFunction::getClosure()
+ * Description: Returns a dynamically created closure for the method
+ * Source code: ext/reflection/php_reflection.c
+ * Alias to functions:
+ */
+
+echo "*** Testing ReflectionMethod::getClosure() : basic functionality ***\n";
+
+class StaticExample
+{
+ static function foo()
+ {
+ var_dump( "Static Example class, Hello World!" );
+ }
+}
+
+class Example
+{
+ public $bar = 42;
+ public function foo()
+ {
+ var_dump( "Example class, bar: " . $this->bar );
+ }
+}
+
+// Initialize classes
+$class = new ReflectionClass( 'Example' );
+$staticclass = new ReflectionClass( 'StaticExample' );
+$object = new Example();
+$fakeobj = new StdClass();
+
+
+$method = $staticclass->getMethod( 'foo' );
+$closure = $method->getClosure();
+$closure();
+
+$method = $class->getMethod( 'foo' );
+
+$closure = $method->getClosure( $object );
+$closure();
+$object->bar = 34;
+$closure();
+
+?>
+===DONE===
+--EXPECTF--
+*** Testing ReflectionMethod::getClosure() : basic functionality ***
+string(34) "Static Example class, Hello World!"
+string(22) "Example class, bar: 42"
+string(22) "Example class, bar: 34"
+===DONE===
diff --git a/ext/reflection/tests/ReflectionMethod_getClosure_error.phpt b/ext/reflection/tests/ReflectionMethod_getClosure_error.phpt
new file mode 100644
index 0000000..d3b9ca3
--- /dev/null
+++ b/ext/reflection/tests/ReflectionMethod_getClosure_error.phpt
@@ -0,0 +1,73 @@
+--TEST--
+Test ReflectionMethod::getClosure() function : error functionality
+--FILE--
+<?php
+/* Prototype : public mixed ReflectionFunction::getClosure()
+ * Description: Returns a dynamically created closure for the method
+ * Source code: ext/reflection/php_reflection.c
+ * Alias to functions:
+ */
+
+echo "*** Testing ReflectionMethod::getClosure() : error conditions ***\n";
+
+class StaticExample
+{
+ static function foo()
+ {
+ var_dump( "Static Example class, Hello World!" );
+ }
+}
+
+class Example
+{
+ public $bar = 42;
+ public function foo()
+ {
+ var_dump( "Example class, bar: " . $this->bar );
+ }
+}
+
+// Initialize classes
+$class = new ReflectionClass( 'Example' );
+$staticclass = new ReflectionClass( 'StaticExample' );
+$method = $class->getMethod( 'foo' );
+$staticmethod = $staticclass->getMethod( 'foo' );
+$object = new Example();
+$fakeobj = new StdClass();
+
+echo "\n-- Testing ReflectionMethod::getClosure() function with more than expected no. of arguments --\n";
+var_dump( $staticmethod->getClosure( 'foobar' ) );
+var_dump( $staticmethod->getClosure( 'foo', 'bar' ) );
+var_dump( $method->getClosure( $object, 'foobar' ) );
+
+echo "\n-- Testing ReflectionMethod::getClosure() function with Zero arguments --\n";
+$closure = $method->getClosure();
+
+echo "\n-- Testing ReflectionMethod::getClosure() function with Zero arguments --\n";
+try {
+ var_dump( $method->getClosure( $fakeobj ) );
+} catch( Exception $e ) {
+ var_dump( $e->getMessage() );
+}
+
+?>
+===DONE===
+--EXPECTF--
+*** Testing ReflectionMethod::getClosure() : error conditions ***
+
+-- Testing ReflectionMethod::getClosure() function with more than expected no. of arguments --
+object(Closure)#%d (0) {
+}
+object(Closure)#%d (0) {
+}
+
+Warning: ReflectionMethod::getClosure() expects exactly 1 parameter, 2 given in %s on line %d
+NULL
+
+-- Testing ReflectionMethod::getClosure() function with Zero arguments --
+
+Warning: ReflectionMethod::getClosure() expects exactly 1 parameter, 0 given in %s on line %d
+
+-- Testing ReflectionMethod::getClosure() function with Zero arguments --
+string(72) "Given object is not an instance of the class this method was declared in"
+===DONE===
diff --git a/ext/reflection/tests/ReflectionMethod_getDeclaringClass_basic.phpt b/ext/reflection/tests/ReflectionMethod_getDeclaringClass_basic.phpt
new file mode 100644
index 0000000..6afc700
--- /dev/null
+++ b/ext/reflection/tests/ReflectionMethod_getDeclaringClass_basic.phpt
@@ -0,0 +1,30 @@
+--TEST--
+ReflectionMethod::getDeclaringClass()
+--FILE--
+<?php
+
+class A {
+ function foo() {}
+}
+
+class B extends A {
+ function bar() {}
+}
+
+$methodInfo = new ReflectionMethod('B', 'foo');
+var_dump($methodInfo->getDeclaringClass());
+
+$methodInfo = new ReflectionMethod('B', 'bar');
+var_dump($methodInfo->getDeclaringClass());
+
+?>
+--EXPECTF--
+object(ReflectionClass)#%d (1) {
+ ["name"]=>
+ string(1) "A"
+}
+object(ReflectionClass)#%d (1) {
+ ["name"]=>
+ string(1) "B"
+}
+
diff --git a/ext/reflection/tests/ReflectionMethod_getDocComment_basic.phpt b/ext/reflection/tests/ReflectionMethod_getDocComment_basic.phpt
new file mode 100644
index 0000000..c01f689
--- /dev/null
+++ b/ext/reflection/tests/ReflectionMethod_getDocComment_basic.phpt
@@ -0,0 +1,113 @@
+--TEST--
+ReflectionMethod::getDocComment()
+--FILE--
+<?php
+/**
+ * My Doc Comment for A
+ */
+class A {
+ /**
+ * My Doc Comment for A::f
+ */
+ function f() {}
+
+ /**
+ * My Doc Comment for A::privf
+ */
+ private function privf() {}
+
+ /** My Doc Comment for A::protStatf */
+ protected static function protStatf() {}
+
+ /**
+
+ * My Doc Comment for A::finalStatPubf
+ */
+ final static public function finalStatPubf() {}
+
+}
+
+
+class B extends A {
+ /*** Not a doc comment */
+ function f() {}
+
+ /** *
+ * My Doc Comment for B::privf
+ */
+
+
+
+
+ private function privf() {}
+
+
+ /** My Doc Comment for B::protStatf
+
+
+
+
+ */
+ protected static function protStatf() {}
+
+}
+
+foreach (array('A', 'B') as $class) {
+ $rc = new ReflectionClass($class);
+ $rms = $rc->getMethods();
+ foreach ($rms as $rm) {
+ echo "\n\n---> Doc comment for $class::" . $rm->getName() . "():\n";
+ var_dump($rm->getDocComment());
+ }
+}
+?>
+--EXPECTF--
+
+
+---> Doc comment for A::f():
+string(%d) "/**
+ * My Doc Comment for A::f
+ */"
+
+
+---> Doc comment for A::privf():
+string(%d) "/**
+ * My Doc Comment for A::privf
+ */"
+
+
+---> Doc comment for A::protStatf():
+string(%d) "/** My Doc Comment for A::protStatf */"
+
+
+---> Doc comment for A::finalStatPubf():
+string(%d) "/**
+
+ * My Doc Comment for A::finalStatPubf
+ */"
+
+
+---> Doc comment for B::f():
+bool(false)
+
+
+---> Doc comment for B::privf():
+string(%d) "/** *
+ * My Doc Comment for B::privf
+ */"
+
+
+---> Doc comment for B::protStatf():
+string(%d) "/** My Doc Comment for B::protStatf
+
+
+
+
+ */"
+
+
+---> Doc comment for B::finalStatPubf():
+string(%d) "/**
+
+ * My Doc Comment for A::finalStatPubf
+ */"
diff --git a/ext/reflection/tests/ReflectionMethod_getDocComment_error.phpt b/ext/reflection/tests/ReflectionMethod_getDocComment_error.phpt
new file mode 100644
index 0000000..02de25b
--- /dev/null
+++ b/ext/reflection/tests/ReflectionMethod_getDocComment_error.phpt
@@ -0,0 +1,15 @@
+--TEST--
+ReflectionMethod::getDocComment() errors
+--FILE--
+<?php
+class C { function f() {} }
+$rc = new ReflectionMethod('C::f');
+var_dump($rc->getDocComment(null));
+var_dump($rc->getDocComment('X'));
+?>
+--EXPECTF--
+Warning: ReflectionFunctionAbstract::getDocComment() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionFunctionAbstract::getDocComment() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
diff --git a/ext/reflection/tests/ReflectionMethod_getModifiers_basic.phpt b/ext/reflection/tests/ReflectionMethod_getModifiers_basic.phpt
new file mode 100644
index 0000000..72baa53
--- /dev/null
+++ b/ext/reflection/tests/ReflectionMethod_getModifiers_basic.phpt
@@ -0,0 +1,242 @@
+--TEST--
+ReflectionMethod::getModifiers()
+--FILE--
+<?php
+
+function reflectMethodModifiers($class) {
+ $classInfo = new reflectionClass($class);
+ $methodArray = $classInfo->getMethods();
+
+ foreach ($methodArray as $method) {
+ echo "Modifiers for method $method->class::$method->name():\n";
+ printf("0x%08x\n", $method->getModifiers());
+ echo "\n\n";
+ }
+}
+
+class TestClass
+{
+ public function foo() {
+ echo "Called foo()\n";
+ }
+
+ static function stat() {
+ echo "Called stat()\n";
+ }
+
+ private function priv() {
+ echo "Called priv()\n";
+ }
+
+ protected function prot() {}
+
+ public final function fin() {}
+
+ public function __destruct() {}
+
+ public function __call($a, $b) {}
+
+ public function __clone() {}
+
+ public function __get($a) {}
+
+ public function __set($a, $b) {}
+
+ public function __unset($a) {}
+
+ public function __isset($a) {}
+
+ public function __tostring() {}
+
+ public function __sleep() {}
+
+ public function __wakeup() {}
+
+ public function __set_state() {}
+
+ public function __autoload() {}
+}
+
+class DerivedClass extends TestClass {}
+
+interface TestInterface {
+ public function int();
+ public function __clone();
+}
+
+abstract class AbstractClass {
+ public abstract function foo();
+}
+
+
+
+reflectMethodModifiers("TestClass");
+reflectMethodModifiers("DerivedClass");
+reflectMethodModifiers("TestInterface");
+reflectMethodModifiers("AbstractClass");
+
+echo "Wrong number of params:\n";
+$a = new ReflectionMethod('TestClass::foo');
+$a->getModifiers(1);
+
+$a = new ReflectionMethod('ReflectionMethod::getModifiers');
+
+echo "\nReflectionMethod::getModifiers() modifiers:\n";
+printf("0x%08x\n", $a->getModifiers());
+
+?>
+--EXPECTF--
+Modifiers for method TestClass::foo():
+0x08010100
+
+
+Modifiers for method TestClass::stat():
+0x08000101
+
+
+Modifiers for method TestClass::priv():
+0x08010400
+
+
+Modifiers for method TestClass::prot():
+0x08010200
+
+
+Modifiers for method TestClass::fin():
+0x08010104
+
+
+Modifiers for method TestClass::__destruct():
+0x08004100
+
+
+Modifiers for method TestClass::__call():
+0x08000100
+
+
+Modifiers for method TestClass::__clone():
+0x08008100
+
+
+Modifiers for method TestClass::__get():
+0x08000100
+
+
+Modifiers for method TestClass::__set():
+0x08000100
+
+
+Modifiers for method TestClass::__unset():
+0x08000100
+
+
+Modifiers for method TestClass::__isset():
+0x08000100
+
+
+Modifiers for method TestClass::__tostring():
+0x08000100
+
+
+Modifiers for method TestClass::__sleep():
+0x08010100
+
+
+Modifiers for method TestClass::__wakeup():
+0x08010100
+
+
+Modifiers for method TestClass::__set_state():
+0x08010100
+
+
+Modifiers for method TestClass::__autoload():
+0x08010100
+
+
+Modifiers for method TestClass::foo():
+0x08010100
+
+
+Modifiers for method TestClass::stat():
+0x08000101
+
+
+Modifiers for method TestClass::priv():
+0x08010400
+
+
+Modifiers for method TestClass::prot():
+0x08010200
+
+
+Modifiers for method TestClass::fin():
+0x08010104
+
+
+Modifiers for method TestClass::__destruct():
+0x08004100
+
+
+Modifiers for method TestClass::__call():
+0x08000100
+
+
+Modifiers for method TestClass::__clone():
+0x08008100
+
+
+Modifiers for method TestClass::__get():
+0x08000100
+
+
+Modifiers for method TestClass::__set():
+0x08000100
+
+
+Modifiers for method TestClass::__unset():
+0x08000100
+
+
+Modifiers for method TestClass::__isset():
+0x08000100
+
+
+Modifiers for method TestClass::__tostring():
+0x08000100
+
+
+Modifiers for method TestClass::__sleep():
+0x08010100
+
+
+Modifiers for method TestClass::__wakeup():
+0x08010100
+
+
+Modifiers for method TestClass::__set_state():
+0x08010100
+
+
+Modifiers for method TestClass::__autoload():
+0x08010100
+
+
+Modifiers for method TestInterface::int():
+0x08000102
+
+
+Modifiers for method TestInterface::__clone():
+0x08000102
+
+
+Modifiers for method AbstractClass::foo():
+0x08010102
+
+
+Wrong number of params:
+
+Warning: ReflectionMethod::getModifiers() expects exactly 0 parameters, 1 given in %sReflectionMethod_getModifiers_basic.php on line %d
+
+ReflectionMethod::getModifiers() modifiers:
+0x00000100
diff --git a/ext/reflection/tests/ReflectionMethod_getStaticVariables_basic.phpt b/ext/reflection/tests/ReflectionMethod_getStaticVariables_basic.phpt
new file mode 100644
index 0000000..4c50b96
--- /dev/null
+++ b/ext/reflection/tests/ReflectionMethod_getStaticVariables_basic.phpt
@@ -0,0 +1,63 @@
+--TEST--
+ReflectionMethod::getStaticVariables()
+--FILE--
+<?php
+
+class TestClass {
+ public function foo() {
+ static $c;
+ static $a = 1;
+ static $b = "hello";
+ $d = 5;
+ }
+
+ private function bar() {
+ static $a = 1;
+ }
+
+ public function noStatics() {
+ $a = 54;
+ }
+}
+
+echo "Public method:\n";
+$methodInfo = new ReflectionMethod('TestClass::foo');
+var_dump($methodInfo->getStaticVariables());
+
+echo "\nPrivate method:\n";
+$methodInfo = new ReflectionMethod('TestClass::bar');
+var_dump($methodInfo->getStaticVariables());
+
+echo "\nMethod with no static variables:\n";
+$methodInfo = new ReflectionMethod('TestClass::noStatics');
+var_dump($methodInfo->getStaticVariables());
+
+echo "\nInternal Method:\n";
+$methodInfo = new ReflectionMethod('ReflectionClass::getName');
+var_dump($methodInfo->getStaticVariables());
+
+?>
+--EXPECT--
+Public method:
+array(3) {
+ ["c"]=>
+ NULL
+ ["a"]=>
+ int(1)
+ ["b"]=>
+ string(5) "hello"
+}
+
+Private method:
+array(1) {
+ ["a"]=>
+ int(1)
+}
+
+Method with no static variables:
+array(0) {
+}
+
+Internal Method:
+array(0) {
+}
diff --git a/ext/reflection/tests/ReflectionMethod_invokeArgs_basic.phpt b/ext/reflection/tests/ReflectionMethod_invokeArgs_basic.phpt
new file mode 100644
index 0000000..24282cd
--- /dev/null
+++ b/ext/reflection/tests/ReflectionMethod_invokeArgs_basic.phpt
@@ -0,0 +1,73 @@
+--TEST--
+ReflectionMethod::invokeArgs()
+--FILE--
+<?php
+
+class TestClass {
+ public $prop = 2;
+
+ public function foo() {
+ echo "Called foo(), property = $this->prop\n";
+ var_dump($this);
+ return "Return Val";
+ }
+
+ public function willThrow() {
+ throw new Exception("Called willThrow()");
+ }
+
+ public function methodWithArgs($a, $b) {
+ echo "Called methodWithArgs($a, $b)\n";
+ }
+}
+
+
+$testClassInstance = new TestClass();
+$testClassInstance->prop = "Hello";
+
+$foo = new ReflectionMethod($testClassInstance, 'foo');
+$methodWithArgs = new ReflectionMethod('TestClass', 'methodWithArgs');
+$methodThatThrows = new ReflectionMethod("TestClass::willThrow");
+
+
+echo "Public method:\n";
+
+var_dump($foo->invokeArgs($testClassInstance, array()));
+var_dump($foo->invokeArgs($testClassInstance, array(true)));
+
+echo "\nMethod with args:\n";
+
+var_dump($methodWithArgs->invokeArgs($testClassInstance, array(1, "arg2")));
+var_dump($methodWithArgs->invokeArgs($testClassInstance, array(1, "arg2", 3)));
+
+echo "\nMethod that throws an exception:\n";
+try {
+ $methodThatThrows->invokeArgs($testClassInstance, array());
+} catch (Exception $e) {
+ var_dump($e->getMessage());
+}
+
+?>
+--EXPECTF--
+Public method:
+Called foo(), property = Hello
+object(TestClass)#%d (1) {
+ ["prop"]=>
+ string(5) "Hello"
+}
+string(10) "Return Val"
+Called foo(), property = Hello
+object(TestClass)#%d (1) {
+ ["prop"]=>
+ string(5) "Hello"
+}
+string(10) "Return Val"
+
+Method with args:
+Called methodWithArgs(1, arg2)
+NULL
+Called methodWithArgs(1, arg2)
+NULL
+
+Method that throws an exception:
+string(18) "Called willThrow()"
diff --git a/ext/reflection/tests/ReflectionMethod_invokeArgs_error1.phpt b/ext/reflection/tests/ReflectionMethod_invokeArgs_error1.phpt
new file mode 100644
index 0000000..ac97e3e
--- /dev/null
+++ b/ext/reflection/tests/ReflectionMethod_invokeArgs_error1.phpt
@@ -0,0 +1,36 @@
+--TEST--
+ReflectionMethod:invokeArgs() errors
+--FILE--
+<?php
+
+class TestClass {
+
+ public function methodWithArgs($a, $b) {
+ echo "Called methodWithArgs($a, $b)\n";
+ }
+}
+
+abstract class AbstractClass {
+ abstract function foo();
+}
+
+$methodWithArgs = new ReflectionMethod('TestClass', 'methodWithArgs');
+
+$testClassInstance = new TestClass();
+
+echo "\nMethod with args:\n";
+var_dump($methodWithArgs->invokeArgs($testClassInstance, array()));
+
+?>
+--EXPECTF--
+Method with args:
+
+Warning: Missing argument 1 for TestClass::methodWithArgs() in %s on line %d
+
+Warning: Missing argument 2 for TestClass::methodWithArgs() in %s on line %d
+
+Notice: Undefined variable: a in %s on line %d
+
+Notice: Undefined variable: b in %s on line %d
+Called methodWithArgs(, )
+NULL
diff --git a/ext/reflection/tests/ReflectionMethod_invokeArgs_error2.phpt b/ext/reflection/tests/ReflectionMethod_invokeArgs_error2.phpt
new file mode 100644
index 0000000..5fc7564
--- /dev/null
+++ b/ext/reflection/tests/ReflectionMethod_invokeArgs_error2.phpt
@@ -0,0 +1,27 @@
+--TEST--
+ReflectionMethod::invokeArgs() further errors
+--FILE--
+<?php
+
+class TestClass {
+
+ public function foo() {
+ echo "Called foo()\n";
+ var_dump($this);
+ return "Return Val";
+ }
+}
+
+$foo = new ReflectionMethod('TestClass', 'foo');
+
+$testClassInstance = new TestClass();
+
+try {
+ var_dump($foo->invokeArgs($testClassInstance, true));
+} catch (Exception $e) {
+ var_dump($e->getMessage());
+}
+
+?>
+--EXPECTF--
+Catchable fatal error: Argument 2 passed to ReflectionMethod::invokeArgs() must be of the type array, boolean given in %s on line %d
diff --git a/ext/reflection/tests/ReflectionMethod_invokeArgs_error3.phpt b/ext/reflection/tests/ReflectionMethod_invokeArgs_error3.phpt
new file mode 100644
index 0000000..513cc18
--- /dev/null
+++ b/ext/reflection/tests/ReflectionMethod_invokeArgs_error3.phpt
@@ -0,0 +1,117 @@
+--TEST--
+ReflectionMethod::invokeArgs() further errors
+--FILE--
+<?php
+
+class TestClass {
+ public $prop = 2;
+
+ public function foo() {
+ echo "Called foo(), property = $this->prop\n";
+ var_dump($this);
+ return "Return Val";
+ }
+
+ public static function staticMethod() {
+ echo "Called staticMethod()\n";
+ var_dump($this);
+ }
+
+ private static function privateMethod() {
+ echo "Called privateMethod()\n";
+ }
+}
+
+abstract class AbstractClass {
+ abstract function foo();
+}
+
+$testClassInstance = new TestClass();
+$testClassInstance->prop = "Hello";
+
+$foo = new ReflectionMethod($testClassInstance, 'foo');
+$staticMethod = new ReflectionMethod('TestClass::staticMethod');
+$privateMethod = new ReflectionMethod("TestClass::privateMethod");
+
+echo "Wrong number of parameters:\n";
+var_dump($foo->invokeArgs());
+var_dump($foo->invokeArgs(true));
+
+echo "\nNon-instance:\n";
+try {
+ var_dump($foo->invokeArgs(new stdClass(), array()));
+} catch (ReflectionException $e) {
+ var_dump($e->getMessage());
+}
+
+echo "\nNon-object:\n";
+var_dump($foo->invokeArgs(true, array()));
+
+echo "\nStatic method:\n";
+
+var_dump($staticMethod->invokeArgs());
+var_dump($staticMethod->invokeArgs(true));
+var_dump($staticMethod->invokeArgs(true, array()));
+var_dump($staticMethod->invokeArgs(null, array()));
+
+echo "\nPrivate method:\n";
+try {
+ var_dump($privateMethod->invokeArgs($testClassInstance, array()));
+} catch (ReflectionException $e) {
+ var_dump($e->getMessage());
+}
+
+echo "\nAbstract method:\n";
+$abstractMethod = new ReflectionMethod("AbstractClass::foo");
+try {
+ $abstractMethod->invokeArgs($testClassInstance, array());
+} catch (ReflectionException $e) {
+ var_dump($e->getMessage());
+}
+try {
+ $abstractMethod->invokeArgs(true);
+} catch (ReflectionException $e) {
+ var_dump($e->getMessage());
+}
+
+?>
+--EXPECTF--
+Wrong number of parameters:
+
+Warning: ReflectionMethod::invokeArgs() expects exactly 2 parameters, 0 given in %s on line %d
+NULL
+
+Warning: ReflectionMethod::invokeArgs() expects exactly 2 parameters, 1 given in %s on line %d
+NULL
+
+Non-instance:
+string(72) "Given object is not an instance of the class this method was declared in"
+
+Non-object:
+
+Warning: ReflectionMethod::invokeArgs() expects parameter 1 to be object, boolean given in %s on line %d
+NULL
+
+Static method:
+
+Warning: ReflectionMethod::invokeArgs() expects exactly 2 parameters, 0 given in %s on line %d
+NULL
+
+Warning: ReflectionMethod::invokeArgs() expects exactly 2 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionMethod::invokeArgs() expects parameter 1 to be object, boolean given in %s on line %d
+NULL
+Called staticMethod()
+
+Notice: Undefined variable: this in %s on line %d
+NULL
+NULL
+
+Private method:
+string(86) "Trying to invoke private method TestClass::privateMethod() from scope ReflectionMethod"
+
+Abstract method:
+string(53) "Trying to invoke abstract method AbstractClass::foo()"
+
+Warning: ReflectionMethod::invokeArgs() expects exactly 2 parameters, 1 given in %s on line %d
diff --git a/ext/reflection/tests/ReflectionMethod_invoke_basic.phpt b/ext/reflection/tests/ReflectionMethod_invoke_basic.phpt
new file mode 100644
index 0000000..cbf358c
--- /dev/null
+++ b/ext/reflection/tests/ReflectionMethod_invoke_basic.phpt
@@ -0,0 +1,108 @@
+--TEST--
+ReflectionMethod::invoke()
+--FILE--
+<?php
+
+class TestClass {
+ public $prop = 2;
+
+ public function foo() {
+ echo "Called foo(), property = $this->prop\n";
+ var_dump($this);
+ return "Return Val";
+ }
+
+ public function willThrow() {
+ throw new Exception("Called willThrow()");
+ }
+
+ public function methodWithArgs($a, $b) {
+ echo "Called methodWithArgs($a, $b)\n";
+ }
+
+ public static function staticMethod() {
+ echo "Called staticMethod()\n";
+ var_dump($this);
+ }
+
+ private static function privateMethod() {
+ echo "Called privateMethod()\n";
+ }
+}
+
+abstract class AbstractClass {
+ abstract function foo();
+}
+
+$foo = new ReflectionMethod('TestClass', 'foo');
+$methodWithArgs = new ReflectionMethod('TestClass', 'methodWithArgs');
+$staticMethod = new ReflectionMethod('TestClass::staticMethod');
+$privateMethod = new ReflectionMethod("TestClass::privateMethod");
+$methodThatThrows = new ReflectionMethod("TestClass::willThrow");
+
+$testClassInstance = new TestClass();
+$testClassInstance->prop = "Hello";
+
+echo "Public method:\n";
+
+var_dump($foo->invoke($testClassInstance));
+
+var_dump($foo->invoke($testClassInstance, true));
+
+echo "\nMethod with args:\n";
+
+var_dump($methodWithArgs->invoke($testClassInstance, 1, "arg2"));
+var_dump($methodWithArgs->invoke($testClassInstance, 1, "arg2", 3));
+
+echo "\nStatic method:\n";
+
+var_dump($staticMethod->invoke());
+var_dump($staticMethod->invoke(true));
+var_dump($staticMethod->invoke(new stdClass()));
+
+echo "\nMethod that throws an exception:\n";
+try {
+ var_dump($methodThatThrows->invoke($testClassInstance));
+} catch (Exception $exc) {
+ var_dump($exc->getMessage());
+}
+
+?>
+--EXPECTF--
+Public method:
+Called foo(), property = Hello
+object(TestClass)#%d (1) {
+ ["prop"]=>
+ string(5) "Hello"
+}
+string(10) "Return Val"
+Called foo(), property = Hello
+object(TestClass)#%d (1) {
+ ["prop"]=>
+ string(5) "Hello"
+}
+string(10) "Return Val"
+
+Method with args:
+Called methodWithArgs(1, arg2)
+NULL
+Called methodWithArgs(1, arg2)
+NULL
+
+Static method:
+
+Warning: ReflectionMethod::invoke() expects at least 1 parameter, 0 given in %s on line %d
+NULL
+Called staticMethod()
+
+Notice: Undefined variable: this in %s on line %d
+NULL
+NULL
+Called staticMethod()
+
+Notice: Undefined variable: this in %s on line %d
+NULL
+NULL
+
+Method that throws an exception:
+string(18) "Called willThrow()"
diff --git a/ext/reflection/tests/ReflectionMethod_invoke_error1.phpt b/ext/reflection/tests/ReflectionMethod_invoke_error1.phpt
new file mode 100644
index 0000000..758f1ac
--- /dev/null
+++ b/ext/reflection/tests/ReflectionMethod_invoke_error1.phpt
@@ -0,0 +1,71 @@
+--TEST--
+ReflectionMethod::invoke() errors
+--FILE--
+<?php
+
+class TestClass {
+ public $prop = 2;
+
+ public function foo() {
+ echo "Called foo(), property = $this->prop\n";
+ var_dump($this);
+ return "Return Val";
+ }
+
+ private static function privateMethod() {
+ echo "Called privateMethod()\n";
+ }
+}
+
+abstract class AbstractClass {
+ abstract function foo();
+}
+
+$foo = new ReflectionMethod('TestClass', 'foo');
+$privateMethod = new ReflectionMethod("TestClass::privateMethod");
+
+$testClassInstance = new TestClass();
+$testClassInstance->prop = "Hello";
+
+echo "invoke() on a non-object:\n";
+try {
+ var_dump($foo->invoke(true));
+} catch (ReflectionException $e) {
+ var_dump($e->getMessage());
+}
+
+echo "\ninvoke() on a non-instance:\n";
+try {
+ var_dump($foo->invoke(new stdClass()));
+} catch (ReflectionException $e) {
+ var_dump($e->getMessage());
+}
+
+echo "\nPrivate method:\n";
+try {
+ var_dump($privateMethod->invoke($testClassInstance));
+} catch (ReflectionException $e) {
+ var_dump($e->getMessage());
+}
+
+echo "\nAbstract method:\n";
+$abstractMethod = new ReflectionMethod("AbstractClass::foo");
+try {
+ $abstractMethod->invoke(true);
+} catch (ReflectionException $e) {
+ var_dump($e->getMessage());
+}
+
+?>
+--EXPECTF--
+invoke() on a non-object:
+string(29) "Non-object passed to Invoke()"
+
+invoke() on a non-instance:
+string(72) "Given object is not an instance of the class this method was declared in"
+
+Private method:
+string(86) "Trying to invoke private method TestClass::privateMethod() from scope ReflectionMethod"
+
+Abstract method:
+string(53) "Trying to invoke abstract method AbstractClass::foo()"
diff --git a/ext/reflection/tests/ReflectionMethod_invoke_error2.phpt b/ext/reflection/tests/ReflectionMethod_invoke_error2.phpt
new file mode 100644
index 0000000..a070c8f
--- /dev/null
+++ b/ext/reflection/tests/ReflectionMethod_invoke_error2.phpt
@@ -0,0 +1,32 @@
+--TEST--
+ReflectionMethod::invoke() further errors
+--FILE--
+<?php
+
+class TestClass {
+
+ public function methodWithArgs($a, $b) {
+ echo "Called methodWithArgs($a, $b)\n";
+ }
+}
+
+$methodWithArgs = new ReflectionMethod('TestClass', 'methodWithArgs');
+
+$testClassInstance = new TestClass();
+
+echo "\nMethod with args:\n";
+var_dump($methodWithArgs->invoke($testClassInstance));
+
+?>
+--EXPECTF--
+Method with args:
+
+Warning: Missing argument 1 for TestClass::methodWithArgs() in %s on line %d
+
+Warning: Missing argument 2 for TestClass::methodWithArgs() in %s on line %d
+
+Notice: Undefined variable: a in %s on line %d
+
+Notice: Undefined variable: b in %s on line %d
+Called methodWithArgs(, )
+NULL
diff --git a/ext/reflection/tests/ReflectionMethod_returnsReference_basic.phpt b/ext/reflection/tests/ReflectionMethod_returnsReference_basic.phpt
new file mode 100644
index 0000000..f1fd205
--- /dev/null
+++ b/ext/reflection/tests/ReflectionMethod_returnsReference_basic.phpt
@@ -0,0 +1,23 @@
+--TEST--
+ReflectionMethod::returnsReference()
+--FILE--
+<?php
+
+class TestClass {
+ public function &foo() {
+ }
+
+ private function bar() {
+ }
+}
+
+$methodInfo = new ReflectionMethod('TestClass::foo');
+var_dump($methodInfo->returnsReference());
+
+$methodInfo = new ReflectionMethod('TestClass::bar');
+var_dump($methodInfo->returnsReference());
+
+?>
+--EXPECT--
+bool(true)
+bool(false)
diff --git a/ext/reflection/tests/ReflectionMethod_setAccessible.phpt b/ext/reflection/tests/ReflectionMethod_setAccessible.phpt
new file mode 100644
index 0000000..79a8fbe
--- /dev/null
+++ b/ext/reflection/tests/ReflectionMethod_setAccessible.phpt
@@ -0,0 +1,111 @@
+--TEST--
+Test ReflectionMethod::setAccessible().
+--FILE--
+<?php
+class A {
+ private function aPrivate($a) { print __METHOD__ . "\n"; }
+ private static function aPrivateStatic($a) { print __METHOD__ . "\n"; }
+ protected function aProtected($a) { print __METHOD__ . "\n"; }
+ protected static function aProtectedStatic($a) { print __METHOD__ . "\n"; }
+}
+
+$private = new ReflectionMethod('A', 'aPrivate');
+$privateStatic = new ReflectionMethod('A', 'aPrivateStatic');
+$protected = new ReflectionMethod('A', 'aProtected');
+$protectedStatic = new ReflectionMethod('A', 'aProtectedStatic');
+
+try {
+ $private->invoke(new A, NULL);
+}
+
+catch (ReflectionException $e) {
+ var_dump($e->getMessage());
+}
+
+try {
+ $private->invokeArgs(new A, array(NULL));
+}
+
+catch (ReflectionException $e) {
+ var_dump($e->getMessage());
+}
+
+try {
+ $privateStatic->invoke(NULL, NULL);
+}
+
+catch (ReflectionException $e) {
+ var_dump($e->getMessage());
+}
+
+try {
+ $privateStatic->invokeArgs(NULL, array(NULL));
+}
+
+catch (ReflectionException $e) {
+ var_dump($e->getMessage());
+}
+
+try {
+ $protected->invoke(new A, NULL);
+}
+
+catch (ReflectionException $e) {
+ var_dump($e->getMessage());
+}
+
+try {
+ $protected->invokeArgs(new A, array(NULL));
+}
+
+catch (ReflectionException $e) {
+ var_dump($e->getMessage());
+}
+
+try {
+ $protectedStatic->invoke(NULL, NULL);
+}
+
+catch (ReflectionException $e) {
+ var_dump($e->getMessage());
+}
+
+try {
+ $protectedStatic->invokeArgs(NULL, array(NULL));
+}
+
+catch (ReflectionException $e) {
+ var_dump($e->getMessage());
+}
+
+$private->setAccessible(TRUE);
+$privateStatic->setAccessible(TRUE);
+$protected->setAccessible(TRUE);
+$protectedStatic->setAccessible(TRUE);
+
+$private->invoke(new A, NULL);
+$private->invokeArgs(new A, array(NULL));
+$privateStatic->invoke(NULL, NULL);
+$privateStatic->invokeArgs(NULL, array(NULL));
+$protected->invoke(new A, NULL);
+$protected->invokeArgs(new A, array(NULL));
+$protectedStatic->invoke(NULL, NULL);
+$protectedStatic->invokeArgs(NULL, array(NULL));
+?>
+--EXPECT--
+string(73) "Trying to invoke private method A::aPrivate() from scope ReflectionMethod"
+string(73) "Trying to invoke private method A::aPrivate() from scope ReflectionMethod"
+string(79) "Trying to invoke private method A::aPrivateStatic() from scope ReflectionMethod"
+string(79) "Trying to invoke private method A::aPrivateStatic() from scope ReflectionMethod"
+string(77) "Trying to invoke protected method A::aProtected() from scope ReflectionMethod"
+string(77) "Trying to invoke protected method A::aProtected() from scope ReflectionMethod"
+string(83) "Trying to invoke protected method A::aProtectedStatic() from scope ReflectionMethod"
+string(83) "Trying to invoke protected method A::aProtectedStatic() from scope ReflectionMethod"
+A::aPrivate
+A::aPrivate
+A::aPrivateStatic
+A::aPrivateStatic
+A::aProtected
+A::aProtected
+A::aProtectedStatic
+A::aProtectedStatic
diff --git a/ext/reflection/tests/ReflectionObject_FileInfo_basic.phpt b/ext/reflection/tests/ReflectionObject_FileInfo_basic.phpt
new file mode 100644
index 0000000..00214dc
--- /dev/null
+++ b/ext/reflection/tests/ReflectionObject_FileInfo_basic.phpt
@@ -0,0 +1,25 @@
+--TEST--
+ReflectionObject::getFileName(), ReflectionObject::getStartLine(), ReflectionObject::getEndLine() - basic function
+--FILE--
+<?php
+$rc = new ReflectionObject(new C);
+var_dump($rc->getFileName());
+var_dump($rc->getStartLine());
+var_dump($rc->getEndLine());
+
+$rc = new ReflectionObject(new stdclass);
+var_dump($rc->getFileName());
+var_dump($rc->getStartLine());
+var_dump($rc->getEndLine());
+
+Class C {
+
+}
+?>
+--EXPECTF--
+string(%d) "%sReflectionObject_FileInfo_basic.php"
+int(12)
+int(14)
+bool(false)
+bool(false)
+bool(false)
diff --git a/ext/reflection/tests/ReflectionObject_FileInfo_error.phpt b/ext/reflection/tests/ReflectionObject_FileInfo_error.phpt
new file mode 100644
index 0000000..d30e677
--- /dev/null
+++ b/ext/reflection/tests/ReflectionObject_FileInfo_error.phpt
@@ -0,0 +1,37 @@
+--TEST--
+ReflectionObject::getFileName(), ReflectionObject::getStartLine(), ReflectionObject::getEndLine() -invalid aparams
+--FILE--
+<?php
+Class C { }
+
+$rc = new ReflectionObject(new C);
+$methods = array("getFileName", "getStartLine", "getEndLine");
+
+foreach ($methods as $method) {
+ var_dump($rc->$method());
+ var_dump($rc->$method(null));
+ var_dump($rc->$method('X', 0));
+}
+?>
+--EXPECTF--
+string(%d) "%s"
+
+Warning: ReflectionClass::getFileName() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionClass::getFileName() expects exactly 0 parameters, 2 given in %s on line %d
+NULL
+int(2)
+
+Warning: ReflectionClass::getStartLine() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionClass::getStartLine() expects exactly 0 parameters, 2 given in %s on line %d
+NULL
+int(2)
+
+Warning: ReflectionClass::getEndLine() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionClass::getEndLine() expects exactly 0 parameters, 2 given in %s on line %d
+NULL
diff --git a/ext/reflection/tests/ReflectionObject___toString_basic1.phpt b/ext/reflection/tests/ReflectionObject___toString_basic1.phpt
new file mode 100644
index 0000000..fefa220
--- /dev/null
+++ b/ext/reflection/tests/ReflectionObject___toString_basic1.phpt
@@ -0,0 +1,36 @@
+--TEST--
+ReflectionObject::__toString() : very basic test with no dynamic properties
+--FILE--
+<?php
+
+class Foo {
+ public $bar = 1;
+}
+$f = new foo;
+
+echo new ReflectionObject($f);
+
+?>
+--EXPECTF--
+Object of class [ <user> class Foo ] {
+ @@ %s 3-5
+
+ - Constants [0] {
+ }
+
+ - Static properties [0] {
+ }
+
+ - Static methods [0] {
+ }
+
+ - Properties [1] {
+ Property [ <default> public $bar ]
+ }
+
+ - Dynamic properties [0] {
+ }
+
+ - Methods [0] {
+ }
+} \ No newline at end of file
diff --git a/ext/reflection/tests/ReflectionObject___toString_basic2.phpt b/ext/reflection/tests/ReflectionObject___toString_basic2.phpt
new file mode 100644
index 0000000..332386a
--- /dev/null
+++ b/ext/reflection/tests/ReflectionObject___toString_basic2.phpt
@@ -0,0 +1,39 @@
+--TEST--
+ReflectionObject::__toString() : very basic test with dynamic properties
+--FILE--
+<?php
+
+class Foo {
+ public $bar = 1;
+}
+$f = new foo;
+$f->dynProp = 'hello';
+$f->dynProp2 = 'hello again';
+echo new ReflectionObject($f);
+
+?>
+--EXPECTF--
+Object of class [ <user> class Foo ] {
+ @@ %s 3-5
+
+ - Constants [0] {
+ }
+
+ - Static properties [0] {
+ }
+
+ - Static methods [0] {
+ }
+
+ - Properties [1] {
+ Property [ <default> public $bar ]
+ }
+
+ - Dynamic properties [2] {
+ Property [ <dynamic> public $dynProp ]
+ Property [ <dynamic> public $dynProp2 ]
+ }
+
+ - Methods [0] {
+ }
+} \ No newline at end of file
diff --git a/ext/reflection/tests/ReflectionObject_constructor_basic.phpt b/ext/reflection/tests/ReflectionObject_constructor_basic.phpt
new file mode 100644
index 0000000..8f4a908
--- /dev/null
+++ b/ext/reflection/tests/ReflectionObject_constructor_basic.phpt
@@ -0,0 +1,28 @@
+--TEST--
+ReflectionObject::__construct - basic function test
+--FILE--
+<?php
+$r1 = new ReflectionObject(new stdClass);
+var_dump($r1);
+
+class C { }
+$myInstance = new C;
+$r2 = new ReflectionObject($myInstance);
+var_dump($r2);
+
+$r3 = new ReflectionObject($r2);
+var_dump($r3);
+?>
+--EXPECTF--
+object(ReflectionObject)#%d (1) {
+ ["name"]=>
+ string(8) "stdClass"
+}
+object(ReflectionObject)#%d (1) {
+ ["name"]=>
+ string(1) "C"
+}
+object(ReflectionObject)#%d (1) {
+ ["name"]=>
+ string(16) "ReflectionObject"
+}
diff --git a/ext/reflection/tests/ReflectionObject_constructor_error.phpt b/ext/reflection/tests/ReflectionObject_constructor_error.phpt
new file mode 100644
index 0000000..baa6129
--- /dev/null
+++ b/ext/reflection/tests/ReflectionObject_constructor_error.phpt
@@ -0,0 +1,49 @@
+--TEST--
+ReflectionObject::__construct - invalid arguments
+--FILE--
+<?php
+
+var_dump(new ReflectionObject());
+var_dump(new ReflectionObject('stdClass'));
+$myInstance = new stdClass;
+var_dump(new ReflectionObject($myInstance, $myInstance));
+var_dump(new ReflectionObject(0));
+var_dump(new ReflectionObject(null));
+var_dump(new ReflectionObject(array(1,2)));
+?>
+--EXPECTF--
+Warning: ReflectionObject::__construct() expects exactly 1 parameter, 0 given in %s on line 3
+object(ReflectionObject)#%d (1) {
+ ["name"]=>
+ string(0) ""
+}
+
+Warning: ReflectionObject::__construct() expects parameter 1 to be object, string given in %s on line 4
+object(ReflectionObject)#%d (1) {
+ ["name"]=>
+ string(0) ""
+}
+
+Warning: ReflectionObject::__construct() expects exactly 1 parameter, 2 given in %s on line 6
+object(ReflectionObject)#%d (1) {
+ ["name"]=>
+ string(0) ""
+}
+
+Warning: ReflectionObject::__construct() expects parameter 1 to be object, integer given in %s on line 7
+object(ReflectionObject)#%d (1) {
+ ["name"]=>
+ string(0) ""
+}
+
+Warning: ReflectionObject::__construct() expects parameter 1 to be object, null given in %s on line 8
+object(ReflectionObject)#%d (1) {
+ ["name"]=>
+ string(0) ""
+}
+
+Warning: ReflectionObject::__construct() expects parameter 1 to be object, array given in %s on line 9
+object(ReflectionObject)#%d (1) {
+ ["name"]=>
+ string(0) ""
+}
diff --git a/ext/reflection/tests/ReflectionObject_export_basic1.phpt b/ext/reflection/tests/ReflectionObject_export_basic1.phpt
new file mode 100644
index 0000000..f7dfef8
--- /dev/null
+++ b/ext/reflection/tests/ReflectionObject_export_basic1.phpt
@@ -0,0 +1,36 @@
+--TEST--
+ReflectionObject::export() : very basic test with no dynamic properties
+--FILE--
+<?php
+
+class Foo {
+ public $bar = 1;
+}
+$f = new foo;
+
+ReflectionObject::export($f);
+
+?>
+--EXPECTF--
+Object of class [ <user> class Foo ] {
+ @@ %s 3-5
+
+ - Constants [0] {
+ }
+
+ - Static properties [0] {
+ }
+
+ - Static methods [0] {
+ }
+
+ - Properties [1] {
+ Property [ <default> public $bar ]
+ }
+
+ - Dynamic properties [0] {
+ }
+
+ - Methods [0] {
+ }
+} \ No newline at end of file
diff --git a/ext/reflection/tests/ReflectionObject_export_basic2.phpt b/ext/reflection/tests/ReflectionObject_export_basic2.phpt
new file mode 100644
index 0000000..277f06e
--- /dev/null
+++ b/ext/reflection/tests/ReflectionObject_export_basic2.phpt
@@ -0,0 +1,39 @@
+--TEST--
+ReflectionObject::export() : very basic test with dynamic properties
+--FILE--
+<?php
+
+class Foo {
+ public $bar = 1;
+}
+$f = new foo;
+$f->dynProp = 'hello';
+$f->dynProp2 = 'hello again';
+ReflectionObject::export($f);
+
+?>
+--EXPECTF--
+Object of class [ <user> class Foo ] {
+ @@ %s 3-5
+
+ - Constants [0] {
+ }
+
+ - Static properties [0] {
+ }
+
+ - Static methods [0] {
+ }
+
+ - Properties [1] {
+ Property [ <default> public $bar ]
+ }
+
+ - Dynamic properties [2] {
+ Property [ <dynamic> public $dynProp ]
+ Property [ <dynamic> public $dynProp2 ]
+ }
+
+ - Methods [0] {
+ }
+} \ No newline at end of file
diff --git a/ext/reflection/tests/ReflectionObject_export_basic3.phpt b/ext/reflection/tests/ReflectionObject_export_basic3.phpt
new file mode 100644
index 0000000..7c1da34
--- /dev/null
+++ b/ext/reflection/tests/ReflectionObject_export_basic3.phpt
@@ -0,0 +1,38 @@
+--TEST--
+ReflectionObject::export() - ensure dynamic property with same name as inherited private property is shown.
+--FILE--
+<?php
+class C {
+ private $p = 1;
+}
+
+class D extends C{
+}
+
+$Obj = new D;
+$Obj->p = 'value';
+ReflectionObject::export($Obj)
+?>
+--EXPECTF--
+Object of class [ <user> class D extends C ] {
+ @@ %s 6-7
+
+ - Constants [0] {
+ }
+
+ - Static properties [0] {
+ }
+
+ - Static methods [0] {
+ }
+
+ - Properties [0] {
+ }
+
+ - Dynamic properties [0] {
+ }
+
+ - Methods [0] {
+ }
+}
+
diff --git a/ext/reflection/tests/ReflectionObject_getConstant_basic.phpt b/ext/reflection/tests/ReflectionObject_getConstant_basic.phpt
new file mode 100644
index 0000000..3d151bc
--- /dev/null
+++ b/ext/reflection/tests/ReflectionObject_getConstant_basic.phpt
@@ -0,0 +1,41 @@
+--TEST--
+ReflectionObject::getConstant() basic function test
+--FILE--
+<?php
+class C {
+ const a = 'hello from C';
+}
+class D extends C {
+}
+class E extends D {
+}
+class F extends E {
+ const a = 'hello from F';
+}
+class X {
+}
+
+$classes = array("C", "D", "E", "F", "X");
+foreach($classes as $class) {
+ echo "Reflecting on instance of class $class: \n";
+ $rc = new ReflectionObject(new $class);
+ var_dump($rc->getConstant('a'));
+ var_dump($rc->getConstant('doesntexist'));
+}
+?>
+--EXPECTF--
+Reflecting on instance of class C:
+string(12) "hello from C"
+bool(false)
+Reflecting on instance of class D:
+string(12) "hello from C"
+bool(false)
+Reflecting on instance of class E:
+string(12) "hello from C"
+bool(false)
+Reflecting on instance of class F:
+string(12) "hello from F"
+bool(false)
+Reflecting on instance of class X:
+bool(false)
+bool(false)
diff --git a/ext/reflection/tests/ReflectionObject_getConstant_error.phpt b/ext/reflection/tests/ReflectionObject_getConstant_error.phpt
new file mode 100644
index 0000000..3f12f3a
--- /dev/null
+++ b/ext/reflection/tests/ReflectionObject_getConstant_error.phpt
@@ -0,0 +1,34 @@
+--TEST--
+ReflectionObject::getConstant() - invalid params
+--FILE--
+<?php
+class C {
+ const myConst = 1;
+}
+
+$rc = new ReflectionObject(new C);
+var_dump($rc->getConstant());
+var_dump($rc->getConstant("myConst", "myConst"));
+var_dump($rc->getConstant(null));
+var_dump($rc->getConstant(1));
+var_dump($rc->getConstant(1.5));
+var_dump($rc->getConstant(true));
+var_dump($rc->getConstant(array(1,2,3)));
+var_dump($rc->getConstant(new C));
+?>
+--EXPECTF--
+Warning: ReflectionClass::getConstant() expects exactly 1 parameter, 0 given in %s on line 7
+NULL
+
+Warning: ReflectionClass::getConstant() expects exactly 1 parameter, 2 given in %s on line 8
+NULL
+bool(false)
+bool(false)
+bool(false)
+bool(false)
+
+Warning: ReflectionClass::getConstant() expects parameter 1 to be string, array given in %s on line 13
+NULL
+
+Warning: ReflectionClass::getConstant() expects parameter 1 to be string, object given in %s on line 14
+NULL
diff --git a/ext/reflection/tests/ReflectionObject_getConstants_basic.phpt b/ext/reflection/tests/ReflectionObject_getConstants_basic.phpt
new file mode 100644
index 0000000..6479ec9
--- /dev/null
+++ b/ext/reflection/tests/ReflectionObject_getConstants_basic.phpt
@@ -0,0 +1,49 @@
+--TEST--
+ReflectionObject::getConstants() - basic function test
+--FILE--
+<?php
+class C {
+ const a = 'hello from C';
+}
+class D extends C {
+}
+class E extends D {
+}
+class F extends E {
+ const a = 'hello from F';
+}
+class X {
+}
+
+$classes = array("C", "D", "E", "F", "X");
+foreach($classes as $class) {
+ echo "Reflecting on instance of class $class: \n";
+ $rc = new ReflectionObject(new $class);
+ var_dump($rc->getConstants());
+}
+
+?>
+--EXPECTF--
+Reflecting on instance of class C:
+array(1) {
+ ["a"]=>
+ string(12) "hello from C"
+}
+Reflecting on instance of class D:
+array(1) {
+ ["a"]=>
+ string(12) "hello from C"
+}
+Reflecting on instance of class E:
+array(1) {
+ ["a"]=>
+ string(12) "hello from C"
+}
+Reflecting on instance of class F:
+array(1) {
+ ["a"]=>
+ string(12) "hello from F"
+}
+Reflecting on instance of class X:
+array(0) {
+}
diff --git a/ext/reflection/tests/ReflectionObject_getConstants_error.phpt b/ext/reflection/tests/ReflectionObject_getConstants_error.phpt
new file mode 100644
index 0000000..d3b9080
--- /dev/null
+++ b/ext/reflection/tests/ReflectionObject_getConstants_error.phpt
@@ -0,0 +1,17 @@
+--TEST--
+ReflectionObject::getConstants() - invalid params
+--FILE--
+<?php
+class X {
+}
+
+$rc = new ReflectionObject(new X);
+
+$rc->getConstants('X');
+$rc->getConstants(true);
+
+?>
+--EXPECTF--
+Warning: ReflectionClass::getConstants() expects exactly 0 parameters, 1 given in %s on line %d
+
+Warning: ReflectionClass::getConstants() expects exactly 0 parameters, 1 given in %s on line %d
diff --git a/ext/reflection/tests/ReflectionObject_getConstructor_basic.phpt b/ext/reflection/tests/ReflectionObject_getConstructor_basic.phpt
new file mode 100644
index 0000000..5a0c36f
--- /dev/null
+++ b/ext/reflection/tests/ReflectionObject_getConstructor_basic.phpt
@@ -0,0 +1,79 @@
+--TEST--
+ReflectionObject::getConstructor() - basic function test
+--FILE--
+<?php
+class NewCtor {
+ function __construct() {}
+}
+
+class ExtendsNewCtor extends NewCtor {
+}
+
+class OldCtor {
+ function OldCtor() {}
+}
+
+class ExtendsOldCtor extends OldCtor {
+}
+
+
+class X {
+ function Y() {}
+}
+
+class Y extends X {
+}
+
+class OldAndNewCtor {
+ function OldAndNewCtor() {}
+ function __construct() {}
+}
+
+class NewAndOldCtor {
+ function __construct() {}
+ function NewAndOldCtor() {}
+}
+class B {
+ function B() {}
+}
+
+class C extends B {
+ function C() {}
+}
+
+class D1 extends C {
+ function __construct() {}
+}
+
+class D2 extends C {
+}
+
+$classes = array('NewCtor', 'ExtendsNewCtor', 'OldCtor', 'ExtendsOldCtor',
+ 'OldAndNewCtor', 'NewAndOldCtor', 'B', 'C', 'D1', 'D2', 'X', 'Y');
+
+foreach ($classes as $class) {
+ $rc = new ReflectionObject(new $class);
+ $rm = $rc->getConstructor();
+ if ($rm != null) {
+ echo "Constructor of $class: " . $rm->getName() . "\n";
+ } else {
+ echo "No constructor for $class\n";
+ }
+
+}
+
+?>
+--EXPECTF--
+Strict Standards: Redefining already defined constructor for class OldAndNewCtor in %s on line %d
+Constructor of NewCtor: __construct
+Constructor of ExtendsNewCtor: __construct
+Constructor of OldCtor: OldCtor
+Constructor of ExtendsOldCtor: OldCtor
+Constructor of OldAndNewCtor: __construct
+Constructor of NewAndOldCtor: __construct
+Constructor of B: B
+Constructor of C: C
+Constructor of D1: __construct
+Constructor of D2: C
+No constructor for X
+No constructor for Y
diff --git a/ext/reflection/tests/ReflectionObject_getConstructor_error.phpt b/ext/reflection/tests/ReflectionObject_getConstructor_error.phpt
new file mode 100644
index 0000000..2f52de2
--- /dev/null
+++ b/ext/reflection/tests/ReflectionObject_getConstructor_error.phpt
@@ -0,0 +1,23 @@
+--TEST--
+ReflectionObject::getConstructor() - invalid params
+--FILE--
+<?php
+class C {}
+$rc = new ReflectionObject(new C);
+var_dump($rc->getConstructor(null));
+var_dump($rc->getConstructor('X'));
+var_dump($rc->getConstructor(true));
+var_dump($rc->getConstructor(array(1,2,3)));
+?>
+--EXPECTF--
+Warning: ReflectionClass::getConstructor() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionClass::getConstructor() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionClass::getConstructor() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionClass::getConstructor() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
diff --git a/ext/reflection/tests/ReflectionObject_getName_basic.phpt b/ext/reflection/tests/ReflectionObject_getName_basic.phpt
new file mode 100644
index 0000000..db0cbfb
--- /dev/null
+++ b/ext/reflection/tests/ReflectionObject_getName_basic.phpt
@@ -0,0 +1,27 @@
+--TEST--
+ReflectionObject::getName() - basic function test
+--FILE--
+<?php
+$r0 = new ReflectionObject();
+var_dump($r0->getName());
+
+$r1 = new ReflectionObject(new stdClass);
+var_dump($r1->getName());
+
+class C { }
+$myInstance = new C;
+$r2 = new ReflectionObject($myInstance);
+var_dump($r2->getName());
+
+$r3 = new ReflectionObject($r2);
+var_dump($r3->getName());
+
+?>
+--EXPECTF--
+
+Warning: ReflectionObject::__construct() expects exactly 1 parameter, 0 given in %s on line 2
+string(0) ""
+string(8) "stdClass"
+string(1) "C"
+string(16) "ReflectionObject"
+
diff --git a/ext/reflection/tests/ReflectionObject_getName_error.phpt b/ext/reflection/tests/ReflectionObject_getName_error.phpt
new file mode 100644
index 0000000..ff8e279
--- /dev/null
+++ b/ext/reflection/tests/ReflectionObject_getName_error.phpt
@@ -0,0 +1,23 @@
+--TEST--
+ReflectionObject::getname() - invalid params
+--FILE--
+<?php
+class C { }
+$myInstance = new C;
+$r2 = new ReflectionObject($myInstance);
+
+$r3 = new ReflectionObject($r2);
+
+var_dump($r3->getName(null));
+var_dump($r3->getName('x','y'));
+var_dump($r3->getName(0));
+?>
+--EXPECTF--
+Warning: ReflectionClass::getName() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionClass::getName() expects exactly 0 parameters, 2 given in %s on line %d
+NULL
+
+Warning: ReflectionClass::getName() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
diff --git a/ext/reflection/tests/ReflectionObject_getName_error1.phpt b/ext/reflection/tests/ReflectionObject_getName_error1.phpt
new file mode 100644
index 0000000..26c342d
--- /dev/null
+++ b/ext/reflection/tests/ReflectionObject_getName_error1.phpt
@@ -0,0 +1,8 @@
+--TEST--
+ReflectionObject::getName - forbid static invocation
+--FILE--
+<?php
+ReflectionObject::getName();
+?>
+--EXPECTF--
+Fatal error: Non-static method ReflectionClass::getName() cannot be called statically in %s on line 2
diff --git a/ext/reflection/tests/ReflectionObject_isInstance_basic.phpt b/ext/reflection/tests/ReflectionObject_isInstance_basic.phpt
new file mode 100644
index 0000000..ef605aa
--- /dev/null
+++ b/ext/reflection/tests/ReflectionObject_isInstance_basic.phpt
@@ -0,0 +1,33 @@
+--TEST--
+ReflectionObject::isInstance() - basic function test
+--FILE--
+<?php
+class A {}
+class B extends A {}
+class X {}
+
+$classes = array("A", "B", "X");
+
+$instances = array( "myA" => new A,
+ "myB" => new B,
+ "myX" => new X );
+
+foreach ($classes as $class) {
+ $ro = new ReflectionObject(new $class);
+ foreach ($instances as $name => $instance) {
+ echo "is $name a $class? ";
+ var_dump($ro->isInstance($instance));
+ }
+}
+
+?>
+--EXPECTF--
+is myA a A? bool(true)
+is myB a A? bool(true)
+is myX a A? bool(false)
+is myA a B? bool(false)
+is myB a B? bool(true)
+is myX a B? bool(false)
+is myA a X? bool(false)
+is myB a X? bool(false)
+is myX a X? bool(true)
diff --git a/ext/reflection/tests/ReflectionObject_isInstance_error.phpt b/ext/reflection/tests/ReflectionObject_isInstance_error.phpt
new file mode 100644
index 0000000..692c2f8
--- /dev/null
+++ b/ext/reflection/tests/ReflectionObject_isInstance_error.phpt
@@ -0,0 +1,38 @@
+--TEST--
+ReflectionObject::isInstance() - invalid params
+--FILE--
+<?php
+class X {}
+$instance = new X;
+$ro = new ReflectionObject(new X);
+
+var_dump($ro->isInstance());
+var_dump($ro->isInstance($instance, $instance));
+var_dump($ro->isInstance(1));
+var_dump($ro->isInstance(1.5));
+var_dump($ro->isInstance(true));
+var_dump($ro->isInstance('X'));
+var_dump($ro->isInstance(null));
+
+?>
+--EXPECTF--
+Warning: ReflectionClass::isInstance() expects exactly 1 parameter, 0 given in %s on line 6
+NULL
+
+Warning: ReflectionClass::isInstance() expects exactly 1 parameter, 2 given in %s on line 7
+NULL
+
+Warning: ReflectionClass::isInstance() expects parameter 1 to be object, integer given in %s on line 8
+NULL
+
+Warning: ReflectionClass::isInstance() expects parameter 1 to be object, double given in %s on line 9
+NULL
+
+Warning: ReflectionClass::isInstance() expects parameter 1 to be object, boolean given in %s on line 10
+NULL
+
+Warning: ReflectionClass::isInstance() expects parameter 1 to be object, string given in %s on line 11
+NULL
+
+Warning: ReflectionClass::isInstance() expects parameter 1 to be object, null given in %s on line 12
+NULL
diff --git a/ext/reflection/tests/ReflectionObject_isInstantiable_basic.phpt b/ext/reflection/tests/ReflectionObject_isInstantiable_basic.phpt
new file mode 100644
index 0000000..4b8a6ec
--- /dev/null
+++ b/ext/reflection/tests/ReflectionObject_isInstantiable_basic.phpt
@@ -0,0 +1,36 @@
+--TEST--
+ReflectionObject::IsInstantiable() - basic function test
+--FILE--
+<?php
+class C {
+}
+
+interface iface {
+ function f1();
+}
+
+class ifaceImpl implements iface {
+ function f1() {}
+}
+
+abstract class abstractClass {
+ function f1() {}
+ abstract function f2();
+}
+
+class D extends abstractClass {
+ function f2() {}
+}
+
+$classes = array("C", "ifaceImpl", "D");
+
+foreach($classes as $class ) {
+ $ro = new ReflectionObject(new $class);
+ echo "Is $class instantiable? ";
+ var_dump($ro->IsInstantiable());
+}
+?>
+--EXPECTF--
+Is C instantiable? bool(true)
+Is ifaceImpl instantiable? bool(true)
+Is D instantiable? bool(true)
diff --git a/ext/reflection/tests/ReflectionObject_isInstantiable_error.phpt b/ext/reflection/tests/ReflectionObject_isInstantiable_error.phpt
new file mode 100644
index 0000000..f993367
--- /dev/null
+++ b/ext/reflection/tests/ReflectionObject_isInstantiable_error.phpt
@@ -0,0 +1,22 @@
+--TEST--
+ReflectionObject::IsInstantiable() - invalid params
+--FILE--
+<?php
+class privateCtorOld {
+ private function privateCtorOld() {}
+ public static function reflectionObjectFactory() {
+ return new ReflectionObject(new self);
+ }
+}
+$reflectionObject = privateCtorOld::reflectionObjectFactory();
+
+var_dump($reflectionObject->IsInstantiable('X'));
+var_dump($reflectionObject->IsInstantiable(0, null));
+
+?>
+--EXPECTF--
+Warning: ReflectionClass::isInstantiable() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionClass::isInstantiable() expects exactly 0 parameters, 2 given in %s on line %d
+NULL
diff --git a/ext/reflection/tests/ReflectionObject_isInstantiable_variation.phpt b/ext/reflection/tests/ReflectionObject_isInstantiable_variation.phpt
new file mode 100644
index 0000000..ac7199c
--- /dev/null
+++ b/ext/reflection/tests/ReflectionObject_isInstantiable_variation.phpt
@@ -0,0 +1,78 @@
+--TEST--
+ReflectionObject::IsInstantiable() - variation - constructors
+--FILE--
+<?php
+
+class noCtor {
+ public static function reflectionObjectFactory() {
+ return new ReflectionObject(new self);
+ }
+}
+
+class publicCtorNew {
+ public function __construct() {}
+ public static function reflectionObjectFactory() {
+ return new ReflectionObject(new self);
+ }
+}
+
+class protectedCtorNew {
+ protected function __construct() {}
+ public static function reflectionObjectFactory() {
+ return new ReflectionObject(new self);
+ }
+}
+
+class privateCtorNew {
+ private function __construct() {}
+ public static function reflectionObjectFactory() {
+ return new ReflectionObject(new self);
+ }
+}
+
+class publicCtorOld {
+ public function publicCtorOld() {}
+ public static function reflectionObjectFactory() {
+ return new ReflectionObject(new self);
+ }
+}
+
+class protectedCtorOld {
+ protected function protectedCtorOld() {}
+ public static function reflectionObjectFactory() {
+ return new ReflectionObject(new self);
+ }
+}
+
+class privateCtorOld {
+ private function privateCtorOld() {}
+ public static function reflectionObjectFactory() {
+ return new ReflectionObject(new self);
+ }
+}
+
+
+$reflectionObjects = array(
+ noCtor::reflectionObjectFactory(),
+ publicCtorNew::reflectionObjectFactory(),
+ protectedCtorNew::reflectionObjectFactory(),
+ privateCtorNew::reflectionObjectFactory(),
+ publicCtorOld::reflectionObjectFactory(),
+ protectedCtorOld::reflectionObjectFactory(),
+ privateCtorOld::reflectionObjectFactory()
+ );
+
+foreach($reflectionObjects as $reflectionObject ) {
+ $name = $reflectionObject->getName();
+ echo "Is $name instantiable? ";
+ var_dump($reflectionObject->IsInstantiable());
+}
+?>
+--EXPECTF--
+Is noCtor instantiable? bool(true)
+Is publicCtorNew instantiable? bool(true)
+Is protectedCtorNew instantiable? bool(false)
+Is privateCtorNew instantiable? bool(false)
+Is publicCtorOld instantiable? bool(true)
+Is protectedCtorOld instantiable? bool(false)
+Is privateCtorOld instantiable? bool(false)
diff --git a/ext/reflection/tests/ReflectionObject_isInternal_basic.phpt b/ext/reflection/tests/ReflectionObject_isInternal_basic.phpt
new file mode 100644
index 0000000..066bca7
--- /dev/null
+++ b/ext/reflection/tests/ReflectionObject_isInternal_basic.phpt
@@ -0,0 +1,23 @@
+--TEST--
+ReflectionObject::isInternal() - basic function test
+--FILE--
+<?php
+class C {
+}
+
+$r1 = new ReflectionObject(new stdClass);
+$r2 = new ReflectionObject(new ReflectionClass('C'));
+$r3 = new ReflectionObject(new ReflectionProperty('Exception', 'message'));
+$r4 = new ReflectionObject(new Exception);
+$r5 = new ReflectionObject(new C);
+
+var_dump($r1->isInternal(), $r2->isInternal(), $r3->isInternal(),
+ $r4->isInternal(), $r5->isInternal());
+
+?>
+--EXPECTF--
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(false)
diff --git a/ext/reflection/tests/ReflectionObject_isInternal_error.phpt b/ext/reflection/tests/ReflectionObject_isInternal_error.phpt
new file mode 100644
index 0000000..996add6
--- /dev/null
+++ b/ext/reflection/tests/ReflectionObject_isInternal_error.phpt
@@ -0,0 +1,15 @@
+--TEST--
+ReflectionObject::isInternal() - invalid params
+--FILE--
+<?php
+
+$r1 = new ReflectionObject(new stdClass);
+var_dump($r1->isInternal('X'));
+var_dump($r1->isInternal('X', true));
+?>
+--EXPECTF--
+Warning: ReflectionClass::isInternal() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionClass::isInternal() expects exactly 0 parameters, 2 given in %s on line %d
+NULL
diff --git a/ext/reflection/tests/ReflectionObject_isSubclassOf.002.phpt b/ext/reflection/tests/ReflectionObject_isSubclassOf.002.phpt
new file mode 100644
index 0000000..2fb8cb0
--- /dev/null
+++ b/ext/reflection/tests/ReflectionObject_isSubclassOf.002.phpt
@@ -0,0 +1,48 @@
+--TEST--
+ReflectionObject::isSubclassOf() - bad arguments
+--CREDITS--
+Robin Fernandes <robinf@php.net>
+Steve Seear <stevseea@php.net>
+--FILE--
+<?php
+class C {}
+$ro = new ReflectionObject(new C);
+
+echo "\n\nTest bad arguments:\n";
+try {
+ var_dump($ro->isSubclassOf());
+} catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+try {
+ var_dump($ro->isSubclassOf('C', 'C'));
+} catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+try {
+ var_dump($ro->isSubclassOf(null));
+} catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+try {
+ var_dump($ro->isSubclassOf('ThisClassDoesNotExist'));
+} catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+try {
+ var_dump($ro->isSubclassOf(2));
+} catch (Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+?>
+--EXPECTF--
+Test bad arguments:
+
+Warning: ReflectionClass::isSubclassOf() expects exactly 1 parameter, 0 given in %s on line 7
+NULL
+
+Warning: ReflectionClass::isSubclassOf() expects exactly 1 parameter, 2 given in %s on line 12
+NULL
+Parameter one must either be a string or a ReflectionClass object
+Class ThisClassDoesNotExist does not exist
+Parameter one must either be a string or a ReflectionClass object \ No newline at end of file
diff --git a/ext/reflection/tests/ReflectionObject_isSubclassOf_basic.phpt b/ext/reflection/tests/ReflectionObject_isSubclassOf_basic.phpt
new file mode 100644
index 0000000..e89066a
--- /dev/null
+++ b/ext/reflection/tests/ReflectionObject_isSubclassOf_basic.phpt
@@ -0,0 +1,116 @@
+--TEST--
+ReflectionObject::isSubclassOf() - basic function test
+--FILE--
+<?php
+class A {}
+class B extends A {}
+class C extends B {}
+
+interface I {}
+class X implements I {}
+
+$classNames = array('A', 'B', 'C', 'I', 'X');
+
+//Create ReflectionClasses
+foreach ($classNames as $className) {
+ $rcs[$className] = new ReflectionClass($className);
+}
+
+//Create ReflectionObjects
+foreach ($classNames as $className) {
+ if ($rcs[$className]->isInstantiable()) {
+ $ros[$className] = new ReflectionObject(new $className);
+ }
+}
+
+foreach ($ros as $childName => $child) {
+ foreach ($rcs as $parentName => $parent) {
+ echo "Is " . $childName . " a subclass of " . $parentName . "? \n";
+ echo " - Using ReflectionClass object argument: ";
+ var_dump($child->isSubclassOf($parent));
+ if ($parent->isInstantiable()) {
+ echo " - Using ReflectionObject object argument: ";
+ var_dump($child->isSubclassOf($ros[$parentName]));
+ }
+ echo " - Using string argument: ";
+ var_dump($child->isSubclassOf($parentName));
+ }
+}
+?>
+--EXPECTF--
+Is A a subclass of A?
+ - Using ReflectionClass object argument: bool(false)
+ - Using ReflectionObject object argument: bool(false)
+ - Using string argument: bool(false)
+Is A a subclass of B?
+ - Using ReflectionClass object argument: bool(false)
+ - Using ReflectionObject object argument: bool(false)
+ - Using string argument: bool(false)
+Is A a subclass of C?
+ - Using ReflectionClass object argument: bool(false)
+ - Using ReflectionObject object argument: bool(false)
+ - Using string argument: bool(false)
+Is A a subclass of I?
+ - Using ReflectionClass object argument: bool(false)
+ - Using string argument: bool(false)
+Is A a subclass of X?
+ - Using ReflectionClass object argument: bool(false)
+ - Using ReflectionObject object argument: bool(false)
+ - Using string argument: bool(false)
+Is B a subclass of A?
+ - Using ReflectionClass object argument: bool(true)
+ - Using ReflectionObject object argument: bool(true)
+ - Using string argument: bool(true)
+Is B a subclass of B?
+ - Using ReflectionClass object argument: bool(false)
+ - Using ReflectionObject object argument: bool(false)
+ - Using string argument: bool(false)
+Is B a subclass of C?
+ - Using ReflectionClass object argument: bool(false)
+ - Using ReflectionObject object argument: bool(false)
+ - Using string argument: bool(false)
+Is B a subclass of I?
+ - Using ReflectionClass object argument: bool(false)
+ - Using string argument: bool(false)
+Is B a subclass of X?
+ - Using ReflectionClass object argument: bool(false)
+ - Using ReflectionObject object argument: bool(false)
+ - Using string argument: bool(false)
+Is C a subclass of A?
+ - Using ReflectionClass object argument: bool(true)
+ - Using ReflectionObject object argument: bool(true)
+ - Using string argument: bool(true)
+Is C a subclass of B?
+ - Using ReflectionClass object argument: bool(true)
+ - Using ReflectionObject object argument: bool(true)
+ - Using string argument: bool(true)
+Is C a subclass of C?
+ - Using ReflectionClass object argument: bool(false)
+ - Using ReflectionObject object argument: bool(false)
+ - Using string argument: bool(false)
+Is C a subclass of I?
+ - Using ReflectionClass object argument: bool(false)
+ - Using string argument: bool(false)
+Is C a subclass of X?
+ - Using ReflectionClass object argument: bool(false)
+ - Using ReflectionObject object argument: bool(false)
+ - Using string argument: bool(false)
+Is X a subclass of A?
+ - Using ReflectionClass object argument: bool(false)
+ - Using ReflectionObject object argument: bool(false)
+ - Using string argument: bool(false)
+Is X a subclass of B?
+ - Using ReflectionClass object argument: bool(false)
+ - Using ReflectionObject object argument: bool(false)
+ - Using string argument: bool(false)
+Is X a subclass of C?
+ - Using ReflectionClass object argument: bool(false)
+ - Using ReflectionObject object argument: bool(false)
+ - Using string argument: bool(false)
+Is X a subclass of I?
+ - Using ReflectionClass object argument: bool(true)
+ - Using string argument: bool(true)
+Is X a subclass of X?
+ - Using ReflectionClass object argument: bool(false)
+ - Using ReflectionObject object argument: bool(false)
+ - Using string argument: bool(false)
diff --git a/ext/reflection/tests/ReflectionObject_isSubclassOf_error.phpt b/ext/reflection/tests/ReflectionObject_isSubclassOf_error.phpt
new file mode 100644
index 0000000..9387b7d
--- /dev/null
+++ b/ext/reflection/tests/ReflectionObject_isSubclassOf_error.phpt
@@ -0,0 +1,24 @@
+--TEST--
+ReflectionObject::isSubclassOf() - invalid params
+--FILE--
+<?php
+class A {}
+$ro = new ReflectionObject(new A);
+
+var_dump($ro->isSubclassOf());
+var_dump($ro->isSubclassOf('A',5));
+var_dump($ro->isSubclassOf('X'));
+
+?>
+--EXPECTF--
+Warning: ReflectionClass::isSubclassOf() expects exactly 1 parameter, 0 given in %s on line 5
+NULL
+
+Warning: ReflectionClass::isSubclassOf() expects exactly 1 parameter, 2 given in %s on line 6
+NULL
+
+Fatal error: Uncaught exception 'ReflectionException' with message 'Class X does not exist' in %s:7
+Stack trace:
+#0 %s(7): ReflectionClass->isSubclassOf('X')
+#1 {main}
+ thrown in %s on line 7
diff --git a/ext/reflection/tests/ReflectionObject_isUserDefined_basic.phpt b/ext/reflection/tests/ReflectionObject_isUserDefined_basic.phpt
new file mode 100644
index 0000000..4cb08fc
--- /dev/null
+++ b/ext/reflection/tests/ReflectionObject_isUserDefined_basic.phpt
@@ -0,0 +1,23 @@
+--TEST--
+ReflectionObject::isUserDefined() - basic function test
+--FILE--
+<?php
+class C {
+}
+
+$r1 = new ReflectionObject(new stdClass);
+$r2 = new ReflectionObject(new ReflectionClass('C'));
+$r3 = new ReflectionObject(new ReflectionProperty('Exception', 'message'));
+$r4 = new ReflectionObject(new Exception);
+$r5 = new ReflectionObject(new C);
+
+var_dump($r1->isUserDefined(), $r2->isUserDefined(), $r3->isUserDefined(),
+ $r4->isUserDefined(), $r5->isUserDefined());
+
+?>
+--EXPECTF--
+bool(false)
+bool(false)
+bool(false)
+bool(false)
+bool(true)
diff --git a/ext/reflection/tests/ReflectionObject_isUserDefined_error.phpt b/ext/reflection/tests/ReflectionObject_isUserDefined_error.phpt
new file mode 100644
index 0000000..06be47a
--- /dev/null
+++ b/ext/reflection/tests/ReflectionObject_isUserDefined_error.phpt
@@ -0,0 +1,15 @@
+--TEST--
+ReflectionObject::isUserDefined() - invalid params
+--FILE--
+<?php
+$r1 = new ReflectionObject(new stdClass);
+
+var_dump($r1->isUserDefined('X'));
+var_dump($r1->isUserDefined('X', true));
+?>
+--EXPECTF--
+Warning: ReflectionClass::isUserDefined() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionClass::isUserDefined() expects exactly 0 parameters, 2 given in %s on line %d
+NULL
diff --git a/ext/reflection/tests/ReflectionParameter_001.phpt b/ext/reflection/tests/ReflectionParameter_001.phpt
new file mode 100644
index 0000000..dae3ac7
--- /dev/null
+++ b/ext/reflection/tests/ReflectionParameter_001.phpt
@@ -0,0 +1,80 @@
+--TEST--
+ReflectionParameter class - getNames() method.
+--CREDITS--
+Robin Fernandes <robinf@php.net>
+Steve Seear <stevseea@php.net>
+--FILE--
+<?php
+class ReflectTestClass {
+ public static function twoArgFunction($theIncrement, $anotherParam) {
+ return ++$theIncrement;
+ }
+
+ public function oneArgNonStatic($theParam) {
+ $theParam--;
+ }
+
+ public function noArgs() {
+ echo "No arg function\n";
+ }
+}
+
+// Create an instance of the Reflection_Method class
+$method = new ReflectionMethod('ReflectTestClass', 'twoArgFunction');
+// Get the parameters
+$parameters = $method->getParameters();
+echo "Parameters from twoArgMethod:\n\n";
+foreach($parameters as $parameter) {
+ var_dump($parameter);
+ $name = $parameter->getName();
+ echo "\n";
+}
+
+$method = new ReflectionMethod('ReflectTestClass', 'oneArgNonStatic');
+$parameters = $method->getParameters();
+echo "Parameters from oneArgNonStatic:\n\n";
+foreach($parameters as $parameter) {
+ var_dump($parameter);
+ $name = $parameter->getName();
+ echo "\n";
+}
+
+
+$method = new ReflectionMethod('ReflectTestClass', 'noArgs');
+$parameters = $method->getParameters();
+echo "Parameters from noArgs:\n\n";
+var_dump($parameters);
+foreach($parameters as $parameter) {
+ var_dump($parameter);
+ $name = $parameter->getName();
+ echo "\n";
+}
+
+echo "done\n";
+
+?>
+--EXPECTF--
+Parameters from twoArgMethod:
+
+object(ReflectionParameter)#%i (1) {
+ ["name"]=>
+ string(12) "theIncrement"
+}
+
+object(ReflectionParameter)#%i (1) {
+ ["name"]=>
+ string(12) "anotherParam"
+}
+
+Parameters from oneArgNonStatic:
+
+object(ReflectionParameter)#%i (1) {
+ ["name"]=>
+ string(8) "theParam"
+}
+
+Parameters from noArgs:
+
+array(0) {
+}
+done \ No newline at end of file
diff --git a/ext/reflection/tests/ReflectionParameter_002.phpt b/ext/reflection/tests/ReflectionParameter_002.phpt
new file mode 100644
index 0000000..3b7df6f
--- /dev/null
+++ b/ext/reflection/tests/ReflectionParameter_002.phpt
@@ -0,0 +1,80 @@
+--TEST--
+ReflectionParameter class - isPassedByReferenceMethod()
+--CREDITS--
+Robin Fernandes <robinf@php.net>
+Steve Seear <stevseea@php.net>
+--FILE--
+<?php
+class ReflectTestClass {
+ public static function staticMethod(&$paramOne, $anotherParam) {
+ return ++$theIncrement;
+ }
+
+ public function instanceMethod($firstParam, &$secondParam) {
+ $firstParam = "Hello\n";
+ }
+}
+
+// Create an instance of the Reflection_Method class
+$method = new ReflectionMethod('ReflectTestClass', 'staticMethod');
+// Get the parameters
+$parameters = $method->getParameters();
+echo "Parameters from staticMethod:\n\n";
+foreach($parameters as $parameter) {
+ var_dump($parameter);
+ if($parameter->isPassedByReference()) {
+ echo "This param is passed by reference\n";
+ } else {
+ echo "This param is not passed by reference\n";
+ }
+ echo "\n";
+}
+
+// Create an instance of the Reflection_Method class
+$method = new ReflectionMethod('ReflectTestClass', 'instanceMethod');
+// Get the parameters
+$parameters = $method->getParameters();
+echo "Parameters from instanceMethod:\n\n";
+foreach($parameters as $parameter) {
+ var_dump($parameter);
+ if($parameter->isPassedByReference()) {
+ echo "This param is passed by reference\n";
+ } else {
+ echo "This param is not passed by reference\n";
+ }
+ echo "\n";
+}
+
+echo "done\n";
+
+?>
+--EXPECTF--
+Parameters from staticMethod:
+
+object(ReflectionParameter)#%i (1) {
+ ["name"]=>
+ string(8) "paramOne"
+}
+This param is passed by reference
+
+object(ReflectionParameter)#%i (1) {
+ ["name"]=>
+ string(12) "anotherParam"
+}
+This param is not passed by reference
+
+Parameters from instanceMethod:
+
+object(ReflectionParameter)#%i (1) {
+ ["name"]=>
+ string(10) "firstParam"
+}
+This param is not passed by reference
+
+object(ReflectionParameter)#%i (1) {
+ ["name"]=>
+ string(11) "secondParam"
+}
+This param is passed by reference
+
+done \ No newline at end of file
diff --git a/ext/reflection/tests/ReflectionParameter_003.phpt b/ext/reflection/tests/ReflectionParameter_003.phpt
new file mode 100644
index 0000000..f7ced9a
--- /dev/null
+++ b/ext/reflection/tests/ReflectionParameter_003.phpt
@@ -0,0 +1,88 @@
+--TEST--
+ReflectionParameter class - isOptional, isDefaultValueAvailable and getDefaultValue methods.
+--CREDITS--
+Robin Fernandes <robinf@php.net>
+Steve Seear <stevseea@php.net>
+--FILE--
+<?php
+
+class ReflectTestClass {
+ public static function staticMethod($paramOne, $anotherParam = "bob",
+ &$thirdParam = "jack", $arrayParam = array('one')) {
+ echo "hello from test\n";
+ echo "third is $thirdParam\n";
+ return ++$theIncrement;
+ }
+
+}
+
+$jane = "jane";
+ReflectTestClass::staticMethod("bob", "jack");
+
+$refMethod = new ReflectionMethod('ReflectTestClass', 'staticMethod');
+$refParameters = $refMethod->getParameters();
+
+echo "parameter names from staticMethod method:\n\n";
+foreach($refParameters as $parameter) {
+ var_dump($parameter);
+ if($parameter->isOptional()) {
+ echo "this parameter is optional\n";
+ } else {
+ echo "this parameter is not optional\n";
+ }
+
+ if($parameter->isDefaultValueAvailable()) {
+ echo "this parameter has a default value\n";
+ } else {
+ echo "this parameter has no default value\n";
+ }
+
+ /*
+ $val = 0;
+ try {
+ $val = $parameter->getDefaultValue();
+ var_dump($val);
+ } catch (ReflectionException $e) {
+ print $e->getMessage();
+ echo "\n";
+ }
+ */
+
+ echo "\n";
+}
+
+?>
+--EXPECTF--
+hello from test
+third is jack
+
+Notice: Undefined variable: theIncrement in %s on line 8
+parameter names from staticMethod method:
+
+object(ReflectionParameter)#%d (1) {
+ ["name"]=>
+ string(8) "paramOne"
+}
+this parameter is not optional
+this parameter has no default value
+
+object(ReflectionParameter)#%d (1) {
+ ["name"]=>
+ string(12) "anotherParam"
+}
+this parameter is optional
+this parameter has a default value
+
+object(ReflectionParameter)#%d (1) {
+ ["name"]=>
+ string(10) "thirdParam"
+}
+this parameter is optional
+this parameter has a default value
+
+object(ReflectionParameter)#%d (1) {
+ ["name"]=>
+ string(10) "arrayParam"
+}
+this parameter is optional
+this parameter has a default value
diff --git a/ext/reflection/tests/ReflectionParameter_DefaultValueConstant_basic1.phpt b/ext/reflection/tests/ReflectionParameter_DefaultValueConstant_basic1.phpt
new file mode 100644
index 0000000..cdd00d2
--- /dev/null
+++ b/ext/reflection/tests/ReflectionParameter_DefaultValueConstant_basic1.phpt
@@ -0,0 +1,52 @@
+--TEST--
+ReflectionParameter::isDefaultValueConstant() && getDefaultValueConstantName()
+--FILE--
+<?php
+
+define("CONST_TEST_1", "const1");
+
+function ReflectionParameterTest($test1=array(), $test2 = CONST_TEST_1) {
+ echo $test;
+}
+$reflect = new ReflectionFunction('ReflectionParameterTest');
+foreach($reflect->getParameters() as $param) {
+ if($param->getName() == 'test1') {
+ var_dump($param->isDefaultValueConstant());
+ }
+ if($param->getName() == 'test2') {
+ var_dump($param->isDefaultValueConstant());
+ }
+ if($param->isDefaultValueAvailable() && $param->isDefaultValueConstant()) {
+ var_dump($param->getDefaultValueConstantName());
+ }
+}
+
+class Foo2 {
+ const bar = 'Foo2::bar';
+}
+
+class Foo {
+ const bar = 'Foo::bar';
+
+ public function baz($param1 = self::bar, $param2=Foo2::bar, $param3=CONST_TEST_1) {
+ }
+}
+
+$method = new ReflectionMethod('Foo', 'baz');
+$params = $method->getParameters();
+
+foreach ($params as $param) {
+ if ($param->isDefaultValueConstant()) {
+ var_dump($param->getDefaultValueConstantName());
+ }
+}
+?>
+==DONE==
+--EXPECT--
+bool(false)
+bool(true)
+string(12) "CONST_TEST_1"
+string(9) "self::bar"
+string(9) "Foo2::bar"
+string(12) "CONST_TEST_1"
+==DONE==
diff --git a/ext/reflection/tests/ReflectionParameter_DefaultValueConstant_basic2.phpt b/ext/reflection/tests/ReflectionParameter_DefaultValueConstant_basic2.phpt
new file mode 100644
index 0000000..1ee9e93
--- /dev/null
+++ b/ext/reflection/tests/ReflectionParameter_DefaultValueConstant_basic2.phpt
@@ -0,0 +1,30 @@
+--TEST--
+ReflectionParameter::isDefaultValueConstant() && getDefaultValueConstantName() for namespace
+--FILE--
+<?php
+
+namespace ReflectionTestNamespace {
+ CONST TEST_CONST_1 = "Test Const 1";
+
+ class TestClass {
+ const TEST_CONST_2 = "Test Const 2 in class";
+ }
+}
+
+namespace {
+ function ReflectionParameterTest($test=ReflectionTestNamespace\TestClass::TEST_CONST_2, $test2 = ReflectionTestNamespace\CONST_TEST_1) {
+ echo $test;
+ }
+ $reflect = new ReflectionFunction('ReflectionParameterTest');
+ foreach($reflect->getParameters() as $param) {
+ if($param->isDefaultValueAvailable() && $param->isDefaultValueConstant()) {
+ echo $param->getDefaultValueConstantName() . "\n";
+ }
+ }
+ echo "==DONE==";
+}
+?>
+--EXPECT--
+ReflectionTestNamespace\TestClass::TEST_CONST_2
+ReflectionTestNamespace\CONST_TEST_1
+==DONE==
diff --git a/ext/reflection/tests/ReflectionParameter_DefaultValueConstant_error.phpt b/ext/reflection/tests/ReflectionParameter_DefaultValueConstant_error.phpt
new file mode 100644
index 0000000..a2c2d24
--- /dev/null
+++ b/ext/reflection/tests/ReflectionParameter_DefaultValueConstant_error.phpt
@@ -0,0 +1,23 @@
+--TEST--
+ReflectionParameter::getDefaultValueConstant() should raise exception on non optional parameter
+--FILE--
+<?php
+
+define("CONST_TEST_1", "const1");
+
+function ReflectionParameterTest($test, $test2 = CONST_TEST_1) {
+ echo $test;
+}
+$reflect = new ReflectionFunction('ReflectionParameterTest');
+foreach($reflect->getParameters() as $param) {
+ try {
+ echo $param->getDefaultValueConstantName() . "\n";
+ }
+ catch(ReflectionException $e) {
+ echo $e->getMessage() . "\n";
+ }
+}
+?>
+--EXPECT--
+Internal error: Failed to retrieve the default value
+CONST_TEST_1
diff --git a/ext/reflection/tests/ReflectionParameter_canBePassedByValue.phpt b/ext/reflection/tests/ReflectionParameter_canBePassedByValue.phpt
new file mode 100644
index 0000000..82c6200
--- /dev/null
+++ b/ext/reflection/tests/ReflectionParameter_canBePassedByValue.phpt
@@ -0,0 +1,84 @@
+--TEST--
+ReflectionParameter class - canBePassedByValue() method.
+--FILE--
+<?php
+
+function aux($fun) {
+
+ $func = new ReflectionFunction($fun);
+ $parameters = $func->getParameters();
+ foreach($parameters as $parameter) {
+ echo "Name: ", $parameter->getName(), "\n";
+ echo "Is passed by reference: ", $parameter->isPassedByReference()?"yes":"no", "\n";
+ echo "Can be passed by value: ", $parameter->canBePassedByValue()?"yes":"no", "\n";
+ echo "\n";
+ }
+
+}
+
+echo "=> array_multisort:\n\n";
+
+aux('array_multisort');
+
+
+echo "=> sort:\n\n";
+
+aux('sort');
+
+echo "=> user function:\n\n";
+
+function ufunc(&$arg1, $arg2) {}
+
+aux('ufunc');
+
+echo "Done.\n";
+
+?>
+--EXPECTF--
+=> array_multisort:
+
+Name: arr1
+Is passed by reference: yes
+Can be passed by value: yes
+
+Name: SORT_ASC_or_SORT_DESC
+Is passed by reference: yes
+Can be passed by value: yes
+
+Name: SORT_REGULAR_or_SORT_NUMERIC_or_SORT_STRING
+Is passed by reference: yes
+Can be passed by value: yes
+
+Name: arr2
+Is passed by reference: yes
+Can be passed by value: yes
+
+Name: SORT_ASC_or_SORT_DESC
+Is passed by reference: yes
+Can be passed by value: yes
+
+Name: SORT_REGULAR_or_SORT_NUMERIC_or_SORT_STRING
+Is passed by reference: yes
+Can be passed by value: yes
+
+=> sort:
+
+Name: arg
+Is passed by reference: yes
+Can be passed by value: no
+
+Name: sort_flags
+Is passed by reference: no
+Can be passed by value: yes
+
+=> user function:
+
+Name: arg1
+Is passed by reference: yes
+Can be passed by value: no
+
+Name: arg2
+Is passed by reference: no
+Can be passed by value: yes
+
+Done.
diff --git a/ext/reflection/tests/ReflectionParameter_export_basic.phpt b/ext/reflection/tests/ReflectionParameter_export_basic.phpt
new file mode 100644
index 0000000..74428cc
--- /dev/null
+++ b/ext/reflection/tests/ReflectionParameter_export_basic.phpt
@@ -0,0 +1,19 @@
+--TEST--
+ReflectionParameter::export()
+--CREDITS--
+Stefan Koopmanschap <stefan@stefankoopmanschap.nl>
+--FILE--
+<?php
+function ReflectionParameterTest($test, $test2 = null) {
+ echo $test;
+}
+$reflect = new ReflectionFunction('ReflectionParameterTest');
+foreach($reflect->getParameters() as $key => $value) {
+ echo ReflectionParameter::export('ReflectionParameterTest', $key);
+}
+?>
+==DONE==
+--EXPECT--
+Parameter #0 [ <required> $test ]
+Parameter #1 [ <optional> $test2 = NULL ]
+==DONE==
diff --git a/ext/reflection/tests/ReflectionParameter_export_error.phpt b/ext/reflection/tests/ReflectionParameter_export_error.phpt
new file mode 100644
index 0000000..31acfe1
--- /dev/null
+++ b/ext/reflection/tests/ReflectionParameter_export_error.phpt
@@ -0,0 +1,21 @@
+--TEST--
+ReflectionParameter::export() without parameters
+--CREDITS--
+Stefan Koopmanschap <stefan@stefankoopmanschap.nl>
+--FILE--
+<?php
+function ReflectionParameterTest($test, $test2 = null) {
+ echo $test;
+}
+$reflect = new ReflectionFunction('ReflectionParameterTest');
+foreach($reflect->getParameters() as $key => $value) {
+ ReflectionParameter::export();
+}
+?>
+==DONE==
+--EXPECTF--
+
+Warning: ReflectionParameter::export() expects at least 2 parameters, 0 given in %s.php on line %d
+
+Warning: ReflectionParameter::export() expects at least 2 parameters, 0 given in %s.php on line %d
+==DONE==
diff --git a/ext/reflection/tests/ReflectionParameter_export_error2.phpt b/ext/reflection/tests/ReflectionParameter_export_error2.phpt
new file mode 100644
index 0000000..8bdbc6a
--- /dev/null
+++ b/ext/reflection/tests/ReflectionParameter_export_error2.phpt
@@ -0,0 +1,31 @@
+--TEST--
+ReflectionParameter::export() with incorrect first parameter
+--CREDITS--
+Stefan Koopmanschap <stefan@stefankoopmanschap.nl>
+--FILE--
+<?php
+function ReflectionParameterTest($test, $test2 = null) {
+ echo $test;
+}
+$reflect = new ReflectionFunction('ReflectionParameterTest');
+$params = $reflect->getParameters();
+try {
+ foreach($params as $key => $value) {
+ ReflectionParameter::export($reflect, $key);
+ }
+}
+catch (ReflectionException $e) {
+ echo $e->getMessage() . "\n";
+}
+try {
+ foreach($params as $key => $value) {
+ ReflectionParameter::export(42, $key);
+ }
+}
+catch (ReflectionException $e) {
+ echo $e->getMessage() . "\n";
+}
+?>
+--EXPECTF--
+Method ReflectionFunction::__invoke() does not exist
+The parameter class is expected to be either a string, an array(class, method) or a callable object
diff --git a/ext/reflection/tests/ReflectionParameter_export_error3.phpt b/ext/reflection/tests/ReflectionParameter_export_error3.phpt
new file mode 100644
index 0000000..2937853
--- /dev/null
+++ b/ext/reflection/tests/ReflectionParameter_export_error3.phpt
@@ -0,0 +1,22 @@
+--TEST--
+ReflectionParameter::export() with incorrect second parameter
+--CREDITS--
+Stefan Koopmanschap <stefan@stefankoopmanschap.nl>
+--FILE--
+<?php
+function ReflectionParameterTest($test, $test2 = null) {
+ echo $test;
+}
+$reflect = new ReflectionFunction('ReflectionParameterTest');
+$params = $reflect->getParameters();
+foreach($params as $key => $value) {
+ ReflectionParameter::export('ReflectionParameterTest', 'incorrect_parameter');
+}
+--EXPECTF--
+
+Fatal error: Uncaught exception 'ReflectionException' with message 'The parameter specified by its name could not be found' in %s.php:%d
+Stack trace:
+#0 [internal function]: ReflectionParameter->__construct('ReflectionParam...', 'incorrect_param...')
+#1 %s.php(%d): ReflectionParameter::export('ReflectionParam...', 'incorrect_param...')
+#2 {main}
+ thrown in %s.php on line %d
diff --git a/ext/reflection/tests/ReflectionParameter_getDeclaringFunction_basic.phpt b/ext/reflection/tests/ReflectionParameter_getDeclaringFunction_basic.phpt
new file mode 100644
index 0000000..59e15a7
--- /dev/null
+++ b/ext/reflection/tests/ReflectionParameter_getDeclaringFunction_basic.phpt
@@ -0,0 +1,37 @@
+--TEST--
+ReflectionParameter::getDeclaringFunction()
+--CREDITS--
+Stefan Koopmanschap <stefan@stefankoopmanschap.nl>
+#testfest roosendaal on 2008-05-10
+--FILE--
+<?php
+function ReflectionParameterTest($test, $test2 = null) {
+ echo $test;
+}
+$reflect = new ReflectionFunction('ReflectionParameterTest');
+$params = $reflect->getParameters();
+foreach($params as $key => $value) {
+ echo $value->getDeclaringFunction() . "\n";
+}
+?>
+==DONE==
+--EXPECTF--
+Function [ <user> function ReflectionParameterTest ] {
+ @@ %s.php %d - %d
+
+ - Parameters [2] {
+ Parameter #0 [ <required> $test ]
+ Parameter #1 [ <optional> $test2 = NULL ]
+ }
+}
+
+Function [ <user> function ReflectionParameterTest ] {
+ @@ %s.php %d - %d
+
+ - Parameters [2] {
+ Parameter #0 [ <required> $test ]
+ Parameter #1 [ <optional> $test2 = NULL ]
+ }
+}
+
+==DONE==
diff --git a/ext/reflection/tests/ReflectionParameter_getPosition_basic.phpt b/ext/reflection/tests/ReflectionParameter_getPosition_basic.phpt
new file mode 100644
index 0000000..2807bdf
--- /dev/null
+++ b/ext/reflection/tests/ReflectionParameter_getPosition_basic.phpt
@@ -0,0 +1,21 @@
+--TEST--
+ReflectionParameter::getPosition()
+--CREDITS--
+Stefan Koopmanschap <stefan@stefankoopmanschap.nl>
+#testfest roosendaal on 2008-05-10
+--FILE--
+<?php
+function ReflectionParameterTest($test, $test2 = null) {
+ echo $test;
+}
+$reflect = new ReflectionFunction('ReflectionParameterTest');
+$params = $reflect->getParameters();
+foreach($params as $key => $value) {
+ var_dump($value->getPosition());
+}
+?>
+==DONE==
+--EXPECT--
+int(0)
+int(1)
+==DONE==
diff --git a/ext/reflection/tests/ReflectionParameter_invalidMethodInConstructor.phpt b/ext/reflection/tests/ReflectionParameter_invalidMethodInConstructor.phpt
new file mode 100644
index 0000000..3118c17
--- /dev/null
+++ b/ext/reflection/tests/ReflectionParameter_invalidMethodInConstructor.phpt
@@ -0,0 +1,31 @@
+--TEST--
+ReflectionParameter::__construct(): Invalid method as constructor
+--FILE--
+<?php
+
+// Invalid class name
+try {
+ new ReflectionParameter (array ('A', 'b'), 0);
+} catch (ReflectionException $e) { echo $e->getMessage ()."\n"; }
+
+// Invalid class method
+try {
+ new ReflectionParameter (array ('C', 'b'), 0);
+} catch (ReflectionException $e) { echo $e->getMessage ()."\n"; }
+
+// Invalid object method
+try {
+ new ReflectionParameter (array (new C, 'b'), 0);
+} catch (ReflectionException $e) { echo $e->getMessage ()."\n"; }
+
+echo "Done.\n";
+
+class C {
+}
+
+?>
+--EXPECTF--
+Class A does not exist
+Method C::b() does not exist
+Method C::b() does not exist
+Done.
diff --git a/ext/reflection/tests/ReflectionParameter_isDefault.phpt b/ext/reflection/tests/ReflectionParameter_isDefault.phpt
new file mode 100644
index 0000000..6570770
--- /dev/null
+++ b/ext/reflection/tests/ReflectionParameter_isDefault.phpt
@@ -0,0 +1,34 @@
+--TEST--
+ReflectionParameter::isDefault()
+--FILE--
+<?php
+class A {
+public $defprop;
+}
+$a = new A;
+$a->myprop = null;
+
+$ro = new ReflectionObject($a);
+$props = $ro->getProperties();
+$prop1 = $props[0];
+var_dump($prop1->isDefault());
+$prop2 = $props[1];
+var_dump($prop2->isDefault());
+
+var_dump($ro->getProperty('defprop')->isDefault());
+var_dump($ro->getProperty('myprop')->isDefault());
+
+$prop1 = new ReflectionProperty($a, 'defprop');
+$prop2 = new ReflectionProperty($a, 'myprop');
+var_dump($prop1->isDefault());
+var_dump($prop2->isDefault());
+?>
+==DONE==
+--EXPECT--
+bool(true)
+bool(false)
+bool(true)
+bool(false)
+bool(true)
+bool(false)
+==DONE==
diff --git a/ext/reflection/tests/ReflectionParameter_toString_basic.phpt b/ext/reflection/tests/ReflectionParameter_toString_basic.phpt
new file mode 100644
index 0000000..268ced1
--- /dev/null
+++ b/ext/reflection/tests/ReflectionParameter_toString_basic.phpt
@@ -0,0 +1,20 @@
+--TEST--
+ReflectionParameter::__toString()
+--CREDITS--
+Stefan Koopmanschap <stefan@stefankoopmanschap.nl>
+--FILE--
+<?php
+function ReflectionParameterTest($test, $test2 = null) {
+ echo $test;
+}
+$reflect = new ReflectionFunction('ReflectionParameterTest');
+$params = $reflect->getParameters();
+foreach($params as $key => $value) {
+ echo $value->__toString() . "\n";
+}
+?>
+==DONE==
+--EXPECT--
+Parameter #0 [ <required> $test ]
+Parameter #1 [ <optional> $test2 = NULL ]
+==DONE==
diff --git a/ext/reflection/tests/ReflectionProperty_basic1.phpt b/ext/reflection/tests/ReflectionProperty_basic1.phpt
new file mode 100644
index 0000000..63f9542
--- /dev/null
+++ b/ext/reflection/tests/ReflectionProperty_basic1.phpt
@@ -0,0 +1,160 @@
+--TEST--
+Test usage of ReflectionProperty methods __toString(), export(), getName(), isPublic(), isPrivate(), isProtected(), isStatic(), getValue() and setValue().
+--FILE--
+<?php
+
+function reflectProperty($class, $property) {
+ $propInfo = new ReflectionProperty($class, $property);
+ echo "**********************************\n";
+ echo "Reflecting on property $class::$property\n\n";
+ echo "__toString():\n";
+ var_dump($propInfo->__toString());
+ echo "export():\n";
+ var_dump(ReflectionProperty::export($class, $property, true));
+ echo "export():\n";
+ var_dump(ReflectionProperty::export($class, $property, false));
+ echo "getName():\n";
+ var_dump($propInfo->getName());
+ echo "isPublic():\n";
+ var_dump($propInfo->isPublic());
+ echo "isPrivate():\n";
+ var_dump($propInfo->isPrivate());
+ echo "isProtected():\n";
+ var_dump($propInfo->isProtected());
+ echo "isStatic():\n";
+ var_dump($propInfo->isStatic());
+ $instance = new $class();
+ if ($propInfo->isPublic()) {
+ echo "getValue():\n";
+ var_dump($propInfo->getValue($instance));
+ $propInfo->setValue($instance, "NewValue");
+ echo "getValue() after a setValue():\n";
+ var_dump($propInfo->getValue($instance));
+ }
+ echo "\n**********************************\n";
+}
+
+class TestClass {
+ public $pub;
+ static public $stat = "static property";
+ protected $prot = 4;
+ private $priv = "keepOut";
+}
+
+reflectProperty("TestClass", "pub");
+reflectProperty("TestClass", "stat");
+reflectProperty("TestClass", "prot");
+reflectProperty("TestClass", "priv");
+
+?>
+--EXPECT--
+**********************************
+Reflecting on property TestClass::pub
+
+__toString():
+string(35) "Property [ <default> public $pub ]
+"
+export():
+string(35) "Property [ <default> public $pub ]
+"
+export():
+Property [ <default> public $pub ]
+
+NULL
+getName():
+string(3) "pub"
+isPublic():
+bool(true)
+isPrivate():
+bool(false)
+isProtected():
+bool(false)
+isStatic():
+bool(false)
+getValue():
+NULL
+getValue() after a setValue():
+string(8) "NewValue"
+
+**********************************
+**********************************
+Reflecting on property TestClass::stat
+
+__toString():
+string(33) "Property [ public static $stat ]
+"
+export():
+string(33) "Property [ public static $stat ]
+"
+export():
+Property [ public static $stat ]
+
+NULL
+getName():
+string(4) "stat"
+isPublic():
+bool(true)
+isPrivate():
+bool(false)
+isProtected():
+bool(false)
+isStatic():
+bool(true)
+getValue():
+string(15) "static property"
+getValue() after a setValue():
+string(8) "NewValue"
+
+**********************************
+**********************************
+Reflecting on property TestClass::prot
+
+__toString():
+string(39) "Property [ <default> protected $prot ]
+"
+export():
+string(39) "Property [ <default> protected $prot ]
+"
+export():
+Property [ <default> protected $prot ]
+
+NULL
+getName():
+string(4) "prot"
+isPublic():
+bool(false)
+isPrivate():
+bool(false)
+isProtected():
+bool(true)
+isStatic():
+bool(false)
+
+**********************************
+**********************************
+Reflecting on property TestClass::priv
+
+__toString():
+string(37) "Property [ <default> private $priv ]
+"
+export():
+string(37) "Property [ <default> private $priv ]
+"
+export():
+Property [ <default> private $priv ]
+
+NULL
+getName():
+string(4) "priv"
+isPublic():
+bool(false)
+isPrivate():
+bool(true)
+isProtected():
+bool(false)
+isStatic():
+bool(false)
+
+**********************************
+
+
diff --git a/ext/reflection/tests/ReflectionProperty_basic2.phpt b/ext/reflection/tests/ReflectionProperty_basic2.phpt
new file mode 100644
index 0000000..b7b2133
--- /dev/null
+++ b/ext/reflection/tests/ReflectionProperty_basic2.phpt
@@ -0,0 +1,103 @@
+--TEST--
+Test usage of ReflectionProperty methods isDefault(), getModifiers(), getDeclaringClass() and getDocComment().
+--FILE--
+<?php
+
+function reflectProperty($class, $property) {
+ $propInfo = new ReflectionProperty($class, $property);
+ echo "**********************************\n";
+ echo "Reflecting on property $class::$property\n\n";
+ echo "isDefault():\n";
+ var_dump($propInfo->isDefault());
+ echo "getModifiers():\n";
+ var_dump($propInfo->getModifiers());
+ echo "getDeclaringClass():\n";
+ var_dump($propInfo->getDeclaringClass());
+ echo "getDocComment():\n";
+ var_dump($propInfo->getDocComment());
+ echo "\n**********************************\n";
+}
+
+class TestClass {
+ public $pub;
+ static public $stat = "static property";
+ /**
+ * This property has a comment.
+ */
+ protected $prot = 4;
+ private $priv = "keepOut";
+}
+
+reflectProperty("TestClass", "pub");
+reflectProperty("TestClass", "stat");
+reflectProperty("TestClass", "prot");
+reflectProperty("TestClass", "priv");
+
+?>
+--EXPECTF--
+**********************************
+Reflecting on property TestClass::pub
+
+isDefault():
+bool(true)
+getModifiers():
+int(256)
+getDeclaringClass():
+object(ReflectionClass)#%d (1) {
+ ["name"]=>
+ string(9) "TestClass"
+}
+getDocComment():
+bool(false)
+
+**********************************
+**********************************
+Reflecting on property TestClass::stat
+
+isDefault():
+bool(true)
+getModifiers():
+int(257)
+getDeclaringClass():
+object(ReflectionClass)#%d (1) {
+ ["name"]=>
+ string(9) "TestClass"
+}
+getDocComment():
+bool(false)
+
+**********************************
+**********************************
+Reflecting on property TestClass::prot
+
+isDefault():
+bool(true)
+getModifiers():
+int(512)
+getDeclaringClass():
+object(ReflectionClass)#%d (1) {
+ ["name"]=>
+ string(9) "TestClass"
+}
+getDocComment():
+string(%d) "/**
+ * This property has a comment.
+ */"
+
+**********************************
+**********************************
+Reflecting on property TestClass::priv
+
+isDefault():
+bool(true)
+getModifiers():
+int(1024)
+getDeclaringClass():
+object(ReflectionClass)#%d (1) {
+ ["name"]=>
+ string(9) "TestClass"
+}
+getDocComment():
+bool(false)
+
+**********************************
diff --git a/ext/reflection/tests/ReflectionProperty_constructor_error.phpt b/ext/reflection/tests/ReflectionProperty_constructor_error.phpt
new file mode 100644
index 0000000..38a3468
--- /dev/null
+++ b/ext/reflection/tests/ReflectionProperty_constructor_error.phpt
@@ -0,0 +1,44 @@
+--TEST--
+Test ReflectionProperty class constructor errors.
+--FILE--
+<?php
+
+class TestClass {
+}
+
+$a = 5;
+
+echo "Non-existent class:\n";
+try {
+ $propInfo = new ReflectionProperty("NonExistentClass", "prop");
+}
+catch(Exception $e) {
+ echo $e->getMessage();
+}
+
+echo "\n\nWrong property parameter type:\n";
+try {
+ $propInfo = new ReflectionProperty($a, 'TestClass');
+}
+catch(ReflectionException $e) {
+ echo $e->getMessage();
+}
+
+echo "\n\nNon-existent property:\n";
+try {
+ $propInfo = new ReflectionProperty('TestClass', "nonExistentProperty");
+}
+catch(Exception $e) {
+ echo $e->getMessage();
+}
+
+?>
+--EXPECT--
+Non-existent class:
+Class NonExistentClass does not exist
+
+Wrong property parameter type:
+The parameter class is expected to be either a string or an object
+
+Non-existent property:
+Property TestClass::$nonExistentProperty does not exist
diff --git a/ext/reflection/tests/ReflectionProperty_constructor_variation1.phpt b/ext/reflection/tests/ReflectionProperty_constructor_variation1.phpt
new file mode 100644
index 0000000..d614803
--- /dev/null
+++ b/ext/reflection/tests/ReflectionProperty_constructor_variation1.phpt
@@ -0,0 +1,58 @@
+--TEST--
+ReflectionProperty::__construct(): ensure inherited private props can't be accessed through ReflectionProperty.
+--FILE--
+<?php
+
+class C {
+ private $p = 1;
+
+ static function testFromC() {
+ try {
+ $rp = new ReflectionProperty("D", "p");
+ var_dump($rp);
+ } catch (Exception $e) {
+ echo $e->getMessage();
+ }
+ }
+}
+
+class D extends C{
+ static function testFromD() {
+ try {
+ $rp = new ReflectionProperty("D", "p");
+ var_dump($rp);
+ } catch (Exception $e) {
+ echo $e->getMessage();
+ }
+ }
+}
+
+echo "--> Reflect inherited private from global scope:\n";
+try {
+ $rp = new ReflectionProperty("D", "p");
+ var_dump($rp);
+} catch (Exception $e) {
+ echo $e->getMessage();
+}
+
+echo "\n\n--> Reflect inherited private from declaring scope:\n";
+C::testFromC();
+
+echo "\n\n--> Reflect inherited private from declaring scope via subclass:\n";
+D::testFromC();
+
+echo "\n\n--> Reflect inherited private from subclass:\n";
+D::testFromD();
+?>
+--EXPECTF--
+--> Reflect inherited private from global scope:
+Property D::$p does not exist
+
+--> Reflect inherited private from declaring scope:
+Property D::$p does not exist
+
+--> Reflect inherited private from declaring scope via subclass:
+Property D::$p does not exist
+
+--> Reflect inherited private from subclass:
+Property D::$p does not exist \ No newline at end of file
diff --git a/ext/reflection/tests/ReflectionProperty_error.phpt b/ext/reflection/tests/ReflectionProperty_error.phpt
new file mode 100644
index 0000000..56de6e1
--- /dev/null
+++ b/ext/reflection/tests/ReflectionProperty_error.phpt
@@ -0,0 +1,67 @@
+--TEST--
+Test ReflectionProperty class errors.
+--FILE--
+<?php
+
+class C {
+ public static $p;
+}
+
+var_dump(new ReflectionProperty());
+var_dump(new ReflectionProperty('C::p'));
+var_dump(new ReflectionProperty('C', 'p', 'x'));
+$rp = new ReflectionProperty('C', 'p');
+var_dump($rp->getName(1));
+var_dump($rp->isPrivate(1));
+var_dump($rp->isProtected(1));
+var_dump($rp->isPublic(1));
+var_dump($rp->isStatic(1));
+var_dump($rp->getModifiers(1));
+var_dump($rp->isDefault(1));
+
+?>
+--EXPECTF--
+Warning: ReflectionProperty::__construct() expects exactly 2 parameters, 0 given in %s on line %d
+object(ReflectionProperty)#%d (2) {
+ ["name"]=>
+ string(0) ""
+ ["class"]=>
+ string(0) ""
+}
+
+Warning: ReflectionProperty::__construct() expects exactly 2 parameters, 1 given in %s on line %d
+object(ReflectionProperty)#%d (2) {
+ ["name"]=>
+ string(0) ""
+ ["class"]=>
+ string(0) ""
+}
+
+Warning: ReflectionProperty::__construct() expects exactly 2 parameters, 3 given in %s on line %d
+object(ReflectionProperty)#%d (2) {
+ ["name"]=>
+ string(0) ""
+ ["class"]=>
+ string(0) ""
+}
+
+Warning: ReflectionProperty::getName() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionProperty::isPrivate() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionProperty::isProtected() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionProperty::isPublic() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionProperty::isStatic() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionProperty::getModifiers() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionProperty::isDefault() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
diff --git a/ext/reflection/tests/ReflectionProperty_export_basic.phpt b/ext/reflection/tests/ReflectionProperty_export_basic.phpt
new file mode 100644
index 0000000..e77a3b7
--- /dev/null
+++ b/ext/reflection/tests/ReflectionProperty_export_basic.phpt
@@ -0,0 +1,16 @@
+--TEST--
+Test ReflectionProperty::export() usage.
+--FILE--
+<?php
+
+class TestClass {
+ public $proper = 5;
+}
+
+var_dump(ReflectionProperty::export('TestClass', 'proper'));
+
+?>
+--EXPECT--
+Property [ <default> public $proper ]
+
+NULL
diff --git a/ext/reflection/tests/ReflectionProperty_export_error.phpt b/ext/reflection/tests/ReflectionProperty_export_error.phpt
new file mode 100644
index 0000000..ab09ed0
--- /dev/null
+++ b/ext/reflection/tests/ReflectionProperty_export_error.phpt
@@ -0,0 +1,54 @@
+--TEST--
+Test ReflectionProperty::export() errors.
+--FILE--
+<?php
+
+class TestClass {
+}
+
+$a = 5;
+
+echo "Non-existent class:\n";
+try {
+ ReflectionProperty::export("NonExistentClass", "prop", true);
+}
+catch(Exception $e) {
+ echo $e->getMessage();
+}
+
+echo "\n\nWrong property parameter type:\n";
+try {
+ ReflectionProperty::export($a, 'TestClass', false);
+}
+catch(ReflectionException $e) {
+ echo $e->getMessage();
+}
+
+echo "\n\nNon-existent property:\n";
+try {
+ ReflectionProperty::export('TestClass', "nonExistentProperty", true);
+}
+catch(Exception $e) {
+ echo $e->getMessage();
+}
+
+echo "\n\nIncorrect number of args:\n";
+ReflectionProperty::export();
+ReflectionProperty::export('TestClass', "nonExistentProperty", true, false);
+
+?>
+--EXPECTF--
+Non-existent class:
+Class NonExistentClass does not exist
+
+Wrong property parameter type:
+The parameter class is expected to be either a string or an object
+
+Non-existent property:
+Property TestClass::$nonExistentProperty does not exist
+
+Incorrect number of args:
+
+Warning: ReflectionProperty::export() expects at least 2 parameters, 0 given in %s on line %d
+
+Warning: ReflectionProperty::export() expects at most 3 parameters, 4 given in %s on line %d
diff --git a/ext/reflection/tests/ReflectionProperty_getDeclaringClass_variation1.phpt b/ext/reflection/tests/ReflectionProperty_getDeclaringClass_variation1.phpt
new file mode 100644
index 0000000..bf525e1
--- /dev/null
+++ b/ext/reflection/tests/ReflectionProperty_getDeclaringClass_variation1.phpt
@@ -0,0 +1,27 @@
+--TEST--
+Test ReflectionProperty::getDeclaringClass() with inherited properties.
+--FILE--
+<?php
+
+class A {
+ public $prop;
+}
+
+class B extends A {
+}
+
+$propInfo = new ReflectionProperty('B', 'prop');
+var_dump($propInfo->getDeclaringClass());
+
+echo "Wrong number of params:\n";
+$propInfo->getDeclaringClass(1);
+
+?>
+--EXPECTF--
+object(ReflectionClass)#%d (1) {
+ ["name"]=>
+ string(1) "A"
+}
+Wrong number of params:
+
+Warning: ReflectionProperty::getDeclaringClass() expects exactly 0 parameters, 1 given in %s on line %d
diff --git a/ext/reflection/tests/ReflectionProperty_getDocComment_basic.phpt b/ext/reflection/tests/ReflectionProperty_getDocComment_basic.phpt
new file mode 100644
index 0000000..2c4815a
--- /dev/null
+++ b/ext/reflection/tests/ReflectionProperty_getDocComment_basic.phpt
@@ -0,0 +1,100 @@
+--TEST--
+Test ReflectionProperty::getDocComment() usage.
+--FILE--
+<?php
+
+class A {
+ /**
+ * My Doc Comment for $a
+ *
+ */
+ public $a = 2, $b, $c = 1;
+ /**
+ * My Doc Comment for $d
+ */
+ var $d;
+ /**Not a doc comment */
+ private $e;
+ /**
+ * Doc comment for $f
+ */
+ static protected $f;
+}
+
+class B extends A {
+ public $a = 2;
+ /** A doc comment for $b */
+ var $b, $c = 1;
+ /** A doc comment for $e */
+ var $e;
+}
+
+foreach(array('A', 'B') as $class) {
+ $rc = new ReflectionClass($class);
+ $rps = $rc->getProperties();
+ foreach($rps as $rp) {
+ echo "\n\n---> Doc comment for $class::$" . $rp->getName() . ":\n";
+ var_dump($rp->getDocComment());
+ }
+}
+
+?>
+--EXPECTF--
+
+---> Doc comment for A::$a:
+string(%d) "/**
+ * My Doc Comment for $a
+ *
+ */"
+
+
+---> Doc comment for A::$b:
+bool(false)
+
+
+---> Doc comment for A::$c:
+bool(false)
+
+
+---> Doc comment for A::$d:
+string(%d) "/**
+ * My Doc Comment for $d
+ */"
+
+
+---> Doc comment for A::$e:
+bool(false)
+
+
+---> Doc comment for A::$f:
+string(%d) "/**
+ * Doc comment for $f
+ */"
+
+
+---> Doc comment for B::$a:
+bool(false)
+
+
+---> Doc comment for B::$b:
+string(%d) "/** A doc comment for $b */"
+
+
+---> Doc comment for B::$c:
+bool(false)
+
+
+---> Doc comment for B::$e:
+string(%d) "/** A doc comment for $e */"
+
+
+---> Doc comment for B::$d:
+string(%d) "/**
+ * My Doc Comment for $d
+ */"
+
+
+---> Doc comment for B::$f:
+string(%d) "/**
+ * Doc comment for $f
+ */"
diff --git a/ext/reflection/tests/ReflectionProperty_getDocComment_error.phpt b/ext/reflection/tests/ReflectionProperty_getDocComment_error.phpt
new file mode 100644
index 0000000..dae7be2
--- /dev/null
+++ b/ext/reflection/tests/ReflectionProperty_getDocComment_error.phpt
@@ -0,0 +1,28 @@
+--TEST--
+Test ReflectionProperty::getDocComment() errors.
+--FILE--
+<?php
+
+class C {
+ public $a;
+}
+
+$rc = new ReflectionProperty('C', 'a');
+var_dump($rc->getDocComment(null));
+var_dump($rc->getDocComment('X'));
+var_dump($rc->getDocComment(true));
+var_dump($rc->getDocComment(array(1, 2, 3)));
+
+?>
+--EXPECTF--
+Warning: ReflectionProperty::getDocComment() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionProperty::getDocComment() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionProperty::getDocComment() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
+
+Warning: ReflectionProperty::getDocComment() expects exactly 0 parameters, 1 given in %s on line %d
+NULL
diff --git a/ext/reflection/tests/ReflectionProperty_getModifiers.001.phpt b/ext/reflection/tests/ReflectionProperty_getModifiers.001.phpt
new file mode 100644
index 0000000..fe888a8
--- /dev/null
+++ b/ext/reflection/tests/ReflectionProperty_getModifiers.001.phpt
@@ -0,0 +1,66 @@
+--TEST--
+ReflectionProperty::getModifiers()
+--CREDITS--
+Robin Fernandes <robinf@php.net>
+Steve Seear <stevseea@php.net>
+--FILE--
+<?php
+
+function reflectProperty($class, $property) {
+ $propInfo = new ReflectionProperty($class, $property);
+
+ echo "**********************************\n";
+ echo "Reflecting on property $class::$property\n\n";
+
+ echo "getModifiers():\n";
+ var_dump($propInfo->getModifiers());
+
+ echo "\n**********************************\n";
+}
+
+class TestClass
+{
+ public $pub;
+ static public $stat = "static property";
+ /**
+ * This property has a comment.
+ */
+ protected $prot = 4;
+ private $priv = "keepOut";
+}
+
+reflectProperty("TestClass", "pub");
+reflectProperty("TestClass", "stat");
+reflectProperty("TestClass", "prot");
+reflectProperty("TestClass", "priv");
+
+?>
+--EXPECT--
+**********************************
+Reflecting on property TestClass::pub
+
+getModifiers():
+int(256)
+
+**********************************
+**********************************
+Reflecting on property TestClass::stat
+
+getModifiers():
+int(257)
+
+**********************************
+**********************************
+Reflecting on property TestClass::prot
+
+getModifiers():
+int(512)
+
+**********************************
+**********************************
+Reflecting on property TestClass::priv
+
+getModifiers():
+int(1024)
+
+**********************************
diff --git a/ext/reflection/tests/ReflectionProperty_getModifiers_basic.phpt b/ext/reflection/tests/ReflectionProperty_getModifiers_basic.phpt
new file mode 100644
index 0000000..0d1b6bd
--- /dev/null
+++ b/ext/reflection/tests/ReflectionProperty_getModifiers_basic.phpt
@@ -0,0 +1,46 @@
+--TEST--
+Test ReflectionProperty::getModifiers() usage.
+--FILE--
+<?php
+
+class C {
+ public $a1;
+ protected $a2;
+ private $a3;
+ static public $a4;
+ static protected $a5;
+ static private $a6;
+}
+
+class D extends C {
+ public $a1;
+ protected $a2;
+ private $a3;
+ static public $a4;
+ static protected $a5;
+ static private $a6;
+}
+
+for ($i = 1;$i <= 6;$i++) {
+ $rp = new ReflectionProperty("C", "a$i");
+ echo "C::a$i: ";
+ var_dump($rp->getModifiers());
+ $rp = new ReflectionProperty("D", "a$i");
+ echo "D::a$i: ";
+ var_dump($rp->getModifiers());
+}
+
+?>
+--EXPECTF--
+C::a1: int(256)
+D::a1: int(256)
+C::a2: int(512)
+D::a2: int(512)
+C::a3: int(1024)
+D::a3: int(3072)
+C::a4: int(257)
+D::a4: int(257)
+C::a5: int(513)
+D::a5: int(513)
+C::a6: int(1025)
+D::a6: int(3073)
diff --git a/ext/reflection/tests/ReflectionProperty_getValue_error.phpt b/ext/reflection/tests/ReflectionProperty_getValue_error.phpt
new file mode 100644
index 0000000..c2152e9
--- /dev/null
+++ b/ext/reflection/tests/ReflectionProperty_getValue_error.phpt
@@ -0,0 +1,81 @@
+--TEST--
+Test ReflectionProperty::getValue() errors.
+--FILE--
+<?php
+
+class TestClass {
+ public $pub;
+ public $pub2 = 5;
+ static public $stat = "static property";
+ protected $prot = 4;
+ private $priv = "keepOut";
+}
+
+class AnotherClass {
+}
+
+$instance = new TestClass();
+$instanceWithNoProperties = new AnotherClass();
+$propInfo = new ReflectionProperty('TestClass', 'pub2');
+
+echo "Too few args:\n";
+var_dump($propInfo->getValue());
+
+echo "\nToo many args:\n";
+var_dump($propInfo->getValue($instance, true));
+
+echo "\nWrong type of arg:\n";
+var_dump($propInfo->getValue(true));
+
+echo "\nInstance without property:\n";
+$propInfo = new ReflectionProperty('TestClass', 'stat');
+
+echo "\nStatic property / too many args:\n";
+var_dump($propInfo->getValue($instance, true));
+
+echo "\nStatic property / wrong type of arg:\n";
+var_dump($propInfo->getValue(true));
+
+echo "\nProtected property:\n";
+try {
+ $propInfo = new ReflectionProperty('TestClass', 'prot');
+ var_dump($propInfo->getValue($instance));
+}
+catch(Exception $exc) {
+ echo $exc->getMessage();
+}
+
+echo "\n\nInstance without property:\n";
+$propInfo = new ReflectionProperty('TestClass', 'pub2');
+var_dump($propInfo->getValue($instanceWithNoProperties));
+
+?>
+--EXPECTF--
+Too few args:
+
+Warning: ReflectionProperty::getValue() expects exactly 1 parameter, 0 given in %s on line %d
+NULL
+
+Too many args:
+
+Warning: ReflectionProperty::getValue() expects exactly 1 parameter, 2 given in %s on line %d
+NULL
+
+Wrong type of arg:
+
+Warning: ReflectionProperty::getValue() expects parameter 1 to be object, boolean given in %s on line %d
+NULL
+
+Instance without property:
+
+Static property / too many args:
+string(15) "static property"
+
+Static property / wrong type of arg:
+string(15) "static property"
+
+Protected property:
+Cannot access non-public member TestClass::prot
+
+Instance without property:
+NULL
diff --git a/ext/reflection/tests/ReflectionProperty_isDefault_basic.phpt b/ext/reflection/tests/ReflectionProperty_isDefault_basic.phpt
new file mode 100644
index 0000000..22ee117
--- /dev/null
+++ b/ext/reflection/tests/ReflectionProperty_isDefault_basic.phpt
@@ -0,0 +1,63 @@
+--TEST--
+Test ReflectionProperty::isDefault() usage.
+--FILE--
+<?php
+
+function reflectProperty($class, $property) {
+ $propInfo = new ReflectionProperty($class, $property);
+ echo "**********************************\n";
+ echo "Reflecting on property $class::$property\n\n";
+ echo "isDefault():\n";
+ var_dump($propInfo->isDefault());
+ echo "\n**********************************\n";
+}
+
+class TestClass {
+ public $pub;
+ static public $stat = "static property";
+ protected $prot = 4;
+ private $priv = "keepOut";
+}
+
+reflectProperty("TestClass", "pub");
+reflectProperty("TestClass", "stat");
+reflectProperty("TestClass", "prot");
+reflectProperty("TestClass", "priv");
+
+echo "Wrong number of params:\n";
+$propInfo = new ReflectionProperty('TestClass', 'pub');
+$propInfo->isDefault(1);
+
+?>
+--EXPECTF--
+**********************************
+Reflecting on property TestClass::pub
+
+isDefault():
+bool(true)
+
+**********************************
+**********************************
+Reflecting on property TestClass::stat
+
+isDefault():
+bool(true)
+
+**********************************
+**********************************
+Reflecting on property TestClass::prot
+
+isDefault():
+bool(true)
+
+**********************************
+**********************************
+Reflecting on property TestClass::priv
+
+isDefault():
+bool(true)
+
+**********************************
+Wrong number of params:
+
+Warning: ReflectionProperty::isDefault() expects exactly 0 parameters, 1 given in %s on line %d
diff --git a/ext/reflection/tests/ReflectionProperty_setAccessible.phpt b/ext/reflection/tests/ReflectionProperty_setAccessible.phpt
new file mode 100644
index 0000000..cc184c1
--- /dev/null
+++ b/ext/reflection/tests/ReflectionProperty_setAccessible.phpt
@@ -0,0 +1,139 @@
+--TEST--
+Test ReflectionProperty::setAccessible().
+--FILE--
+<?php
+class A {
+ protected $protected = 'a';
+ protected static $protectedStatic = 'b';
+ private $private = 'c';
+ private static $privateStatic = 'd';
+}
+
+class B extends A {}
+
+$a = new A;
+$protected = new ReflectionProperty($a, 'protected');
+$protectedStatic = new ReflectionProperty('A', 'protectedStatic');
+$private = new ReflectionProperty($a, 'private');
+$privateStatic = new ReflectionProperty('A', 'privateStatic');
+
+try {
+ var_dump($protected->getValue($a));
+}
+
+catch (ReflectionException $e) {
+ var_dump($e->getMessage());
+}
+
+try {
+ var_dump($protectedStatic->getValue());
+}
+
+catch (ReflectionException $e) {
+ var_dump($e->getMessage());
+}
+
+try {
+ var_dump($private->getValue($a));
+}
+
+catch (ReflectionException $e) {
+ var_dump($e->getMessage());
+}
+
+try {
+ var_dump($privateStatic->getValue());
+}
+
+catch (ReflectionException $e) {
+ var_dump($e->getMessage());
+}
+
+$protected->setAccessible(TRUE);
+$protectedStatic->setAccessible(TRUE);
+$private->setAccessible(TRUE);
+$privateStatic->setAccessible(TRUE);
+
+var_dump($protected->getValue($a));
+var_dump($protectedStatic->getValue());
+var_dump($private->getValue($a));
+var_dump($privateStatic->getValue());
+
+$protected->setValue($a, 'e');
+$protectedStatic->setValue('f');
+$private->setValue($a, 'g');
+$privateStatic->setValue('h');
+
+var_dump($protected->getValue($a));
+var_dump($protectedStatic->getValue());
+var_dump($private->getValue($a));
+var_dump($privateStatic->getValue());
+
+$a = new A;
+$b = new B;
+$protected = new ReflectionProperty($b, 'protected');
+$protectedStatic = new ReflectionProperty('B', 'protectedStatic');
+$private = new ReflectionProperty($a, 'private');
+
+try {
+ var_dump($protected->getValue($b));
+}
+
+catch (ReflectionException $e) {
+ var_dump($e->getMessage());
+}
+
+try {
+ var_dump($protectedStatic->getValue());
+}
+
+catch (ReflectionException $e) {
+ var_dump($e->getMessage());
+}
+
+try {
+ var_dump($private->getValue($b));
+}
+
+catch (ReflectionException $e) {
+ var_dump($e->getMessage());
+}
+
+$protected->setAccessible(TRUE);
+$protectedStatic->setAccessible(TRUE);
+$private->setAccessible(TRUE);
+
+var_dump($protected->getValue($b));
+var_dump($protectedStatic->getValue());
+var_dump($private->getValue($b));
+
+$protected->setValue($b, 'e');
+$protectedStatic->setValue('f');
+$private->setValue($b, 'g');
+
+var_dump($protected->getValue($b));
+var_dump($protectedStatic->getValue());
+var_dump($private->getValue($b));
+?>
+--EXPECT--
+string(44) "Cannot access non-public member A::protected"
+string(50) "Cannot access non-public member A::protectedStatic"
+string(42) "Cannot access non-public member A::private"
+string(48) "Cannot access non-public member A::privateStatic"
+string(1) "a"
+string(1) "b"
+string(1) "c"
+string(1) "d"
+string(1) "e"
+string(1) "f"
+string(1) "g"
+string(1) "h"
+string(44) "Cannot access non-public member B::protected"
+string(50) "Cannot access non-public member B::protectedStatic"
+string(42) "Cannot access non-public member A::private"
+string(1) "a"
+string(1) "f"
+string(1) "c"
+string(1) "e"
+string(1) "f"
+string(1) "g"
diff --git a/ext/reflection/tests/ReflectionProperty_setValue_error.phpt b/ext/reflection/tests/ReflectionProperty_setValue_error.phpt
new file mode 100644
index 0000000..7161c53
--- /dev/null
+++ b/ext/reflection/tests/ReflectionProperty_setValue_error.phpt
@@ -0,0 +1,100 @@
+--TEST--
+Test ReflectionProperty::setValue() error cases.
+--FILE--
+<?php
+
+class TestClass {
+ public $pub;
+ public $pub2 = 5;
+ static public $stat = "static property";
+ protected $prot = 4;
+ private $priv = "keepOut";
+}
+
+class AnotherClass {
+}
+
+$instance = new TestClass();
+$instanceWithNoProperties = new AnotherClass();
+$propInfo = new ReflectionProperty('TestClass', 'pub2');
+
+echo "Too few args:\n";
+var_dump($propInfo->setValue());
+var_dump($propInfo->setValue($instance));
+
+echo "\nToo many args:\n";
+var_dump($propInfo->setValue($instance, "NewValue", true));
+
+echo "\nWrong type of arg:\n";
+var_dump($propInfo->setValue(true, "NewValue"));
+$propInfo = new ReflectionProperty('TestClass', 'stat');
+
+echo "\nStatic property / too many args:\n";
+var_dump($propInfo->setValue($instance, "NewValue", true));
+
+echo "\nStatic property / too few args:\n";
+var_dump($propInfo->setValue("A new value"));
+var_dump(TestClass::$stat);
+var_dump($propInfo->setValue());
+var_dump(TestClass::$stat);
+
+echo "\nStatic property / wrong type of arg:\n";
+var_dump($propInfo->setValue(true, "Another new value"));
+var_dump(TestClass::$stat);
+
+echo "\nProtected property:\n";
+try {
+ $propInfo = new ReflectionProperty('TestClass', 'prot');
+ var_dump($propInfo->setValue($instance, "NewValue"));
+}
+catch(Exception $exc) {
+ echo $exc->getMessage();
+}
+
+echo "\n\nInstance without property:\n";
+$propInfo = new ReflectionProperty('TestClass', 'pub2');
+var_dump($propInfo->setValue($instanceWithNoProperties, "NewValue"));
+var_dump($instanceWithNoProperties->pub2);
+?>
+--EXPECTF--
+Too few args:
+
+Warning: ReflectionProperty::setValue() expects exactly 2 parameters, 0 given in %s on line %d
+NULL
+
+Warning: ReflectionProperty::setValue() expects exactly 2 parameters, 1 given in %s on line %d
+NULL
+
+Too many args:
+
+Warning: ReflectionProperty::setValue() expects exactly 2 parameters, 3 given in %s on line %d
+NULL
+
+Wrong type of arg:
+
+Warning: ReflectionProperty::setValue() expects parameter 1 to be object, boolean given in %s on line %d
+NULL
+
+Static property / too many args:
+
+Warning: ReflectionProperty::setValue() expects exactly 2 parameters, 3 given in %s on line %d
+NULL
+
+Static property / too few args:
+NULL
+string(11) "A new value"
+
+Warning: ReflectionProperty::setValue() expects exactly 2 parameters, 0 given in %s on line %d
+NULL
+string(11) "A new value"
+
+Static property / wrong type of arg:
+NULL
+string(17) "Another new value"
+
+Protected property:
+Cannot access non-public member TestClass::prot
+
+Instance without property:
+NULL
+string(8) "NewValue"
diff --git a/ext/reflection/tests/bug26640.phpt b/ext/reflection/tests/bug26640.phpt
new file mode 100644
index 0000000..e375fd4
--- /dev/null
+++ b/ext/reflection/tests/bug26640.phpt
@@ -0,0 +1,25 @@
+--TEST--
+Reflection Bug #26640 (__autoload() not invoked by Reflection classes)
+--FILE--
+<?php
+
+function __autoload($c)
+{
+ class autoload_class
+ {
+ public function __construct()
+ {
+ print "autoload success\n";
+ }
+ }
+}
+
+$a = new ReflectionClass('autoload_class');
+
+if (is_object($a)) {
+ echo "OK\n";
+}
+
+?>
+--EXPECT--
+OK
diff --git a/ext/reflection/tests/bug26695.phpt b/ext/reflection/tests/bug26695.phpt
new file mode 100644
index 0000000..e429f76
--- /dev/null
+++ b/ext/reflection/tests/bug26695.phpt
@@ -0,0 +1,25 @@
+--TEST--
+Reflection Bug #26695 (Reflection API does not recognize mixed-case class hints)
+--FILE--
+<?php
+
+class Foo {
+}
+
+class Bar {
+ function demo(foo $f) {
+ }
+}
+
+$class = new ReflectionClass('bar');
+$methods = $class->getMethods();
+$params = $methods[0]->getParameters();
+
+$class = $params[0]->getClass();
+
+var_dump($class->getName());
+?>
+===DONE===
+--EXPECT--
+string(3) "Foo"
+===DONE===
diff --git a/ext/reflection/tests/bug29268.phpt b/ext/reflection/tests/bug29268.phpt
new file mode 100644
index 0000000..d8efc0b
--- /dev/null
+++ b/ext/reflection/tests/bug29268.phpt
@@ -0,0 +1,27 @@
+--TEST--
+Reflection Bug #29268 (__autoload() not called with reflectionProperty->getClass())
+--FILE--
+<?php
+function __autoload($classname) {
+ echo "__autoload($classname)\n";
+ eval("class $classname {}");
+}
+
+class B{
+ public function doit(A $a){
+ }
+}
+
+$ref = new reflectionMethod('B','doit');
+$parameters = $ref->getParameters();
+foreach($parameters as $parameter)
+{
+ $class = $parameter->getClass();
+ echo $class->name."\n";
+}
+echo "ok\n";
+?>
+--EXPECT--
+__autoload(A)
+A
+ok
diff --git a/ext/reflection/tests/bug29523.phpt b/ext/reflection/tests/bug29523.phpt
new file mode 100644
index 0000000..e74403c
--- /dev/null
+++ b/ext/reflection/tests/bug29523.phpt
@@ -0,0 +1,38 @@
+--TEST--
+Reflection Bug #29523 (ReflectionParameter::isOptional() is incorrect)
+--FILE--
+<?php
+
+class TestClass
+{
+}
+
+function optionalTest(TestClass $a, TestClass $b, $c = 3)
+{
+}
+
+$function = new ReflectionFunction('optionalTest');
+$numberOfNotOptionalParameters = 0;
+$numberOfOptionalParameters = 0;
+foreach($function->getParameters() as $parameter)
+{
+ var_dump($parameter->isOptional());
+ if ($parameter->isOptional())
+ {
+ ++$numberOfOptionalParameters;
+ }
+ else
+ {
+ ++$numberOfNotOptionalParameters;
+ }
+}
+var_dump($function->getNumberOfRequiredParameters());
+var_dump($numberOfNotOptionalParameters);
+
+?>
+--EXPECT--
+bool(false)
+bool(false)
+bool(true)
+int(2)
+int(2)
diff --git a/ext/reflection/tests/bug29828.phpt b/ext/reflection/tests/bug29828.phpt
new file mode 100644
index 0000000..43e32d2
--- /dev/null
+++ b/ext/reflection/tests/bug29828.phpt
@@ -0,0 +1,35 @@
+--TEST--
+Reflection Bug #29828 (Interfaces no longer work)
+--FILE--
+<?php
+
+interface Bla
+{
+ function bla();
+}
+
+class BlaMore implements Bla
+{
+ function bla()
+ {
+ echo "Hello\n";
+ }
+}
+
+$r = new ReflectionClass('BlaMore');
+
+var_dump(count($r->getMethods()));
+var_dump($r->getMethod('bla')->isConstructor());
+var_dump($r->getMethod('bla')->isAbstract());
+
+$o=new BlaMore;
+$o->bla();
+
+?>
+===DONE===
+--EXPECT--
+int(1)
+bool(false)
+bool(false)
+Hello
+===DONE===
diff --git a/ext/reflection/tests/bug29986.phpt b/ext/reflection/tests/bug29986.phpt
new file mode 100644
index 0000000..d30b3a6
--- /dev/null
+++ b/ext/reflection/tests/bug29986.phpt
@@ -0,0 +1,41 @@
+--TEST--
+Reflection Bug #29986 (Class constants won't work with predefined constants when using ReflectionClass)
+--INI--
+precision=14
+--FILE--
+<?php
+class just_constants
+{
+ const BOOLEAN_CONSTANT = true;
+ const NULL_CONSTANT = null;
+ const STRING_CONSTANT = 'This is a string';
+ const INTEGER_CONSTANT = 1000;
+ const FLOAT_CONSTANT = 3.14159265;
+}
+
+Reflection::export(new ReflectionClass('just_constants'));
+?>
+--EXPECTF--
+Class [ <user> class just_constants ] {
+ @@ %s %d-%d
+
+ - Constants [5] {
+ Constant [ boolean BOOLEAN_CONSTANT ] { 1 }
+ Constant [ null NULL_CONSTANT ] { }
+ Constant [ string STRING_CONSTANT ] { This is a string }
+ Constant [ integer INTEGER_CONSTANT ] { 1000 }
+ Constant [ double FLOAT_CONSTANT ] { 3.14159265 }
+ }
+
+ - Static properties [0] {
+ }
+
+ - Static methods [0] {
+ }
+
+ - Properties [0] {
+ }
+
+ - Methods [0] {
+ }
+}
diff --git a/ext/reflection/tests/bug30146.phpt b/ext/reflection/tests/bug30146.phpt
new file mode 100644
index 0000000..3f62141
--- /dev/null
+++ b/ext/reflection/tests/bug30146.phpt
@@ -0,0 +1,23 @@
+--TEST--
+Reflection Bug #30146 (ReflectionProperty->getValue() requires instance for static property)
+--FILE--
+<?php
+class test {
+ static public $a = 1;
+}
+
+$r = new ReflectionProperty('test', 'a');
+var_dump($r->getValue(null));
+
+$r->setValue(NULL, 2);
+var_dump($r->getValue());
+
+$r->setValue(3);
+var_dump($r->getValue());
+?>
+===DONE===
+--EXPECT--
+int(1)
+int(2)
+int(3)
+===DONE===
diff --git a/ext/reflection/tests/bug30148.phpt b/ext/reflection/tests/bug30148.phpt
new file mode 100644
index 0000000..aa5841e
--- /dev/null
+++ b/ext/reflection/tests/bug30148.phpt
@@ -0,0 +1,35 @@
+--TEST--
+Reflection Bug #30148 (ReflectionMethod->isConstructor() fails for inherited classes)
+--FILE--
+<?php
+
+class Root
+{
+ function Root() {}
+}
+class Base extends Root
+{
+ function __construct() {}
+}
+class Derived extends Base
+{
+}
+$a = new ReflectionMethod('Root','Root');
+$b = new ReflectionMethod('Base','Root');
+$c = new ReflectionMethod('Base','__construct');
+$d = new ReflectionMethod('Derived','Root');
+$e = new ReflectionMethod('Derived','__construct');
+var_dump($a->isConstructor());
+var_dump($b->isConstructor());
+var_dump($c->isConstructor());
+var_dump($d->isConstructor());
+var_dump($e->isConstructor());
+?>
+===DONE===
+--EXPECT--
+bool(true)
+bool(false)
+bool(true)
+bool(false)
+bool(true)
+===DONE===
diff --git a/ext/reflection/tests/bug30209.phpt b/ext/reflection/tests/bug30209.phpt
new file mode 100644
index 0000000..2735a74
--- /dev/null
+++ b/ext/reflection/tests/bug30209.phpt
@@ -0,0 +1,31 @@
+--TEST--
+Reflection Bug #30209 (ReflectionClass::getMethod() lowercases attribute)
+--FILE--
+<?php
+
+class Foo
+{
+ private $name = 'testBAR';
+
+ public function testBAR()
+ {
+ try
+ {
+ $class = new ReflectionClass($this);
+ var_dump($this->name);
+ $method = $class->getMethod($this->name);
+ var_dump($this->name);
+ }
+
+ catch (Exception $e) {}
+ }
+}
+
+$foo = new Foo;
+$foo->testBAR();
+?>
+===DONE===
+--EXPECTF--
+string(7) "testBAR"
+string(7) "testBAR"
+===DONE===
diff --git a/ext/reflection/tests/bug30856.phpt b/ext/reflection/tests/bug30856.phpt
new file mode 100644
index 0000000..39fc110
--- /dev/null
+++ b/ext/reflection/tests/bug30856.phpt
@@ -0,0 +1,20 @@
+--TEST--
+Reflection Bug #30856 (ReflectionClass::getStaticProperties segfaults)
+--FILE--
+<?php
+class bogus {
+ const C = 'test';
+ static $a = bogus::C;
+}
+
+$class = new ReflectionClass('bogus');
+
+var_dump($class->getStaticProperties());
+?>
+===DONE===
+--EXPECT--
+array(1) {
+ ["a"]=>
+ string(4) "test"
+}
+===DONE===
diff --git a/ext/reflection/tests/bug30961.phpt b/ext/reflection/tests/bug30961.phpt
new file mode 100644
index 0000000..a61c992
--- /dev/null
+++ b/ext/reflection/tests/bug30961.phpt
@@ -0,0 +1,20 @@
+--TEST--
+Reflection Bug #30961 (Wrong linenumber in ReflectionClass getStartLine())
+--FILE--
+<?php
+ class a
+ {
+ }
+
+ class b extends a
+ {
+ }
+
+ $ref1 = new ReflectionClass('a');
+ $ref2 = new ReflectionClass('b');
+ echo $ref1->getStartLine() . "\n";
+ echo $ref2->getStartLine() . "\n";
+?>
+--EXPECT--
+2
+6
diff --git a/ext/reflection/tests/bug31651.phpt b/ext/reflection/tests/bug31651.phpt
new file mode 100644
index 0000000..59f19ea
--- /dev/null
+++ b/ext/reflection/tests/bug31651.phpt
@@ -0,0 +1,24 @@
+--TEST--
+Reflection Bug #31651 (ReflectionClass::getDefaultProperties segfaults with arrays.)
+--FILE--
+<?php
+
+class Test
+{
+ public $a = array('a' => 1);
+}
+
+$ref = new ReflectionClass('Test');
+
+print_r($ref->getDefaultProperties());
+
+?>
+--EXPECT--
+Array
+(
+ [a] => Array
+ (
+ [a] => 1
+ )
+
+)
diff --git a/ext/reflection/tests/bug32981.phpt b/ext/reflection/tests/bug32981.phpt
new file mode 100644
index 0000000..5735674
--- /dev/null
+++ b/ext/reflection/tests/bug32981.phpt
@@ -0,0 +1,34 @@
+--TEST--
+Reflection Bug #32981 (ReflectionMethod::getStaticVariables() causes apache2.0.54 seg fault)
+--FILE--
+<?php
+
+class TestClass
+{
+ static function test()
+ {
+ static $enabled = true;
+ }
+}
+
+$class = new ReflectionClass('TestClass');
+foreach ($class->getMethods() as $method)
+{
+ var_dump($method->getName());
+ $arr_static_vars[] = $method->getStaticVariables();
+}
+
+var_dump($arr_static_vars);
+
+?>
+===DONE===
+--EXPECT--
+string(4) "test"
+array(1) {
+ [0]=>
+ array(1) {
+ ["enabled"]=>
+ bool(true)
+ }
+}
+===DONE===
diff --git a/ext/reflection/tests/bug33312.phpt b/ext/reflection/tests/bug33312.phpt
new file mode 100644
index 0000000..ffa9180
--- /dev/null
+++ b/ext/reflection/tests/bug33312.phpt
@@ -0,0 +1,20 @@
+--TEST--
+Reflection Bug #33312 (ReflectionParameter methods do not work correctly)
+--FILE--
+<?php
+class Foo {
+ public function bar(Foo $foo, $bar = 'bar') {
+ }
+}
+
+$class = new ReflectionClass('Foo');
+$method = $class->getMethod('bar');
+
+foreach ($method->getParameters() as $parameter) {
+ if ($parameter->isDefaultValueAvailable()) {
+ print $parameter->getDefaultValue()."\n";
+ }
+}
+?>
+--EXPECT--
+bar
diff --git a/ext/reflection/tests/bug33389.phpt b/ext/reflection/tests/bug33389.phpt
new file mode 100644
index 0000000..f1997a3
--- /dev/null
+++ b/ext/reflection/tests/bug33389.phpt
@@ -0,0 +1,97 @@
+--TEST--
+Reflection Bug #33389 (double free() when exporting a ReflectionClass)
+--FILE--
+<?php
+define ('foobar', 1);
+class Test {
+ function foo1($arg=foobar) {
+ }
+ function foo2($arg=null) {
+ }
+ function foo3($arg=false) {
+ }
+ function foo4($arg='foo') {
+ }
+ function foo5($arg=1) {
+ }
+ function bar($arg) {
+ }
+ function foo() {
+ }
+}
+Reflection::export(new ReflectionClass('Test'));
+?>
+===DONE===
+<?php exit(0); ?>
+--EXPECTF--
+Class [ <user> class Test ] {
+ @@ %sbug33389.php 3-18
+
+ - Constants [0] {
+ }
+
+ - Static properties [0] {
+ }
+
+ - Static methods [0] {
+ }
+
+ - Properties [0] {
+ }
+
+ - Methods [7] {
+ Method [ <user> public method foo1 ] {
+ @@ %sbug33389.php 4 - 5
+
+ - Parameters [1] {
+ Parameter #0 [ <optional> $arg = 1 ]
+ }
+ }
+
+ Method [ <user> public method foo2 ] {
+ @@ %sbug33389.php 6 - 7
+
+ - Parameters [1] {
+ Parameter #0 [ <optional> $arg = NULL ]
+ }
+ }
+
+ Method [ <user> public method foo3 ] {
+ @@ %sbug33389.php 8 - 9
+
+ - Parameters [1] {
+ Parameter #0 [ <optional> $arg = false ]
+ }
+ }
+
+ Method [ <user> public method foo4 ] {
+ @@ %sbug33389.php 10 - 11
+
+ - Parameters [1] {
+ Parameter #0 [ <optional> $arg = 'foo' ]
+ }
+ }
+
+ Method [ <user> public method foo5 ] {
+ @@ %sbug33389.php 12 - 13
+
+ - Parameters [1] {
+ Parameter #0 [ <optional> $arg = 1 ]
+ }
+ }
+
+ Method [ <user> public method bar ] {
+ @@ %sbug33389.php 14 - 15
+
+ - Parameters [1] {
+ Parameter #0 [ <required> $arg ]
+ }
+ }
+
+ Method [ <user> public method foo ] {
+ @@ %sbug33389.php 16 - 17
+ }
+ }
+}
+
+===DONE===
diff --git a/ext/reflection/tests/bug36308.phpt b/ext/reflection/tests/bug36308.phpt
new file mode 100644
index 0000000..79aa5f8
--- /dev/null
+++ b/ext/reflection/tests/bug36308.phpt
@@ -0,0 +1,20 @@
+--TEST--
+Reflection Bug #36308 (ReflectionProperty::getDocComment() does not reflect extended class commentary)
+--FILE--
+<?php
+class Base {
+ /** Base comment block */
+ public $foo = 'bar';
+}
+
+class Extended extends Base {
+ /** Extended commentary */
+ public $foo = 'zim';
+}
+
+$reflect = new ReflectionClass('Extended');
+$props = $reflect->getProperties();
+echo $props[0]->getDocComment();
+?>
+--EXPECT--
+/** Extended commentary */
diff --git a/ext/reflection/tests/bug36337.phpt b/ext/reflection/tests/bug36337.phpt
new file mode 100644
index 0000000..369d5be
--- /dev/null
+++ b/ext/reflection/tests/bug36337.phpt
@@ -0,0 +1,28 @@
+--TEST--
+Reflection Bug #36337 (ReflectionProperty fails to return correct visibility)
+--FILE--
+<?php
+
+abstract class enum {
+ protected $_values;
+
+ public function __construct() {
+ $property = new ReflectionProperty(get_class($this),'_values');
+ var_dump($property->isProtected());
+ }
+
+}
+
+final class myEnum extends enum {
+ public $_values = array(
+ 0 => 'No value',
+ );
+}
+
+$x = new myEnum();
+
+echo "Done\n";
+?>
+--EXPECT--
+bool(false)
+Done
diff --git a/ext/reflection/tests/bug36434.phpt b/ext/reflection/tests/bug36434.phpt
new file mode 100644
index 0000000..218055d
--- /dev/null
+++ b/ext/reflection/tests/bug36434.phpt
@@ -0,0 +1,31 @@
+--TEST--
+Reflection Bug #36434 (Properties from parent class fail to indetify their true origin)
+--FILE--
+<?php
+class ancester
+{
+public $ancester = 0;
+ function ancester()
+ {
+ return $this->ancester;
+ }
+}
+class foo extends ancester
+{
+public $bar = "1";
+ function foo()
+ {
+ return $this->bar;
+ }
+}
+
+$r = new ReflectionClass('foo');
+foreach ($r->GetProperties() as $p)
+{
+ echo $p->getName(). " ". $p->getDeclaringClass()->getName()."\n";
+}
+
+?>
+--EXPECT--
+bar foo
+ancester ancester
diff --git a/ext/reflection/tests/bug37816.phpt b/ext/reflection/tests/bug37816.phpt
new file mode 100644
index 0000000..18a4904
--- /dev/null
+++ b/ext/reflection/tests/bug37816.phpt
@@ -0,0 +1,28 @@
+--TEST--
+Bug #37816 (ReflectionProperty does not throw exception when accessing protected attribute)
+--FILE--
+<?php
+
+class TestClass
+{
+ protected $p = 2;
+}
+
+$o = new TestClass;
+
+$r = new ReflectionProperty($o, 'p');
+
+try
+{
+ $x = $r->getValue($o);
+}
+catch (Exception $e)
+{
+ echo 'Caught: ' . $e->getMessage() . "\n";
+}
+
+?>
+===DONE===
+--EXPECTF--
+Caught: Cannot access non-public member TestClass::p
+===DONE===
diff --git a/ext/reflection/tests/bug37964.phpt b/ext/reflection/tests/bug37964.phpt
new file mode 100644
index 0000000..9351193
--- /dev/null
+++ b/ext/reflection/tests/bug37964.phpt
@@ -0,0 +1,50 @@
+--TEST--
+Reflection Bug #37964 (Reflection shows private methods of parent class)
+--FILE--
+<?php
+
+abstract class foobar {
+ private function test2() {
+ }
+}
+class foo extends foobar {
+ private $foo = 1;
+ private function test() {
+ }
+ protected function test3() {
+ }
+}
+class bar extends foo {
+ private function foobar() {
+ }
+}
+
+Reflection::export(new ReflectionClass(new bar));
+
+?>
+--EXPECTF--
+Class [ <user> class bar extends foo ] {
+ @@ %s %s
+
+ - Constants [0] {
+ }
+
+ - Static properties [0] {
+ }
+
+ - Static methods [0] {
+ }
+
+ - Properties [0] {
+ }
+
+ - Methods [2] {
+ Method [ <user> private method foobar ] {
+ @@ %s %d - %d
+ }
+
+ Method [ <user, inherits foo> protected method test3 ] {
+ @@ %s %d - %d
+ }
+ }
+}
diff --git a/ext/reflection/tests/bug38132.phpt b/ext/reflection/tests/bug38132.phpt
new file mode 100644
index 0000000..16e5641
--- /dev/null
+++ b/ext/reflection/tests/bug38132.phpt
@@ -0,0 +1,32 @@
+--TEST--
+Reflection Bug #38132 (ReflectionClass::getStaticProperties() retains \0 in key names)
+--FILE--
+<?php
+class foo {
+ static protected $bar = 'baz';
+ static public $a = 'a';
+}
+
+$class = new ReflectionClass('foo');
+$properties = $class->getStaticProperties();
+var_dump($properties, array_keys($properties));
+var_dump(isset($properties['*bar']));
+var_dump(isset($properties["\0*\0bar"]));
+var_dump(isset($properties["bar"]));
+?>
+--EXPECT--
+array(2) {
+ ["bar"]=>
+ string(3) "baz"
+ ["a"]=>
+ string(1) "a"
+}
+array(2) {
+ [0]=>
+ string(3) "bar"
+ [1]=>
+ string(1) "a"
+}
+bool(false)
+bool(false)
+bool(true)
diff --git a/ext/reflection/tests/bug38194.phpt b/ext/reflection/tests/bug38194.phpt
new file mode 100644
index 0000000..d12f4e4
--- /dev/null
+++ b/ext/reflection/tests/bug38194.phpt
@@ -0,0 +1,11 @@
+--TEST--
+Reflection Bug #38194 (ReflectionClass::isSubclassOf() returns TRUE for the class itself)
+--FILE--
+<?php
+class Object { }
+
+$objectClass= new ReflectionClass('Object');
+var_dump($objectClass->isSubclassOf($objectClass));
+?>
+--EXPECT--
+bool(false)
diff --git a/ext/reflection/tests/bug38217.phpt b/ext/reflection/tests/bug38217.phpt
new file mode 100644
index 0000000..cf007d9
--- /dev/null
+++ b/ext/reflection/tests/bug38217.phpt
@@ -0,0 +1,40 @@
+--TEST--
+Bug #38217 (ReflectionClass::newInstanceArgs() tries to allocate too much memory)
+--FILE--
+<?php
+
+class Object {
+ public function __construct() {
+ }
+}
+
+$class= new ReflectionClass('Object');
+var_dump($class->newInstanceArgs());
+
+class Object1 {
+ public function __construct($var) {
+ var_dump($var);
+ }
+}
+
+$class= new ReflectionClass('Object1');
+var_dump($class->newInstanceArgs());
+var_dump($class->newInstanceArgs(array('test')));
+
+
+echo "Done\n";
+?>
+--EXPECTF--
+object(Object)#%d (0) {
+}
+
+Warning: Missing argument 1 for Object1::__construct() in %s on line %d
+
+Notice: Undefined variable: var in %s on line %d
+NULL
+object(Object1)#%d (0) {
+}
+string(4) "test"
+object(Object1)#%d (0) {
+}
+Done
diff --git a/ext/reflection/tests/bug38465.phpt b/ext/reflection/tests/bug38465.phpt
new file mode 100644
index 0000000..f40d487
--- /dev/null
+++ b/ext/reflection/tests/bug38465.phpt
@@ -0,0 +1,64 @@
+--TEST--
+Bug #38465 (ReflectionParameter fails on access to self::)
+--FILE--
+<?php
+class Baz {
+ const B = 3;
+}
+
+class Foo {
+ const X = 1;
+ public function x($a = self::X, $b = Baz::B, $c = 99) {}
+}
+
+class Bar extends Foo {
+ const Y = 2;
+ public function y($a = self::Y, $b = Baz::B, $c = 99) {}
+}
+
+
+echo "From global scope:\n";
+
+$clazz = new ReflectionClass('Bar');
+foreach ($clazz->getMethods() as $method) {
+ foreach ($method->getParameters() as $param) {
+ if ($param->isDefaultValueAvailable()) {
+ echo $method->getDeclaringClass()->getName(), '::', $method->getName(), '($', $param->getName(), ' = ', $param->getDefaultValue(), ")\n";
+ }
+ }
+}
+
+echo "\nFrom class context:\n";
+
+class Test {
+ function __construct() {
+ $clazz = new ReflectionClass('Bar');
+ foreach ($clazz->getMethods() as $method) {
+ foreach ($method->getParameters() as $param) {
+ if ($param->isDefaultValueAvailable()) {
+ echo $method->getDeclaringClass()->getName(), '::', $method->getName(), '($', $param->getName(), ' = ', $param->getDefaultValue(), ")\n";
+ }
+ }
+ }
+ }
+}
+
+new Test();
+
+?>
+--EXPECT--
+From global scope:
+Bar::y($a = 2)
+Bar::y($b = 3)
+Bar::y($c = 99)
+Foo::x($a = 1)
+Foo::x($b = 3)
+Foo::x($c = 99)
+
+From class context:
+Bar::y($a = 2)
+Bar::y($b = 3)
+Bar::y($c = 99)
+Foo::x($a = 1)
+Foo::x($b = 3)
+Foo::x($c = 99)
diff --git a/ext/reflection/tests/bug38653.phpt b/ext/reflection/tests/bug38653.phpt
new file mode 100644
index 0000000..68781d2
--- /dev/null
+++ b/ext/reflection/tests/bug38653.phpt
@@ -0,0 +1,28 @@
+--TEST--
+Bug #38653 (memory leak in ReflectionClass::getConstant())
+--FILE--
+<?php
+
+class foo {
+ const cons = 10;
+ const cons1 = "";
+ const cons2 = "test";
+}
+
+class bar extends foo {
+}
+
+$foo = new ReflectionClass("foo");
+var_dump($foo->getConstant("cons"));
+var_dump($foo->getConstant("cons1"));
+var_dump($foo->getConstant("cons2"));
+var_dump($foo->getConstant("no such const"));
+
+echo "Done\n";
+?>
+--EXPECTF--
+int(10)
+string(0) ""
+string(4) "test"
+bool(false)
+Done
diff --git a/ext/reflection/tests/bug38942.phpt b/ext/reflection/tests/bug38942.phpt
new file mode 100644
index 0000000..817190c
--- /dev/null
+++ b/ext/reflection/tests/bug38942.phpt
@@ -0,0 +1,34 @@
+--TEST--
+Bug #38942 (Double old-style-ctor inheritance)
+--FILE--
+<?php
+class foo {
+ public function foo() {}
+}
+
+class bar extends foo {
+}
+ReflectionClass::export("bar");
+?>
+--EXPECTF--
+Class [ <user> class bar extends foo ] {
+ @@ %sbug38942.php 6-7
+
+ - Constants [0] {
+ }
+
+ - Static properties [0] {
+ }
+
+ - Static methods [0] {
+ }
+
+ - Properties [0] {
+ }
+
+ - Methods [1] {
+ Method [ <user, inherits foo, ctor> public method foo ] {
+ @@ %sbug38942.php 3 - 3
+ }
+ }
+}
diff --git a/ext/reflection/tests/bug39001.phpt b/ext/reflection/tests/bug39001.phpt
new file mode 100644
index 0000000..1ed675f
--- /dev/null
+++ b/ext/reflection/tests/bug39001.phpt
@@ -0,0 +1,27 @@
+--TEST--
+Bug #39001 (ReflectionProperty returns incorrect declaring class for protected properties)
+--FILE--
+<?php
+
+class Meta {
+}
+
+class CParent extends Meta {
+ public $publicVar;
+ protected $protectedVar;
+}
+
+class Child extends CParent {
+}
+
+$r = new ReflectionClass('Child');
+
+var_dump($r->getProperty('publicVar')->getDeclaringClass()->getName());
+var_dump($r->getProperty('protectedVar')->getDeclaringClass()->getName());
+
+echo "Done\n";
+?>
+--EXPECTF--
+string(7) "CParent"
+string(7) "CParent"
+Done
diff --git a/ext/reflection/tests/bug39067.phpt b/ext/reflection/tests/bug39067.phpt
new file mode 100644
index 0000000..8a7a604
--- /dev/null
+++ b/ext/reflection/tests/bug39067.phpt
@@ -0,0 +1,45 @@
+--TEST--
+Bug #39067 (getDeclaringClass() and private properties)
+--FILE--
+<?php
+
+class A {
+ private $x;
+}
+
+class B extends A {
+ private $x;
+}
+
+class C extends B {
+ private $x;
+}
+
+$rc = new ReflectionClass('C');
+var_dump($rc->getProperty('x')->getDeclaringClass()->getName());
+
+$rc = new ReflectionClass('B');
+var_dump($rc->getProperty('x')->getDeclaringClass()->getName());
+
+$rc = new ReflectionClass('A');
+var_dump($rc->getProperty('x')->getDeclaringClass()->getName());
+
+class Test {
+ private $x;
+}
+
+class Test2 extends Test {
+ public $x;
+}
+
+$rc = new ReflectionClass('Test2');
+var_dump($rc->getProperty('x')->getDeclaringClass()->getName());
+
+echo "Done\n";
+?>
+--EXPECTF--
+string(1) "C"
+string(1) "B"
+string(1) "A"
+string(5) "Test2"
+Done
diff --git a/ext/reflection/tests/bug39884.phpt b/ext/reflection/tests/bug39884.phpt
new file mode 100644
index 0000000..dbc57ee
--- /dev/null
+++ b/ext/reflection/tests/bug39884.phpt
@@ -0,0 +1,22 @@
+--TEST--
+Bug #39884 (ReflectionParameter::getClass() throws exception for type hint self)
+--FILE--
+<?php
+class stubParamTest
+{
+ function paramTest(self $param)
+ {
+ // nothing to do
+ }
+}
+$test1 = new stubParamTest();
+$test2 = new stubParamTest();
+$test1->paramTest($test2);
+$refParam = new ReflectionParameter(array('stubParamTest', 'paramTest'), 'param');
+var_dump($refParam->getClass());
+?>
+--EXPECT--
+object(ReflectionClass)#4 (1) {
+ ["name"]=>
+ string(13) "stubParamTest"
+}
diff --git a/ext/reflection/tests/bug40431.phpt b/ext/reflection/tests/bug40431.phpt
new file mode 100644
index 0000000..863df7a
--- /dev/null
+++ b/ext/reflection/tests/bug40431.phpt
@@ -0,0 +1,136 @@
+--TEST--
+Bug #40431 (dynamic properties may cause crash in ReflectionProperty methods)
+--FILE--
+<?php
+
+echo "=== 1st test ===\n";
+$Obj = new stdClass;
+$Obj->value = 'value';
+$RefObj = new ReflectionObject($Obj);
+
+$props = $RefObj->getProperties();
+
+var_dump($props);
+var_dump($props[0]->isStatic());
+var_dump($props[0]->isPrivate());
+var_dump($props[0]->isPublic());
+var_dump($props[0]->isProtected());
+
+echo "=== 2nd test ===\n";
+
+class test1 {
+}
+
+class test2 extends test1{
+}
+
+$Obj = new test2;
+$Obj->value = 'value';
+$RefObj = new ReflectionObject($Obj);
+
+$props = $RefObj->getProperties();
+
+var_dump($props);
+var_dump($props[0]->isStatic());
+var_dump($props[0]->isPrivate());
+var_dump($props[0]->isPublic());
+var_dump($props[0]->isProtected());
+
+echo "=== 3rd test ===\n";
+
+class test3 {
+}
+
+$Obj = new test3;
+$Obj->value = 'value';
+$RefObj = new ReflectionObject($Obj);
+
+$props = $RefObj->getProperties();
+
+var_dump($props);
+var_dump($props[0]->isStatic());
+var_dump($props[0]->isPrivate());
+var_dump($props[0]->isPublic());
+var_dump($props[0]->isProtected());
+
+echo "=== 4th test ===\n";
+
+class test5 {
+ private $value = 1;
+}
+
+class test4 extends test5{
+}
+
+$Obj = new test4;
+$Obj->value = 'value';
+$RefObj = new ReflectionObject($Obj);
+
+$props = $RefObj->getProperties();
+
+var_dump($props);
+var_dump($props[0]->isStatic());
+var_dump($props[0]->isPrivate());
+var_dump($props[0]->isPublic());
+var_dump($props[0]->isProtected());
+
+echo "Done\n";
+?>
+--EXPECTF--
+=== 1st test ===
+array(1) {
+ [0]=>
+ &object(ReflectionProperty)#%d (2) {
+ ["name"]=>
+ string(5) "value"
+ ["class"]=>
+ string(8) "stdClass"
+ }
+}
+bool(false)
+bool(false)
+bool(true)
+bool(false)
+=== 2nd test ===
+array(1) {
+ [0]=>
+ &object(ReflectionProperty)#%d (2) {
+ ["name"]=>
+ string(5) "value"
+ ["class"]=>
+ string(5) "test2"
+ }
+}
+bool(false)
+bool(false)
+bool(true)
+bool(false)
+=== 3rd test ===
+array(1) {
+ [0]=>
+ &object(ReflectionProperty)#%d (2) {
+ ["name"]=>
+ string(5) "value"
+ ["class"]=>
+ string(5) "test3"
+ }
+}
+bool(false)
+bool(false)
+bool(true)
+bool(false)
+=== 4th test ===
+array(1) {
+ [0]=>
+ &object(ReflectionProperty)#%d (2) {
+ ["name"]=>
+ string(5) "value"
+ ["class"]=>
+ string(5) "test4"
+ }
+}
+bool(false)
+bool(false)
+bool(true)
+bool(false)
+Done
diff --git a/ext/reflection/tests/bug40794.phpt b/ext/reflection/tests/bug40794.phpt
new file mode 100644
index 0000000..bb93b91
--- /dev/null
+++ b/ext/reflection/tests/bug40794.phpt
@@ -0,0 +1,32 @@
+--TEST--
+Bug #40794 (ReflectionObject::getValues() may crash when used with dynamic properties)
+--FILE--
+<?php
+
+$obj = new stdClass();
+$obj->prop1 = '1';
+$obj->prop2 = '2';
+$obj->prop3 = '3';
+
+$reflect = new ReflectionObject($obj);
+
+$array = array();
+foreach($reflect->getProperties() as $prop)
+{
+ $array[$prop->getName()] = $prop->getValue($obj);
+}
+
+var_dump($array);
+
+echo "Done\n";
+?>
+--EXPECTF--
+array(3) {
+ ["prop1"]=>
+ string(1) "1"
+ ["prop2"]=>
+ string(1) "2"
+ ["prop3"]=>
+ string(1) "3"
+}
+Done
diff --git a/ext/reflection/tests/bug41061.phpt b/ext/reflection/tests/bug41061.phpt
new file mode 100644
index 0000000..771cd40
--- /dev/null
+++ b/ext/reflection/tests/bug41061.phpt
@@ -0,0 +1,28 @@
+--TEST--
+Reflection Bug #41061 ("visibility error" in ReflectionFunction::export())
+--FILE--
+<?php
+
+function foo() {
+}
+
+class bar {
+ private function foo() {
+ }
+}
+
+Reflection::export(new ReflectionFunction('foo'));
+Reflection::export(new ReflectionMethod('bar', 'foo'));
+?>
+===DONE===
+<?php exit(0); ?>
+--EXPECTF--
+Function [ <user> function foo ] {
+ @@ %sbug41061.php 3 - 4
+}
+
+Method [ <user> private method foo ] {
+ @@ %sbug41061.php 7 - 8
+}
+
+===DONE===
diff --git a/ext/reflection/tests/bug41884.phpt b/ext/reflection/tests/bug41884.phpt
new file mode 100644
index 0000000..f8c0a0a
--- /dev/null
+++ b/ext/reflection/tests/bug41884.phpt
@@ -0,0 +1,25 @@
+--TEST--
+Bug #41884 (ReflectionClass::getDefaultProperties() does not handle static attributes)
+--FILE--
+<?php
+
+class Foo
+{
+ protected static $fooStatic = 'foo';
+ protected $foo = 'foo';
+}
+
+$class = new ReflectionClass('Foo');
+
+var_dump($class->getDefaultProperties());
+
+echo "Done\n";
+?>
+--EXPECTF--
+array(2) {
+ ["fooStatic"]=>
+ string(3) "foo"
+ ["foo"]=>
+ string(3) "foo"
+}
+Done
diff --git a/ext/reflection/tests/bug42976.phpt b/ext/reflection/tests/bug42976.phpt
new file mode 100644
index 0000000..2e4ade2
--- /dev/null
+++ b/ext/reflection/tests/bug42976.phpt
@@ -0,0 +1,38 @@
+--TEST--
+Bug #42976 (Crash when constructor for newInstance() or newInstanceArgs() fails)
+--FILE--
+<?php
+
+Class C {
+ function __construct(&$x) {
+ $x = "x.changed";
+ }
+}
+
+$x = "x.original";
+new C($x); // OK
+var_dump($x);
+
+$rc = new ReflectionClass('C');
+$x = "x.original";
+$rc->newInstance($x); // causes crash
+var_dump($x);
+$x = "x.original";
+$rc->newInstanceArgs(array($x)); // causes crash
+var_dump($x);
+
+echo "Done\n";
+?>
+--EXPECTF--
+string(9) "x.changed"
+
+Warning: Parameter 1 to C::__construct() expected to be a reference, value given in %sbug42976.php on line 15
+
+Warning: ReflectionClass::newInstance(): Invocation of C's constructor failed in %sbug42976.php on line 15
+string(10) "x.original"
+
+Warning: Parameter 1 to C::__construct() expected to be a reference, value given in %sbug42976.php on line 18
+
+Warning: ReflectionClass::newInstanceArgs(): Invocation of C's constructor failed in %sbug42976.php on line 18
+string(10) "x.original"
+Done
diff --git a/ext/reflection/tests/bug43926.phpt b/ext/reflection/tests/bug43926.phpt
new file mode 100644
index 0000000..95bdb9e
--- /dev/null
+++ b/ext/reflection/tests/bug43926.phpt
@@ -0,0 +1,67 @@
+--TEST--
+Bug #43926 (isInstance() isn't equivalent to instanceof operator)
+--FILE--
+<?php
+
+class E {
+}
+class D extends E {
+}
+
+class A extends D {
+}
+
+class C extends A {
+}
+
+$ra = new ReflectionClass('A');
+$rc = new ReflectionClass('C');
+$rd = new ReflectionClass('D');
+$re = new ReflectionClass('E');
+
+$ca = $ra->newInstance();
+$cc = $rc->newInstance();
+$cd = $rd->newInstance();
+$ce = $re->newInstance();
+
+print("Is? A ". ($ra->isInstance($ca) ? 'true' : 'false') .", instanceof: ". (($ca instanceof A) ? 'true' : 'false') ."\n");
+print("Is? C ". ($rc->isInstance($ca) ? 'true' : 'false') .", instanceof: ". (($ca instanceof C) ? 'true' : 'false') ."\n");
+print("Is? D ". ($rd->isInstance($ca) ? 'true' : 'false') .", instanceof: ". (($ca instanceof D) ? 'true' : 'false') ."\n");
+print("Is? E ". ($re->isInstance($ca) ? 'true' : 'false') .", instanceof: ". (($ca instanceof E) ? 'true' : 'false') ."\n");
+print "-\n";
+print("Is? A ". ($ra->isInstance($cc) ? 'true' : 'false') .", instanceof: ". (($cc instanceof A) ? 'true' : 'false') ."\n");
+print("Is? C ". ($rc->isInstance($cc) ? 'true' : 'false') .", instanceof: ". (($cc instanceof C) ? 'true' : 'false') ."\n");
+print("Is? D ". ($rd->isInstance($cc) ? 'true' : 'false') .", instanceof: ". (($cc instanceof D) ? 'true' : 'false') ."\n");
+print("Is? E ". ($re->isInstance($cc) ? 'true' : 'false') .", instanceof: ". (($cc instanceof E) ? 'true' : 'false') ."\n");
+print "-\n";
+print("Is? A ". ($ra->isInstance($cd) ? 'true' : 'false') .", instanceof: ". (($cd instanceof A) ? 'true' : 'false') ."\n");
+print("Is? C ". ($rc->isInstance($cd) ? 'true' : 'false') .", instanceof: ". (($cd instanceof C) ? 'true' : 'false') ."\n");
+print("Is? D ". ($rd->isInstance($cd) ? 'true' : 'false') .", instanceof: ". (($cd instanceof D) ? 'true' : 'false') ."\n");
+print("Is? E ". ($re->isInstance($cd) ? 'true' : 'false') .", instanceof: ". (($cd instanceof E) ? 'true' : 'false') ."\n");
+print "-\n";
+print("Is? A ". ($ra->isInstance($ce) ? 'true' : 'false') .", instanceof: ". (($ce instanceof A) ? 'true' : 'false') ."\n");
+print("Is? C ". ($rc->isInstance($ce) ? 'true' : 'false') .", instanceof: ". (($ce instanceof C) ? 'true' : 'false') ."\n");
+print("Is? D ". ($rd->isInstance($ce) ? 'true' : 'false') .", instanceof: ". (($ce instanceof D) ? 'true' : 'false') ."\n");
+print("Is? E ". ($re->isInstance($ce) ? 'true' : 'false') .", instanceof: ". (($ce instanceof E) ? 'true' : 'false') ."\n");
+
+?>
+--EXPECT--
+Is? A true, instanceof: true
+Is? C false, instanceof: false
+Is? D true, instanceof: true
+Is? E true, instanceof: true
+-
+Is? A true, instanceof: true
+Is? C true, instanceof: true
+Is? D true, instanceof: true
+Is? E true, instanceof: true
+-
+Is? A false, instanceof: false
+Is? C false, instanceof: false
+Is? D true, instanceof: true
+Is? E true, instanceof: true
+-
+Is? A false, instanceof: false
+Is? C false, instanceof: false
+Is? D false, instanceof: false
+Is? E true, instanceof: true
diff --git a/ext/reflection/tests/bug45139.phpt b/ext/reflection/tests/bug45139.phpt
new file mode 100644
index 0000000..6aa8426
--- /dev/null
+++ b/ext/reflection/tests/bug45139.phpt
@@ -0,0 +1,58 @@
+--TEST--
+Bug #45139 (ReflectionProperty returns incorrect declaring class)
+--FILE--
+<?php
+
+class A {
+ private $foo;
+}
+
+class B extends A {
+ protected $bar;
+ private $baz;
+ private $quux;
+}
+
+class C extends B {
+ public $foo;
+ private $baz;
+ protected $quux;
+}
+
+$rc = new ReflectionClass('C');
+$rp = $rc->getProperty('foo');
+var_dump($rp->getDeclaringClass()->getName()); // c
+
+$rc = new ReflectionClass('A');
+$rp = $rc->getProperty('foo');
+var_dump($rp->getDeclaringClass()->getName()); // A
+
+$rc = new ReflectionClass('B');
+$rp = $rc->getProperty('bar');
+var_dump($rp->getDeclaringClass()->getName()); // B
+
+$rc = new ReflectionClass('C');
+$rp = $rc->getProperty('bar');
+var_dump($rp->getDeclaringClass()->getName()); // B
+
+$rc = new ReflectionClass('C');
+$rp = $rc->getProperty('baz');
+var_dump($rp->getDeclaringClass()->getName()); // C
+
+$rc = new ReflectionClass('B');
+$rp = $rc->getProperty('baz');
+var_dump($rp->getDeclaringClass()->getName()); // B
+
+$rc = new ReflectionClass('C');
+$rp = $rc->getProperty('quux');
+var_dump($rp->getDeclaringClass()->getName()); // C
+
+?>
+--EXPECT--
+string(1) "C"
+string(1) "A"
+string(1) "B"
+string(1) "B"
+string(1) "C"
+string(1) "B"
+string(1) "C"
diff --git a/ext/reflection/tests/bug45571.phpt b/ext/reflection/tests/bug45571.phpt
new file mode 100644
index 0000000..4df542e
--- /dev/null
+++ b/ext/reflection/tests/bug45571.phpt
@@ -0,0 +1,40 @@
+--TEST--
+Bug #45571 (ReflectionClass::export() shows superclasses' private static methods.)
+--FILE--
+<?php
+
+Class A {
+ static private $a = 0;
+ static protected $b = 1;
+ static public $c = 2;
+
+ private function f() {}
+ private static function sf() {}
+}
+
+Class C extends A { }
+
+ReflectionClass::export("C");
+
+?>
+--EXPECTF--
+Class [ <user> class C extends A ] {
+ @@ %s 12-12
+
+ - Constants [0] {
+ }
+
+ - Static properties [2] {
+ Property [ protected static $b ]
+ Property [ public static $c ]
+ }
+
+ - Static methods [0] {
+ }
+
+ - Properties [0] {
+ }
+
+ - Methods [0] {
+ }
+}
diff --git a/ext/reflection/tests/bug45765.phpt b/ext/reflection/tests/bug45765.phpt
new file mode 100644
index 0000000..b0c1be2
--- /dev/null
+++ b/ext/reflection/tests/bug45765.phpt
@@ -0,0 +1,82 @@
+--TEST--
+Fixed bug #45765 (ReflectionObject with default parameters of self::xxx cause an error)
+--FILE--
+<?php
+
+class foo2 {
+ const BAR = 'foobar';
+}
+
+class foo extends foo2 {
+ const BAR = "foo's bar";
+
+ function test($a = self::BAR) {
+ }
+
+ function test2($a = parent::BAR) {
+ }
+
+ function test3($a = foo::BAR) {
+ }
+
+ function test4($a = foo2::BAR) {
+ }
+}
+
+ReflectionObject::export(new foo);
+
+?>
+--EXPECTF--
+Object of class [ <user> class foo extends foo2 ] {
+ @@ %s 7-21
+
+ - Constants [1] {
+ Constant [ string BAR ] { foo's bar }
+ }
+
+ - Static properties [0] {
+ }
+
+ - Static methods [0] {
+ }
+
+ - Properties [0] {
+ }
+
+ - Dynamic properties [0] {
+ }
+
+ - Methods [4] {
+ Method [ <user> public method test ] {
+ @@ %s 10 - 11
+
+ - Parameters [1] {
+ Parameter #0 [ <optional> $a = 'foo's bar' ]
+ }
+ }
+
+ Method [ <user> public method test2 ] {
+ @@ %s 13 - 14
+
+ - Parameters [1] {
+ Parameter #0 [ <optional> $a = 'foobar' ]
+ }
+ }
+
+ Method [ <user> public method test3 ] {
+ @@ %s 16 - 17
+
+ - Parameters [1] {
+ Parameter #0 [ <optional> $a = 'foo's bar' ]
+ }
+ }
+
+ Method [ <user> public method test4 ] {
+ @@ %s 19 - 20
+
+ - Parameters [1] {
+ Parameter #0 [ <optional> $a = 'foobar' ]
+ }
+ }
+ }
+}
diff --git a/ext/reflection/tests/bug46064.phpt b/ext/reflection/tests/bug46064.phpt
new file mode 100644
index 0000000..510e71b
--- /dev/null
+++ b/ext/reflection/tests/bug46064.phpt
@@ -0,0 +1,76 @@
+--TEST--
+Bug #46064 (Exception when creating ReflectionProperty object on dynamicly created property)
+--FILE--
+<?php
+
+class x {
+ public $zzz = 2;
+}
+
+$o = new x;
+$o->z = 1000;
+$o->zzz = 3;
+
+var_dump($h = new reflectionproperty($o, 'z'));
+var_dump($h->isDefault());
+var_dump($h->isPublic());
+var_dump($h->isStatic());
+var_dump($h->getName());
+var_dump(Reflection::getModifierNames($h->getModifiers()));
+var_dump($h->getValue($o));
+
+print "---------------------------\n";
+try {
+ var_dump(new reflectionproperty($o, 'zz'));
+} catch (Exception $e) {
+ var_dump($e->getMessage());
+}
+
+var_dump(new reflectionproperty($o, 'zzz'));
+
+class test {
+ protected $a = 1;
+}
+
+class bar extends test {
+ public function __construct() {
+ $this->foobar = 2;
+ $this->a = 200;
+
+ $p = new reflectionproperty($this, 'foobar');
+ var_dump($p->getValue($this), $p->isDefault(), $p->isPublic());
+ }
+}
+
+new bar;
+
+?>
+===DONE===
+--EXPECTF--
+object(ReflectionProperty)#%d (2) {
+ ["name"]=>
+ string(1) "z"
+ ["class"]=>
+ string(1) "x"
+}
+bool(false)
+bool(true)
+bool(false)
+string(1) "z"
+array(1) {
+ [0]=>
+ string(6) "public"
+}
+int(1000)
+---------------------------
+string(30) "Property x::$zz does not exist"
+object(ReflectionProperty)#%d (2) {
+ ["name"]=>
+ string(3) "zzz"
+ ["class"]=>
+ string(1) "x"
+}
+int(2)
+bool(false)
+bool(true)
+===DONE===
diff --git a/ext/reflection/tests/bug46064_2.phpt b/ext/reflection/tests/bug46064_2.phpt
new file mode 100644
index 0000000..da14148
--- /dev/null
+++ b/ext/reflection/tests/bug46064_2.phpt
@@ -0,0 +1,74 @@
+--TEST--
+Bug #46064.2 (Exception when creating ReflectionProperty object on dynamicly created property)
+--FILE--
+<?php
+
+class foo {
+}
+
+$x = new foo;
+$x->test = 2000;
+
+
+$p = new ReflectionObject($x);
+var_dump($p->getProperty('test'));
+
+
+class bar {
+ public function __construct() {
+ $this->a = 1;
+ }
+}
+
+class test extends bar {
+ private $b = 2;
+
+ public function __construct() {
+ parent::__construct();
+
+ $p = new reflectionobject($this);
+ var_dump($h = $p->getProperty('a'));
+ var_dump($h->isDefault(), $h->isProtected(), $h->isPrivate(), $h->isPublic(), $h->isStatic());
+ var_dump($p->getProperties());
+ }
+}
+
+new test;
+
+?>
+===DONE===
+--EXPECTF--
+object(ReflectionProperty)#%d (2) {
+ ["name"]=>
+ string(4) "test"
+ ["class"]=>
+ string(3) "foo"
+}
+object(ReflectionProperty)#%d (2) {
+ ["name"]=>
+ string(1) "a"
+ ["class"]=>
+ string(4) "test"
+}
+bool(false)
+bool(false)
+bool(false)
+bool(true)
+bool(false)
+array(2) {
+ [0]=>
+ &object(ReflectionProperty)#%d (2) {
+ ["name"]=>
+ string(1) "b"
+ ["class"]=>
+ string(4) "test"
+ }
+ [1]=>
+ &object(ReflectionProperty)#%d (2) {
+ ["name"]=>
+ string(1) "a"
+ ["class"]=>
+ string(4) "test"
+ }
+}
+===DONE=== \ No newline at end of file
diff --git a/ext/reflection/tests/bug46205.phpt b/ext/reflection/tests/bug46205.phpt
new file mode 100644
index 0000000..ef7a692
--- /dev/null
+++ b/ext/reflection/tests/bug46205.phpt
@@ -0,0 +1,14 @@
+--TEST--
+Bug #46205 (Closure - Memory leaks when ReflectionException is thrown)
+--FILE--
+<?php
+$x = new reflectionmethod('reflectionparameter', 'export');
+$y = function() { };
+
+try {
+ $x->invokeArgs(new reflectionparameter('trim', 'str'), array($y, 1));
+} catch (Exception $e) { }
+?>
+ok
+--EXPECT--
+ok
diff --git a/ext/reflection/tests/bug47254.phpt b/ext/reflection/tests/bug47254.phpt
new file mode 100644
index 0000000..83593a4
--- /dev/null
+++ b/ext/reflection/tests/bug47254.phpt
@@ -0,0 +1,41 @@
+--TEST--
+Bug #47254
+--CREDITS--
+Sebastian Schürmann
+sebs@php.net
+Testfest 2009 Munich
+--FILE--
+<?php
+class A
+{
+ protected function a() {}
+
+}
+
+class B extends A
+{
+ public function b() {}
+}
+
+$B = new B();
+$R = new ReflectionObject($B);
+$m = $R->getMethods();
+print_r($m);
+
+?>
+--EXPECT--
+Array
+(
+ [0] => ReflectionMethod Object
+ (
+ [name] => b
+ [class] => B
+ )
+
+ [1] => ReflectionMethod Object
+ (
+ [name] => a
+ [class] => A
+ )
+
+)
diff --git a/ext/reflection/tests/bug48336.phpt b/ext/reflection/tests/bug48336.phpt
new file mode 100644
index 0000000..ee90675
--- /dev/null
+++ b/ext/reflection/tests/bug48336.phpt
@@ -0,0 +1,44 @@
+--TEST--
+Bug #48286 (ReflectionProperty::getDeclaringClass() does not work with redeclared properties)
+--FILE--
+<?php
+class A {
+}
+
+class B extends A {
+ static protected $prop;
+}
+
+class C extends B {
+ static protected $prop;
+}
+
+class D extends C {
+}
+
+class E extends D {
+}
+
+class F extends E {
+ static protected $prop;
+}
+
+$class = 'A';
+for($class = 'A'; $class <= 'F'; $class ++) {
+ print($class.' => ');
+ try {
+ $rp = new ReflectionProperty($class, 'prop');
+ print($rp->getDeclaringClass()->getName());
+ } catch(Exception $e) {
+ print('N/A');
+ }
+ print("\n");
+}
+?>
+--EXPECT--
+A => N/A
+B => B
+C => C
+D => C
+E => C
+F => F
diff --git a/ext/reflection/tests/bug48757.phpt b/ext/reflection/tests/bug48757.phpt
new file mode 100644
index 0000000..a5ced91
--- /dev/null
+++ b/ext/reflection/tests/bug48757.phpt
@@ -0,0 +1,21 @@
+--TEST--
+Bug #48757 (ReflectionFunction::invoke() parameter issues)
+--FILE--
+<?php
+function test() {
+ echo "Hello World\n";
+}
+
+function another_test($parameter) {
+ var_dump($parameter);
+}
+
+$func = new ReflectionFunction('test');
+$func->invoke();
+
+$func = new ReflectionFunction('another_test');
+$func->invoke('testing');
+?>
+--EXPECT--
+Hello World
+string(7) "testing"
diff --git a/ext/reflection/tests/bug49074.phpt b/ext/reflection/tests/bug49074.phpt
new file mode 100644
index 0000000..7ce23b4
--- /dev/null
+++ b/ext/reflection/tests/bug49074.phpt
@@ -0,0 +1,31 @@
+--TEST--
+Bug #49074 (private class static fields can be modified by using reflection)
+--FILE--
+<?php
+class Test {
+ private static $data1 = 1;
+ private static $data4 = 4;
+}
+
+class Test2 extends Test {
+ private static $data2 = 2;
+ public static $data3 = 3;
+}
+
+$r = new ReflectionClass('Test2');
+$m = $r->getStaticProperties();
+
+$m['data1'] = 100;
+$m['data2'] = 200;
+$m['data3'] = 300;
+$m['data4'] = 400;
+
+var_dump($r->getStaticProperties());
+?>
+--EXPECT--
+array(2) {
+ ["data2"]=>
+ int(2)
+ ["data3"]=>
+ int(3)
+}
diff --git a/ext/reflection/tests/bug49092.phpt b/ext/reflection/tests/bug49092.phpt
new file mode 100644
index 0000000..460a131
--- /dev/null
+++ b/ext/reflection/tests/bug49092.phpt
@@ -0,0 +1,12 @@
+--TEST--
+Bug #49092 (ReflectionFunction fails to work with functions in fully qualified namespaces)
+--FILE--
+<?php
+namespace ns;
+function func(){}
+new \ReflectionFunction('ns\func');
+new \ReflectionFunction('\ns\func');
+echo "Ok\n"
+?>
+--EXPECT--
+Ok
diff --git a/ext/reflection/tests/bug49719.phpt b/ext/reflection/tests/bug49719.phpt
new file mode 100644
index 0000000..215140a
--- /dev/null
+++ b/ext/reflection/tests/bug49719.phpt
@@ -0,0 +1,44 @@
+--TEST--
+Bug #49719 (ReflectionClass::hasProperty returns true for a private property in base class)
+--FILE--
+<?php
+
+class A {
+ private $a;
+}
+class B extends A {
+ private $b;
+}
+
+try {
+ $b = new B;
+ $ref = new ReflectionClass($b);
+
+ var_dump(property_exists('b', 'a'));
+ var_dump(property_exists($b, 'a'));
+ var_dump($ref->hasProperty('a'));
+ var_dump($ref->getProperty('a'));
+} catch (Exception $e) {
+ var_dump($e->getMessage());
+}
+
+class A2 {
+ private $a = 1;
+}
+
+class B2 extends A2 {
+ private $a = 2;
+}
+
+$b2 = new ReflectionClass('B2');
+$prop = $b2->getProperty('a');
+$prop->setAccessible(true);
+var_dump($prop->getValue(new b2));
+
+?>
+--EXPECTF--
+bool(false)
+bool(false)
+bool(false)
+%string|unicode%(25) "Property a does not exist"
+int(2)
diff --git a/ext/reflection/tests/bug51905.phpt b/ext/reflection/tests/bug51905.phpt
new file mode 100644
index 0000000..8969924
--- /dev/null
+++ b/ext/reflection/tests/bug51905.phpt
@@ -0,0 +1,28 @@
+--TEST--
+Bug #51905 (ReflectionParameter fails if default value is an array with an access to self::)
+--FILE--
+<?php
+
+class Bar {
+ const Y = 20;
+}
+
+class Foo extends Bar {
+ const X = 12;
+ public function x($x = 1, $y = array(self::X), $z = parent::Y) {}
+}
+
+$clazz = new ReflectionClass('Foo');
+$method = $clazz->getMethod('x');
+foreach ($method->getParameters() as $param) {
+ if ( $param->isDefaultValueAvailable())
+ echo '$', $param->getName(), ' : ', var_export($param->getDefaultValue(), 1), "\n";
+}
+
+?>
+--EXPECT--
+$x : 1
+$y : array (
+ 0 => 12,
+)
+$z : 20
diff --git a/ext/reflection/tests/bug51911.phpt b/ext/reflection/tests/bug51911.phpt
new file mode 100644
index 0000000..12eb459
--- /dev/null
+++ b/ext/reflection/tests/bug51911.phpt
@@ -0,0 +1,22 @@
+--TEST--
+Bug #51911 (ReflectionParameter::getDefaultValue() memory leaks with constant array)
+--FILE--
+<?php
+
+class Foo {
+ const X = 1;
+ public function x($x = array(1)) {}
+}
+
+$clazz = new ReflectionClass('Foo');
+$method = $clazz->getMethod('x');
+foreach ($method->getParameters() as $param) {
+ if ( $param->isDefaultValueAvailable())
+ echo '$', $param->getName(), ' : ', var_export($param->getDefaultValue(), 1), "\n";
+}
+
+?>
+--EXPECT--
+$x : array (
+ 0 => 1,
+)
diff --git a/ext/reflection/tests/bug52057.phpt b/ext/reflection/tests/bug52057.phpt
new file mode 100644
index 0000000..b807035
--- /dev/null
+++ b/ext/reflection/tests/bug52057.phpt
@@ -0,0 +1,54 @@
+--TEST--
+Bug #52057 (ReflectionClass fails on Closure class)
+--FILE--
+<?php
+
+$closure = function($a) { echo $a; };
+
+$reflection = new ReflectionClass('closure');
+var_dump($reflection->hasMethod('__invoke')); // true
+
+$reflection = new ReflectionClass($closure);
+var_dump($reflection->hasMethod('__invoke')); // true
+
+$reflection = new ReflectionObject($closure);
+var_dump($reflection->hasMethod('__invoke')); // true
+
+$reflection = new ReflectionClass('closure');
+var_dump($h = $reflection->getMethod('__invoke')); // true
+var_dump($h->class.'::'.$h->getName());
+
+$reflection = new ReflectionClass($closure);
+var_dump($h = $reflection->getMethod('__invoke')); // true
+var_dump($h->class.'::'.$h->getName());
+
+$reflection = new ReflectionObject($closure);
+var_dump($h = $reflection->getMethod('__invoke')); // true
+var_dump($h->class.'::'.$h->getName());
+
+?>
+--EXPECTF--
+bool(true)
+bool(true)
+bool(true)
+object(ReflectionMethod)#%d (2) {
+ ["name"]=>
+ string(8) "__invoke"
+ ["class"]=>
+ string(7) "Closure"
+}
+string(17) "Closure::__invoke"
+object(ReflectionMethod)#%d (2) {
+ ["name"]=>
+ string(8) "__invoke"
+ ["class"]=>
+ string(7) "Closure"
+}
+string(17) "Closure::__invoke"
+object(ReflectionMethod)#%d (2) {
+ ["name"]=>
+ string(8) "__invoke"
+ ["class"]=>
+ string(7) "Closure"
+}
+string(17) "Closure::__invoke"
diff --git a/ext/reflection/tests/bug52854.phpt b/ext/reflection/tests/bug52854.phpt
new file mode 100644
index 0000000..255522d
--- /dev/null
+++ b/ext/reflection/tests/bug52854.phpt
@@ -0,0 +1,28 @@
+--TEST--
+Bug #52854: ReflectionClass::newInstanceArgs does not work for classes without constructors
+--FILE--
+<?php
+class Test {
+}
+$c = new ReflectionClass('Test');
+var_dump(new Test);
+var_dump(new Test());
+var_dump($c->newInstance());
+var_dump($c->newInstanceArgs(array()));
+
+try {
+ var_dump($c->newInstanceArgs(array(1)));
+} catch(ReflectionException $e) {
+ echo $e->getMessage()."\n";
+}
+?>
+--EXPECTF--
+object(Test)#%d (0) {
+}
+object(Test)#%d (0) {
+}
+object(Test)#%d (0) {
+}
+object(Test)#%d (0) {
+}
+Class Test does not have a constructor, so you cannot pass any constructor arguments
diff --git a/ext/reflection/tests/bug53366.phpt b/ext/reflection/tests/bug53366.phpt
new file mode 100644
index 0000000..5fb119d
--- /dev/null
+++ b/ext/reflection/tests/bug53366.phpt
@@ -0,0 +1,25 @@
+--TEST--
+Bug #53366 (Reflection doesnt get dynamic property value from getProperty())
+--FILE--
+<?php
+
+class UserClass {
+}
+
+$myClass = new UserClass;
+$myClass->id = 1000;
+
+$reflect = new ReflectionObject($myClass);
+
+var_dump($reflect->getProperty('id'));
+var_dump($reflect->getProperty('id')->getValue($myClass));
+
+?>
+--EXPECTF--
+object(ReflectionProperty)#%d (2) {
+ ["name"]=>
+ string(2) "id"
+ ["class"]=>
+ string(9) "UserClass"
+}
+int(1000)
diff --git a/ext/reflection/tests/bug53915.phpt b/ext/reflection/tests/bug53915.phpt
new file mode 100644
index 0000000..f2f2ae5
--- /dev/null
+++ b/ext/reflection/tests/bug53915.phpt
@@ -0,0 +1,28 @@
+--TEST--
+Bug #53915 - ReflectionClass::getConstant(s) emits fatal error on selfreferencing constants
+--FILE--
+<?php
+Class Foo
+{
+ const A = 1;
+ const B = self::A;
+}
+
+$rc = new ReflectionClass('Foo');
+print_r($rc->getConstants());
+
+Class Foo2
+{
+ const A = 1;
+ const B = self::A;
+}
+
+$rc = new ReflectionClass('Foo2');
+print_r($rc->getConstant('B'));
+--EXPECT--
+Array
+(
+ [A] => 1
+ [B] => 1
+)
+1
diff --git a/ext/reflection/tests/bug60357.phpt b/ext/reflection/tests/bug60357.phpt
new file mode 100644
index 0000000..a5ddd40
--- /dev/null
+++ b/ext/reflection/tests/bug60357.phpt
@@ -0,0 +1,10 @@
+--TEST--
+Bug #60357 (__toString() method triggers E_NOTICE "Array to string conversion")
+--FILE--
+<?php
+function foo( array $x = array( 'a', 'b' ) ) {}
+$r = new ReflectionParameter( 'foo', 0 );
+echo $r->__toString();
+?>
+--EXPECTF--
+Parameter #0 [ <optional> array $x = Array ]
diff --git a/ext/reflection/tests/bug60367.phpt b/ext/reflection/tests/bug60367.phpt
new file mode 100644
index 0000000..5c4a098
--- /dev/null
+++ b/ext/reflection/tests/bug60367.phpt
@@ -0,0 +1,28 @@
+--TEST--
+Bug #60367 (Reflection and Late Static Binding)
+--FILE--
+<?php
+abstract class A {
+
+ const WHAT = 'A';
+
+ public static function call() {
+ echo static::WHAT;
+ }
+
+}
+
+class B extends A {
+
+ const WHAT = 'B';
+
+}
+
+$method = new ReflectionMethod("b::call");
+$method->invoke(null);
+$method->invokeArgs(null, array());
+$method = new ReflectionMethod("A::call");
+$method->invoke(null);
+$method->invokeArgs(null, array());
+--EXPECTF--
+BBAA
diff --git a/ext/reflection/tests/bug61388.phpt b/ext/reflection/tests/bug61388.phpt
new file mode 100644
index 0000000..75c0300
--- /dev/null
+++ b/ext/reflection/tests/bug61388.phpt
@@ -0,0 +1,32 @@
+--TEST--
+ReflectionObject:getProperties() issues invalid reads when it get_properties returns a hash table with (inaccessible) dynamic numeric properties
+--FILE--
+<?php
+$x = new ArrayObject();
+$x[0] = 'test string 2';
+$x['test'] = 'test string 3';
+$reflObj = new ReflectionObject($x);
+print_r($reflObj->getProperties(ReflectionProperty::IS_PUBLIC));
+
+$x = (object)array("a", "oo" => "b");
+$reflObj = new ReflectionObject($x);
+print_r($reflObj->getProperties(ReflectionProperty::IS_PUBLIC));
+--EXPECT--
+Array
+(
+ [0] => ReflectionProperty Object
+ (
+ [name] => test
+ [class] => ArrayObject
+ )
+
+)
+Array
+(
+ [0] => ReflectionProperty Object
+ (
+ [name] => oo
+ [class] => stdClass
+ )
+
+)
diff --git a/ext/reflection/tests/bug62384.phpt b/ext/reflection/tests/bug62384.phpt
new file mode 100644
index 0000000..90a871f
--- /dev/null
+++ b/ext/reflection/tests/bug62384.phpt
@@ -0,0 +1,21 @@
+--TEST--
+Bug #62384 (Attempting to invoke a Closure more than once causes segfaul)
+--FILE--
+<?php
+
+$closure1 = function($val){ return $val; };
+$closure2 = function($val){ return $val; };
+
+$reflection_class = new ReflectionClass($closure1);
+$reflection_method = $reflection_class->getMethod('__invoke');
+
+$arguments1 = array('hello');
+$arguments2 = array('world');
+
+var_dump($reflection_method->invokeArgs($closure1, $arguments1));
+var_dump($reflection_method->invokeArgs($closure2, $arguments2));
+
+?>
+--EXPECT--
+string(5) "hello"
+string(5) "world"
diff --git a/ext/reflection/tests/bug62715.phpt b/ext/reflection/tests/bug62715.phpt
new file mode 100644
index 0000000..feb67f6
--- /dev/null
+++ b/ext/reflection/tests/bug62715.phpt
@@ -0,0 +1,24 @@
+--TEST--
+Bug #62715 (ReflectionParameter::isDefaultValueAvailable() wrong result)
+--FILE--
+<?php
+
+function test(PDO $a = null, $b = 0, array $c) {}
+$r = new ReflectionFunction('test');
+
+foreach ($r->getParameters() as $p) {
+ var_dump($p->isDefaultValueAvailable());
+}
+
+foreach ($r->getParameters() as $p) {
+ if ($p->isDefaultValueAvailable()) {
+ var_dump($p->getDefaultValue());
+ }
+}
+?>
+--EXPECT--
+bool(true)
+bool(true)
+bool(false)
+NULL
+int(0)
diff --git a/ext/reflection/tests/bug63399.phpt b/ext/reflection/tests/bug63399.phpt
new file mode 100644
index 0000000..393b861
--- /dev/null
+++ b/ext/reflection/tests/bug63399.phpt
@@ -0,0 +1,49 @@
+--TEST--
+Bug #63399 (ReflectionClass::getTraitAliases() incorrectly resolves traitnames)
+--FILE--
+<?php
+trait Trait1 {
+ public function run() {}
+ public function say() {}
+}
+
+trait Trait2 {
+ public function run() {}
+ public function say() {}
+}
+
+class MyClass
+{
+ use Trait1, Trait2 {
+ Trait1::run as execute;
+ Trait1::say insteadof Trait2;
+ Trait2::run insteadof Trait1;
+ Trait2::say as talk;
+ }
+}
+
+$ref = new ReflectionClass('MyClass');
+
+print_r($ref->getTraitAliases());
+print_r($ref->getTraits());
+
+?>
+--EXPECT--
+Array
+(
+ [execute] => Trait1::run
+ [talk] => Trait2::say
+)
+Array
+(
+ [Trait1] => ReflectionClass Object
+ (
+ [name] => Trait1
+ )
+
+ [Trait2] => ReflectionClass Object
+ (
+ [name] => Trait2
+ )
+
+)
diff --git a/ext/reflection/tests/bug63614.phpt b/ext/reflection/tests/bug63614.phpt
new file mode 100644
index 0000000..c13ff4b
--- /dev/null
+++ b/ext/reflection/tests/bug63614.phpt
@@ -0,0 +1,41 @@
+--TEST--
+Bug #63614 (Fatal error on Reflection)
+--FILE--
+<?php
+function dummy() {
+ static $a = array();
+}
+
+class Test
+{
+ const A = 0;
+
+ public function func()
+ {
+ static $a = array(
+ self::A => 'a'
+ );
+ }
+}
+
+$reflect = new ReflectionFunction("dummy");
+print_r($reflect->getStaticVariables());
+$reflect = new ReflectionMethod('Test', 'func');
+print_r($reflect->getStaticVariables());
+?>
+--EXPECT--
+Array
+(
+ [a] => Array
+ (
+ )
+
+)
+Array
+(
+ [a] => Array
+ (
+ [0] => a
+ )
+
+)
diff --git a/ext/reflection/tests/closures_001.phpt b/ext/reflection/tests/closures_001.phpt
new file mode 100644
index 0000000..6cc7e67
--- /dev/null
+++ b/ext/reflection/tests/closures_001.phpt
@@ -0,0 +1,70 @@
+--TEST--
+Reflection on closures
+--FILE--
+<?php
+
+$closure = function($a, $b = 0) { };
+
+$ro = new ReflectionObject($closure);
+$rm = $ro->getMethod('__invoke');
+var_dump($rm->getNumberOfParameters());
+var_dump($rm->getNumberOfRequiredParameters());
+$rms = $ro->getMethods();
+foreach($rms as $rm) {
+ if ($rm->getName() == '__invoke') {
+ var_dump($rm->getNumberOfParameters());
+ var_dump($rm->getNumberOfRequiredParameters());
+ }
+}
+
+echo "---\n";
+
+$rm = new ReflectionMethod($closure, '__invoke');
+var_dump($rm->getName());
+var_dump($rm->getNumberOfParameters());
+var_dump($rm->getNumberOfRequiredParameters());
+
+echo "---\n";
+
+$rp = new ReflectionParameter(array($closure, '__invoke'), 0);
+var_dump($rp->isOptional());
+$rp = new ReflectionParameter(array($closure, '__invoke'), 1);
+var_dump($rp->isOptional());
+$rp = new ReflectionParameter(array($closure, '__invoke'), 'a');
+var_dump($rp->isOptional());
+$rp = new ReflectionParameter(array($closure, '__invoke'), 'b');
+var_dump($rp->isOptional());
+
+echo "---\n";
+
+$rp = new ReflectionParameter($closure, 0);
+var_dump($rp->isOptional());
+$rp = new ReflectionParameter($closure, 1);
+var_dump($rp->isOptional());
+$rp = new ReflectionParameter($closure, 'a');
+var_dump($rp->isOptional());
+$rp = new ReflectionParameter($closure, 'b');
+var_dump($rp->isOptional());
+
+?>
+===DONE===
+--EXPECTF--
+int(2)
+int(1)
+int(2)
+int(1)
+---
+string(8) "__invoke"
+int(2)
+int(1)
+---
+bool(false)
+bool(true)
+bool(false)
+bool(true)
+---
+bool(false)
+bool(true)
+bool(false)
+bool(true)
+===DONE===
diff --git a/ext/reflection/tests/closures_002.phpt b/ext/reflection/tests/closures_002.phpt
new file mode 100644
index 0000000..e8b080f
--- /dev/null
+++ b/ext/reflection/tests/closures_002.phpt
@@ -0,0 +1,29 @@
+--TEST--
+Reflection on invokable objects
+--FILE--
+<?php
+
+class Test {
+ function __invoke($a, $b = 0) { }
+}
+
+$rm = new ReflectionMethod(new Test, '__invoke');
+var_dump($rm->getName());
+var_dump($rm->getNumberOfParameters());
+var_dump($rm->getNumberOfRequiredParameters());
+
+$rp = new ReflectionParameter(array(new Test, '__invoke'), 0);
+var_dump($rp->isOptional());
+
+$rp = new ReflectionParameter(array(new Test, '__invoke'), 1);
+var_dump($rp->isOptional());
+
+?>
+===DONE===
+--EXPECTF--
+string(8) "__invoke"
+int(2)
+int(1)
+bool(false)
+bool(true)
+===DONE===
diff --git a/ext/reflection/tests/closures_003.phpt b/ext/reflection/tests/closures_003.phpt
new file mode 100644
index 0000000..4483dc0
--- /dev/null
+++ b/ext/reflection/tests/closures_003.phpt
@@ -0,0 +1,25 @@
+--TEST--
+Reflection on closures: Segfaults with getParameters() and getDeclaringFunction()
+--FILE--
+<?php
+
+$closure = function($a, $b = 0) { };
+
+$method = new ReflectionMethod ($closure, '__invoke');
+$params = $method->getParameters ();
+unset ($method);
+$method = $params[0]->getDeclaringFunction ();
+unset ($params);
+echo $method->getName ()."\n";
+
+$parameter = new ReflectionParameter (array ($closure, '__invoke'), 'b');
+$method = $parameter->getDeclaringFunction ();
+unset ($parameter);
+echo $method->getName ()."\n";
+
+?>
+===DONE===
+--EXPECTF--
+__invoke
+__invoke
+===DONE===
diff --git a/ext/reflection/tests/closures_003_v1.phpt b/ext/reflection/tests/closures_003_v1.phpt
new file mode 100644
index 0000000..1b8e1c4
--- /dev/null
+++ b/ext/reflection/tests/closures_003_v1.phpt
@@ -0,0 +1,25 @@
+--TEST--
+Reflection on closures: Segfaults with getParameters() and getDeclaringFunction()
+--FILE--
+<?php
+
+$closure = function($a, $b = 0) { };
+
+$method = new ReflectionFunction ($closure);
+$params = $method->getParameters ();
+unset ($method);
+$method = $params[0]->getDeclaringFunction ();
+unset ($params);
+echo $method->getName ()."\n";
+
+$parameter = new ReflectionParameter ($closure, 'b');
+$method = $parameter->getDeclaringFunction ();
+unset ($parameter);
+echo $method->getName ()."\n";
+
+?>
+===DONE===
+--EXPECTF--
+{closure}
+{closure}
+===DONE===
diff --git a/ext/reflection/tests/closures_004.phpt b/ext/reflection/tests/closures_004.phpt
new file mode 100644
index 0000000..807aea1
--- /dev/null
+++ b/ext/reflection/tests/closures_004.phpt
@@ -0,0 +1,43 @@
+--TEST--
+Reflection on closures: Segfault with getClosure() on closure itself
+--FILE--
+<?php
+$closure = function() { echo "Invoked!\n"; };
+
+$method = new ReflectionFunction ($closure);
+
+$closure2 = $method->getClosure ();
+
+$closure2 ();
+$closure2->__invoke ();
+
+unset ($closure);
+
+$closure2 ();
+$closure2->__invoke ();
+
+$closure = function() { echo "Invoked!\n"; };
+
+$method = new ReflectionMethod ($closure, '__invoke');
+$closure2 = $method->getClosure ($closure);
+
+$closure2 ();
+$closure2->__invoke ();
+
+unset ($closure);
+
+$closure2 ();
+$closure2->__invoke ();
+
+?>
+===DONE===
+--EXPECTF--
+Invoked!
+Invoked!
+Invoked!
+Invoked!
+Invoked!
+Invoked!
+Invoked!
+Invoked!
+===DONE===
diff --git a/ext/reflection/tests/exception.inc b/ext/reflection/tests/exception.inc
new file mode 100644
index 0000000..e403339
--- /dev/null
+++ b/ext/reflection/tests/exception.inc
@@ -0,0 +1,16 @@
+<?php
+class ReflectionExceptionEx extends ReflectionException {
+ function MyException($_errno, $_errmsg) {
+ $this->errno = $_errno;
+ $this->errmsg = $_errmsg;
+ }
+
+ function getErrno() {
+ return $this->errno;
+ }
+
+ function getErrmsg() {
+ return $this->errmsg;
+ }
+}
+?>
diff --git a/ext/reflection/tests/included4.inc b/ext/reflection/tests/included4.inc
new file mode 100644
index 0000000..8894725
--- /dev/null
+++ b/ext/reflection/tests/included4.inc
@@ -0,0 +1,9 @@
+<?php
+echo __FILE__ . "\n";
+echo __LINE__ . "\n";
+
+function g() {
+ echo __FILE__ . "\n";
+ echo __LINE__ . "\n";
+}
+?> \ No newline at end of file
diff --git a/ext/reflection/tests/parameters_001.phpt b/ext/reflection/tests/parameters_001.phpt
new file mode 100644
index 0000000..972b97c
--- /dev/null
+++ b/ext/reflection/tests/parameters_001.phpt
@@ -0,0 +1,38 @@
+--TEST--
+ReflectionParameter Check for parameter being optional
+--FILE--
+<?php
+
+class Test {
+ function func($x, $y = NULL){
+ }
+}
+
+
+$f = new ReflectionMethod('Test', 'func');
+var_dump($f->getNumberOfParameters());
+var_dump($f->getNumberOfRequiredParameters());
+
+$p = new ReflectionParameter(array('Test', 'func'), 'x');
+var_dump($p->isOptional());
+
+$p = new ReflectionParameter(array('Test', 'func'), 'y');
+var_dump($p->isOptional());
+
+try {
+ $p = new ReflectionParameter(array('Test', 'func'), 'z');
+ var_dump($p->isOptional());
+}
+catch (Exception $e) {
+ var_dump($e->getMessage());
+}
+
+?>
+===DONE===
+--EXPECT--
+int(2)
+int(1)
+bool(false)
+bool(true)
+string(54) "The parameter specified by its name could not be found"
+===DONE===
diff --git a/ext/reflection/tests/parameters_002.phpt b/ext/reflection/tests/parameters_002.phpt
new file mode 100644
index 0000000..a861910
--- /dev/null
+++ b/ext/reflection/tests/parameters_002.phpt
@@ -0,0 +1,207 @@
+--TEST--
+ReflectionParameter::getClass(), getDeclaringClass(), getDeclaringFunction()
+--FILE--
+<?php
+
+function test($nix, Array $ar, &$ref, stdClass $std, NonExistingClass $na, stdClass &$opt = NULL, $def = "FooBar")
+{
+}
+
+class test
+{
+ function test($nix, Array $ar, &$ref, stdClass $std, NonExistingClass $na, stdClass $opt = NULL, $def = "FooBar")
+ {
+ }
+}
+
+function check_params_decl_func($r, $f)
+{
+ $c = $r->$f();
+ echo $f . ': ' . ($c ? ($c instanceof ReflectionMethod ? $c->class . '::' : '') . $c->name : 'NULL') . "()\n";
+}
+
+function check_params_decl_class($r, $f)
+{
+ $c = $r->$f();
+ echo $f . ': ' . ($c ? $c->name : 'NULL') . "\n";
+}
+
+function check_params_func($r, $f)
+{
+ echo $f . ': ';
+ $v = $r->$f();
+ var_dump($v);
+}
+
+function check_params($r)
+{
+ echo "#####" . ($r instanceof ReflectionMethod ? $r->class . '::' : '') . $r->name . "()#####\n";
+ $i = 0;
+ foreach($r->getParameters() as $p)
+ {
+ echo "===" . $i . "===\n";
+ $i++;
+ check_params_func($p, 'getName');
+ check_params_func($p, 'isPassedByReference');
+ try
+ {
+ check_params_decl_class($p, 'getClass');
+ }
+ catch(ReflectionException $e)
+ {
+ echo $e->getMessage() . "\n";
+ }
+ check_params_decl_class($p, 'getDeclaringClass');
+// check_params_decl_func($p, 'getDeclaringFunction');
+ check_params_func($p, 'isArray');
+ check_params_func($p, 'allowsNull');
+ check_params_func($p, 'isOptional');
+ check_params_func($p, 'isDefaultValueAvailable');
+ if ($p->isOptional())
+ {
+ check_params_func($p, 'getDefaultValue');
+ }
+ }
+}
+
+check_params(new ReflectionFunction('test'));
+
+check_params(new ReflectionMethod('test::test'));
+
+?>
+===DONE===
+<?php exit(0); ?>
+--EXPECT--
+#####test()#####
+===0===
+getName: string(3) "nix"
+isPassedByReference: bool(false)
+getClass: NULL
+getDeclaringClass: NULL
+isArray: bool(false)
+allowsNull: bool(true)
+isOptional: bool(false)
+isDefaultValueAvailable: bool(false)
+===1===
+getName: string(2) "ar"
+isPassedByReference: bool(false)
+getClass: NULL
+getDeclaringClass: NULL
+isArray: bool(true)
+allowsNull: bool(false)
+isOptional: bool(false)
+isDefaultValueAvailable: bool(false)
+===2===
+getName: string(3) "ref"
+isPassedByReference: bool(true)
+getClass: NULL
+getDeclaringClass: NULL
+isArray: bool(false)
+allowsNull: bool(true)
+isOptional: bool(false)
+isDefaultValueAvailable: bool(false)
+===3===
+getName: string(3) "std"
+isPassedByReference: bool(false)
+getClass: stdClass
+getDeclaringClass: NULL
+isArray: bool(false)
+allowsNull: bool(false)
+isOptional: bool(false)
+isDefaultValueAvailable: bool(false)
+===4===
+getName: string(2) "na"
+isPassedByReference: bool(false)
+Class NonExistingClass does not exist
+getDeclaringClass: NULL
+isArray: bool(false)
+allowsNull: bool(false)
+isOptional: bool(false)
+isDefaultValueAvailable: bool(false)
+===5===
+getName: string(3) "opt"
+isPassedByReference: bool(true)
+getClass: stdClass
+getDeclaringClass: NULL
+isArray: bool(false)
+allowsNull: bool(true)
+isOptional: bool(true)
+isDefaultValueAvailable: bool(true)
+getDefaultValue: NULL
+===6===
+getName: string(3) "def"
+isPassedByReference: bool(false)
+getClass: NULL
+getDeclaringClass: NULL
+isArray: bool(false)
+allowsNull: bool(true)
+isOptional: bool(true)
+isDefaultValueAvailable: bool(true)
+getDefaultValue: string(6) "FooBar"
+#####test::test()#####
+===0===
+getName: string(3) "nix"
+isPassedByReference: bool(false)
+getClass: NULL
+getDeclaringClass: test
+isArray: bool(false)
+allowsNull: bool(true)
+isOptional: bool(false)
+isDefaultValueAvailable: bool(false)
+===1===
+getName: string(2) "ar"
+isPassedByReference: bool(false)
+getClass: NULL
+getDeclaringClass: test
+isArray: bool(true)
+allowsNull: bool(false)
+isOptional: bool(false)
+isDefaultValueAvailable: bool(false)
+===2===
+getName: string(3) "ref"
+isPassedByReference: bool(true)
+getClass: NULL
+getDeclaringClass: test
+isArray: bool(false)
+allowsNull: bool(true)
+isOptional: bool(false)
+isDefaultValueAvailable: bool(false)
+===3===
+getName: string(3) "std"
+isPassedByReference: bool(false)
+getClass: stdClass
+getDeclaringClass: test
+isArray: bool(false)
+allowsNull: bool(false)
+isOptional: bool(false)
+isDefaultValueAvailable: bool(false)
+===4===
+getName: string(2) "na"
+isPassedByReference: bool(false)
+Class NonExistingClass does not exist
+getDeclaringClass: test
+isArray: bool(false)
+allowsNull: bool(false)
+isOptional: bool(false)
+isDefaultValueAvailable: bool(false)
+===5===
+getName: string(3) "opt"
+isPassedByReference: bool(false)
+getClass: stdClass
+getDeclaringClass: test
+isArray: bool(false)
+allowsNull: bool(true)
+isOptional: bool(true)
+isDefaultValueAvailable: bool(true)
+getDefaultValue: NULL
+===6===
+getName: string(3) "def"
+isPassedByReference: bool(false)
+getClass: NULL
+getDeclaringClass: test
+isArray: bool(false)
+allowsNull: bool(true)
+isOptional: bool(true)
+isDefaultValueAvailable: bool(true)
+getDefaultValue: string(6) "FooBar"
+===DONE===
diff --git a/ext/reflection/tests/property_exists.phpt b/ext/reflection/tests/property_exists.phpt
new file mode 100644
index 0000000..c74b775
--- /dev/null
+++ b/ext/reflection/tests/property_exists.phpt
@@ -0,0 +1,222 @@
+--TEST--
+Reflection and property_exists()
+--FILE--
+<?php
+
+class A
+{
+ public $a = 1;
+ protected $b = 2;
+ private $c = 3;
+
+ public $empty;
+ public $init = 1;
+
+ function __toString()
+ {
+ return 'obj(' . get_class($this) . ')';
+ }
+
+ static function test($oc, $props)
+ {
+ echo '===' . __CLASS__ . "===\n";
+ foreach($props as $p2) {
+ echo $oc, '::$' , $p2, "\n";
+ var_dump(property_exists($oc, $p2));
+ }
+ }
+}
+
+class B extends A
+{
+ private $c = 4;
+
+ static function test($oc, $props)
+ {
+ echo '===' . __CLASS__ . "===\n";
+ foreach($props as $p2) {
+ echo $oc, '::$' , $p2, "\n";
+ var_dump(property_exists($oc, $p2));
+ }
+ }
+}
+
+class C extends B
+{
+ private $d = 5;
+
+ static function test($oc, $props)
+ {
+ echo '===' . __CLASS__ . "===\n";
+ foreach($props as $p2) {
+ echo $oc, '::$' , $p2, "\n";
+ var_dump(property_exists($oc, $p2));
+ }
+ }
+}
+
+$oA = new A;
+$oA->e = 6;
+
+$oC = new C;
+
+$pc = array($oA, 'A', 'B', 'C', $oC);
+$pr = array('a', 'b', 'c', 'd', 'e');
+
+foreach($pc as $p1) {
+ if (is_object($p1)) {
+ $p1->test($p1, $pr);
+ } else {
+ $r = new ReflectionMethod($p1, 'test');
+ $r->invoke(NULL, $p1, $pr);
+ }
+ echo "===GLOBAL===\n";
+ foreach($pr as $p2) {
+ echo $p1, '::$' , $p2, "\n";
+ var_dump(property_exists($p1, $p2));
+ }
+}
+
+echo "===PROBLEMS===\n";
+var_dump(property_exists(NULL, 'empty'));
+var_dump(property_exists(25,'empty'));
+var_dump(property_exists('',''));
+var_dump(property_exists('A',''));
+var_dump(property_exists('A','123'));
+var_dump(property_exists('A','init'));
+var_dump(property_exists('A','empty'));
+var_dump(property_exists(new A, ''));
+var_dump(property_exists(new A, '123'));
+var_dump(property_exists(new A, 'init'));
+var_dump(property_exists(new A, 'empty'));
+?>
+===DONE===
+<?php exit(0); ?>
+--EXPECTF--
+===A===
+obj(A)::$a
+bool(true)
+obj(A)::$b
+bool(true)
+obj(A)::$c
+bool(true)
+obj(A)::$d
+bool(false)
+obj(A)::$e
+bool(true)
+===GLOBAL===
+obj(A)::$a
+bool(true)
+obj(A)::$b
+bool(true)
+obj(A)::$c
+bool(true)
+obj(A)::$d
+bool(false)
+obj(A)::$e
+bool(true)
+===A===
+A::$a
+bool(true)
+A::$b
+bool(true)
+A::$c
+bool(true)
+A::$d
+bool(false)
+A::$e
+bool(false)
+===GLOBAL===
+A::$a
+bool(true)
+A::$b
+bool(true)
+A::$c
+bool(true)
+A::$d
+bool(false)
+A::$e
+bool(false)
+===B===
+B::$a
+bool(true)
+B::$b
+bool(true)
+B::$c
+bool(true)
+B::$d
+bool(false)
+B::$e
+bool(false)
+===GLOBAL===
+B::$a
+bool(true)
+B::$b
+bool(true)
+B::$c
+bool(true)
+B::$d
+bool(false)
+B::$e
+bool(false)
+===C===
+C::$a
+bool(true)
+C::$b
+bool(true)
+C::$c
+bool(false)
+C::$d
+bool(true)
+C::$e
+bool(false)
+===GLOBAL===
+C::$a
+bool(true)
+C::$b
+bool(true)
+C::$c
+bool(false)
+C::$d
+bool(true)
+C::$e
+bool(false)
+===C===
+obj(C)::$a
+bool(true)
+obj(C)::$b
+bool(true)
+obj(C)::$c
+bool(false)
+obj(C)::$d
+bool(true)
+obj(C)::$e
+bool(false)
+===GLOBAL===
+obj(C)::$a
+bool(true)
+obj(C)::$b
+bool(true)
+obj(C)::$c
+bool(false)
+obj(C)::$d
+bool(true)
+obj(C)::$e
+bool(false)
+===PROBLEMS===
+
+Warning: First parameter must either be an object or the name of an existing class in %sproperty_exists.php on line %d
+NULL
+
+Warning: First parameter must either be an object or the name of an existing class in %sproperty_exists.php on line %d
+NULL
+bool(false)
+bool(false)
+bool(false)
+bool(true)
+bool(true)
+bool(false)
+bool(false)
+bool(true)
+bool(true)
+===DONE===
diff --git a/ext/reflection/tests/static_properties_002.phpt b/ext/reflection/tests/static_properties_002.phpt
new file mode 100644
index 0000000..218c629
--- /dev/null
+++ b/ext/reflection/tests/static_properties_002.phpt
@@ -0,0 +1,60 @@
+--TEST--
+Reflection and inheriting static properties
+--FILE--
+<?php
+
+class base {
+ static protected $prop = 2;
+
+ static function show() {
+ echo __METHOD__ . '(' . self::$prop . ")\n";
+ }
+
+ static function inc() {
+ base::$prop++;
+ echo __METHOD__ . "()\n";
+ }
+}
+
+class derived extends base {
+ static public $prop = 2;
+
+ static function show() {
+ echo __METHOD__ . '(' . self::$prop . ")\n";
+ }
+
+ static function inc() {
+ derived::$prop++;
+ echo __METHOD__ . "()\n";
+ }
+}
+
+base::show();
+derived::show();
+
+base::inc();
+
+base::show();
+derived::show();
+
+derived::inc();
+
+base::show();
+derived::show();
+
+$r = new ReflectionClass('derived');
+echo 'Number of properties: '. count($r->getStaticProperties()) . "\n";
+
+echo "Done\n";
+?>
+--EXPECTF--
+base::show(2)
+derived::show(2)
+base::inc()
+base::show(3)
+derived::show(2)
+derived::inc()
+base::show(3)
+derived::show(3)
+Number of properties: 1
+Done
diff --git a/ext/reflection/tests/traits001.phpt b/ext/reflection/tests/traits001.phpt
new file mode 100644
index 0000000..4e36cee
--- /dev/null
+++ b/ext/reflection/tests/traits001.phpt
@@ -0,0 +1,70 @@
+--TEST--
+ReflectionClass and Traits
+--FILE--
+<?php
+trait Foo {
+ public function someMethod() { }
+}
+
+class Bar {
+ use Foo;
+
+ public function someOtherMethod() { }
+}
+
+$rFoo = new ReflectionClass('Foo');
+$rBar = new ReflectionClass('Bar');
+
+var_dump($rFoo->isTrait());
+var_dump($rBar->isTrait());
+echo $rFoo;
+echo $rBar;
+--EXPECTF--
+bool(true)
+bool(false)
+Trait [ <user> trait Foo ] {
+ @@ %straits001.php 2-4
+
+ - Constants [0] {
+ }
+
+ - Static properties [0] {
+ }
+
+ - Static methods [0] {
+ }
+
+ - Properties [0] {
+ }
+
+ - Methods [1] {
+ Method [ <user> public method someMethod ] {
+ @@ %straits001.php 3 - 3
+ }
+ }
+}
+Class [ <user> class Bar ] {
+ @@ %straits001.php 6-10
+
+ - Constants [0] {
+ }
+
+ - Static properties [0] {
+ }
+
+ - Static methods [0] {
+ }
+
+ - Properties [0] {
+ }
+
+ - Methods [2] {
+ Method [ <user> public method someOtherMethod ] {
+ @@ %straits001.php 9 - 9
+ }
+
+ Method [ <user> public method someMethod ] {
+ @@ %straits001.php 3 - 3
+ }
+ }
+}
diff --git a/ext/reflection/tests/traits002.phpt b/ext/reflection/tests/traits002.phpt
new file mode 100644
index 0000000..b55b288
--- /dev/null
+++ b/ext/reflection/tests/traits002.phpt
@@ -0,0 +1,54 @@
+--TEST--
+ReflectionClass and Traits
+--FILE--
+<?php
+
+abstract class foo {
+}
+
+trait bar {
+
+}
+
+reflectionclass::export('foo');
+reflectionclass::export('bar');
+
+?>
+--EXPECTF--
+Class [ <user> abstract class foo ] {
+ @@ %s 3-4
+
+ - Constants [0] {
+ }
+
+ - Static properties [0] {
+ }
+
+ - Static methods [0] {
+ }
+
+ - Properties [0] {
+ }
+
+ - Methods [0] {
+ }
+}
+
+Trait [ <user> trait bar ] {
+ @@ %s 6-8
+
+ - Constants [0] {
+ }
+
+ - Static properties [0] {
+ }
+
+ - Static methods [0] {
+ }
+
+ - Properties [0] {
+ }
+
+ - Methods [0] {
+ }
+}
diff --git a/ext/reflection/tests/traits003.phpt b/ext/reflection/tests/traits003.phpt
new file mode 100644
index 0000000..c569a8e
--- /dev/null
+++ b/ext/reflection/tests/traits003.phpt
@@ -0,0 +1,30 @@
+--TEST--
+Reflection and Traits
+--FILE--
+<?php
+
+abstract class foo {
+}
+
+trait bar {
+
+}
+
+final class baz {
+
+}
+
+$x = new ReflectionClass('foo');
+var_dump($x->isTrait());
+
+$x = new ReflectionClass('bar');
+var_dump($x->isTrait());
+
+$x = new ReflectionClass('baz');
+var_dump($x->isTrait());
+
+?>
+--EXPECT--
+bool(false)
+bool(true)
+bool(false)
diff --git a/ext/reflection/tests/traits004.phpt b/ext/reflection/tests/traits004.phpt
new file mode 100644
index 0000000..c9367c1
--- /dev/null
+++ b/ext/reflection/tests/traits004.phpt
@@ -0,0 +1,58 @@
+--TEST--
+ReflectionClass::getTraits() and ReflectionClass::getTraitNames
+--FILE--
+<?php
+trait T1 { }
+trait T2 { }
+
+class C1 { }
+class C2 { use T1; }
+class C3 { use T1; use T2; }
+
+for ($c = "C1"; $c <= "C3"; $c++) {
+ echo "class $c:\n";
+ $r = new ReflectionClass($c);
+ var_dump($r->getTraitNames());
+ var_dump($r->getTraits());
+ echo "\n";
+}
+--EXPECT--
+class C1:
+array(0) {
+}
+array(0) {
+}
+
+class C2:
+array(1) {
+ [0]=>
+ string(2) "T1"
+}
+array(1) {
+ ["T1"]=>
+ &object(ReflectionClass)#1 (1) {
+ ["name"]=>
+ string(2) "T1"
+ }
+}
+
+class C3:
+array(2) {
+ [0]=>
+ string(2) "T1"
+ [1]=>
+ string(2) "T2"
+}
+array(2) {
+ ["T1"]=>
+ &object(ReflectionClass)#2 (1) {
+ ["name"]=>
+ string(2) "T1"
+ }
+ ["T2"]=>
+ &object(ReflectionClass)#3 (1) {
+ ["name"]=>
+ string(2) "T2"
+ }
+}
+
diff --git a/ext/reflection/tests/traits005.phpt b/ext/reflection/tests/traits005.phpt
new file mode 100644
index 0000000..4cfa6c0
--- /dev/null
+++ b/ext/reflection/tests/traits005.phpt
@@ -0,0 +1,41 @@
+--TEST--
+ReflectionClass::getTraitAlias
+--FILE--
+<?php
+trait T1 { function m1() { } function m2() { } }
+
+class C1 { }
+class C2 { use T1; }
+class C3 { use T1 { m1 as a1; } }
+class C4 { use T1 { m1 as a1; m2 as a2; } }
+
+for ($c = "C1"; $c <= "C4"; $c++) {
+ echo "class $c:\n";
+ $r = new ReflectionClass($c);
+ var_dump($r->getTraitAliases());
+ echo "\n";
+}
+?>
+--EXPECT--
+class C1:
+array(0) {
+}
+
+class C2:
+array(0) {
+}
+
+class C3:
+array(1) {
+ ["a1"]=>
+ string(6) "T1::m1"
+}
+
+class C4:
+array(2) {
+ ["a1"]=>
+ string(6) "T1::m1"
+ ["a2"]=>
+ string(6) "T1::m2"
+}
+